Update SPECIFICATION.MD

some more ideas, rename the language again lol
This commit is contained in:
zongor 2024-07-20 12:38:03 -04:00
parent 5f0c66fa93
commit 518070d2bd
1 changed files with 76 additions and 120 deletions

View File

@ -1,4 +1,4 @@
# *ghun* Design parameters
# *zwl* (zongors world language) Design parameters, for *zwm* (zongors world machine)
## Modern programming languages in the 21st century usually have need for the following requirements
@ -132,21 +132,46 @@
- delete
# *ghun* at a high level.
# *zwl* at a high level.
ghun should be thought of as more of a virtual machine more than a programming language.
zwl should be thought of as more of a scripting language for virtual machine more than a programming language that is compiled.
# *ghun* Grammar and Specification
# *zwl* Grammar and Specification
## Form
- describe storage objects "the ideal state of the object"
- atoms (invoked forms) are stored in the internal database which is why they need version numbers
- Forms can be inherited, multiple inheritance is taken from left to right overriding collisions.
- Forms can be implementations of interfaces, collsions are not important as the names of interfaces only carry what needs to be implemented a not any implemtntation itself. for people coming from OOP you can think of this similar to an abstract class.
- there are also a list of "substantial forms" which come with the language which are the building blocks for more complex forms. If you are coming from object oriented languages you can think of this as "primitive types"
- all forms derive from the root form or the "parent of all forms"
All substantial forms are "fat pointers" like in [Cello](https://www.libcello.org/). and have the following structure (here I will use a psudo C as an example):
```c
typedef enum error_e {
none, // no error
bound, // array out of bounds error
} error;
typedef enum type_e {
u8,
u16,
} type;
typedef struct type_s {
size_t sz; // size/length of the pointer
error err; // the error on the form (default is none)
void *ptr;
} frm;
```
So as you can see each type includes some extra information, its type, if it has an error, the length, and the 'real' pointer to the value.
```
frm «form_token» impls «this_form», «that_form» {
version : [0, 0, 1] ! version number for auto saving to a database or whatnot
@ -155,7 +180,6 @@ frm «form_token» impls «this_form», «that_form» {
unit : <> ! this is for the unit/measures system
display : <> ! some kind of UI form or None
position : <> ! a position in space or None
! form definitions here
}
```
@ -226,34 +250,25 @@ Also follows the style boolean 'c' rules of nonzero / zero, but the interpreter
## null values
### *ghun* does not have null, it stole some monads from Rust and Haskell, they never saw it coming
### *zwl* does not have null, it stole some monads from Rust, Haskell, and the like
If you are coming from haskell, a 'Just' is `< some value >` and a 'None' is `<>`, note 'None' is also an error
Like in Rust you have `unwrap` and `unwrap_or` and the like, you use `?` and `??`
```
<3> ~ a set
<> ~ b set
~ x a ? set
~ y b 1 ?? set
"%d%d\n" (x y) fmt print ! outputs 3, 1
1| i32 a = <3>; ! this can also be writen `i32 a = just(3);`
2| i32 b = <>; ! this can also be written `i32 b = none;`
3|
4| i32 x ?= a; ! this will set x to 3
5| i32 y ?= b; ! this will set y to an error
6| i32 z ?= b ?= 1; ! this will return an error from b, then unwrap the error and set y = 1;
7|
8| print("$x $y $z\n") ! prints 3, "error: failed to unwrap a 'none' on line 5", 1
```
additionally, a None will be evaluated as "false" and Just as "true" in a boolean check
as you can see the `?` after the form notes that it is wrapped in a maybe
## any
any is the same as an Object in OOP languages, but is used slightly differently, it is mostly used for data structures like
```
let test any[] ! this is a list of form abstract
```
## error
error is a form which describes an error that occurred, it is similar to the Go programming language and is returned as a monad like the maybe monad above and is unwrapped in a similar way, take a look at the tunnel section for an example
@ -265,7 +280,7 @@ error is a form which describes an error that occurred, it is similar to the Go
syntax
```
(item1 item2 ...)
(item1 item2 )
```
### set
@ -275,7 +290,7 @@ same as list except does not allow duplicates, allows set operations
n is the starting size of the set
```
let «atom_token» as «form»{}
«form»{} «atom_token»;
```
sets also have the following transforms associated with them
@ -285,7 +300,7 @@ sets also have the following transforms associated with them
a simple form to form storage
```
«form» «form» map «atom_token» set
«form» ~> «form» «atom_token»;
```
### tunnel
@ -305,12 +320,12 @@ The following is a list of global operators and their effect:
comment
!!
block comment (looks for another !! to close)
:
=
set operator
?
unwrap or none
??
unwrap or
unwrap
?=
unwrap and set
\
lambda function
+
@ -324,18 +339,6 @@ The following is a list of global operators and their effect:
divisor
**
power
=
equals
<
less than
>
greater than
>=
greater than or equals
<=
less than or equals
~=
approximately equal to (to be used with floating point evaluation)
.
accessor
..
@ -387,30 +390,6 @@ expander
bitwise xor
```
### keywords
`is?`
checks if a atom is of that form, replacement for number? / null? and makes it more flexable
```
i32 «token» is?
```
`threaten (buQ)`
coerces a form as another form if possible
```
~ «token» i32 threaten set
```
`impls`
checks if a atom's form, or a form impls another form
```
«token» Tunnel implements
```
## Atom
An atom is an invoked form.
@ -423,7 +402,7 @@ Each atom has its own "process" with "socket like" i/o.
an atom can be created (in the universe) using the following syntax:
```
«atom_token» : «form»(«fields», …)
«form» «atom_token»(«fields», …);
```
note: if the atom name is omitted, it will make the atom unaccessible! but it is allowed, this is usually useful in the "universe" namespace
@ -440,35 +419,35 @@ note the form must always be of a form which is "tunnel-able" i.e. Files, socket
### transforms for tunnels
`tunnel? : attach(tunnel_atom)` -> open communication
`tunnel attach(tunnel_atom)` -> open communication
`success? : tunnel_atom.clunk()` -> close communication
`bool success = tunnel_atom.clunk()` -> close communication
`success? : tunnel_atom.flush()` -> cancels long operation and dumps whatever is in buffer
`bool success = tunnel_atom.flush()` -> cancels long operation and dumps whatever is in buffer
`success? : tunnel_atom.open(resource, mode)` -> opens a tunnel for doing operations on
`bool success = tunnel_atom.open(resource, mode)` -> opens a tunnel for doing operations on
`success? : tunnel_atom.create(resource)` -> creates the object from the database graph/file from file structure
`bool success = tunnel_atom.create(resource)` -> creates the object from the database graph/file from file structure
`data? : tunnel_atom.read(resource)` -> reads from a tunnel
`«form» data = tunnel_atom.read(resource)` -> reads from a tunnel
`success? : tunnel_atom.write(resource, data)` -> writes to a tunnel
`bool success = tunnel_atom.write(resource, data)` -> writes to a tunnel
`success? : tunnel_atom.remove(resource)` -> removes the object from the database graph/file from file structure
`bool success = tunnel_atom.remove(resource)` -> removes the object from the database graph/file from file structure
`stat_data? : tunnel_atom.stat(resource)` -> returns the status of the file/resource
`«form» stat_data = tunnel_atom.stat(resource)` -> returns the status of the file/resource
`version? : tunnel_atom.version()` -> returns the version code for the connected tunnel
`«form» version = tunnel_atom.version()` -> returns the version code for the connected tunnel
`success? : tunnel_atom.walk(path_or_endpoint)` -> moves around the filesystem or through the graph
`bool success = tunnel_atom.walk(path_or_endpoint)` -> moves around the filesystem or through the graph
```
let data as «some form»
endpoint : «tunnel-able form»(endpoint_str)
tunnel : endpoint.attach(user, auth)
tunnel.?open("\some\resource").?read(data)
std.write(data)
data.flush()
«some form» data();
«tunnel-able form» endpoint(endpoint_str);
«tunnel» tunnel = endpoint.attach(user, auth);
data = tunnel.open(`\some\resource`).read()
std.write(data) ! will either write the data or if the data has an error will write the error message instead
tunnel.flush()
endpoint.clunk()
```
@ -501,22 +480,22 @@ You can also create a lambda/closure form by using the syntax
## Control flow
### do
### loops
```
do «token» in «collection», +/-/iter { «body» }
for «token» in «collection», +/-/iter { «body» }
```
iterates through each object in the collection setting it to token
```
do «boolean expression» { «body» }
while «boolean expression» { «body» }
```
loops until the expression is false
```
do { «body» }
loop { «body» }
```
loops infinitely until break or return
@ -542,9 +521,9 @@ match «token» {
take a look at error's, but you can panic on an error like this:
```
panic("error message" as err)
panic(-3 as err)
panic(«some_error_token»)
panic(error("error message"));
panic(error(-3));
panic(«some_error_token»);
```
## Libraries and “includes”
@ -554,11 +533,11 @@ The other way to do this would be to just specifically “name” the paths usin
Since everything is lazily compiled jit anyways it (in theory) doesn't hurt performance much
```
import `https://raw.githubusercontent.com/some_user/some_library/some_file.igk`
import `https://raw.githubusercontent.com/some_user/some_library/some_file.zwl`;
```
```
import `./some_local_file.igk`
import `./some_local_file.zwl`;
```
## Universe
@ -571,33 +550,16 @@ in kOS this actually *is* the kernel layer
## GUI
The GUI is inspired by PicoLisp and Electron, using a web browser engine to render the GUI including 3D stuff like webgl.
Most html elements have an analogous form in *ghun*: Tables, lists, links, buttons, input boxes, etc.
Most html elements have an analogous form in *zwl*: Tables, lists, links, buttons, input boxes, etc.
In kOS these are replaces by its own version of these forms.
These of course can be wrapped in your own implementations. The idea is that on *ghuns* side all UI is unified by forms but also is interoperable with HTML, templating engines, or gui libraries
```
ui Table impl HTML {
start = "<table>"
end = "</table>"
}
ui TableRow impl HTML {
start = "<th>"
end = "</th>"
}
ui TableColumn impl HTML {
start = "<td>"
end = "</td>"
}
```
These of course can be wrapped in your own implementations. The idea is that on *zwls* side all UI is unified by forms but also is interoperable with HTML, templating engines, or gui libraries
## Concurrency
As in elixir there are as many schedulers as there are cores for your cpu
Like in CM and real time micro architecture systems like QNX tasks are scheduled based on priority and must stay within a time limit or it will be “punished” into a lower priority
Threading in *ghun* are split up into tasks (which take input) and daemons (which take no input)
Threading in *zwl* are split up into tasks (which take input) and daemons (which take no input)
Tasks are spawned whereas daemons are summoned
Message passing can be achieved by using tunnels.
@ -617,9 +579,3 @@ test some_test {
```
### assertion
```
«error or none» : assert(«expression», «expected output»)
```