12 KiB
ghun Design parameters
Modern programming languages in the 21st century usually have need for the following requirements
Data
- describing data
- numeric
- string
- logical
- complex
- point
- edge
- color
- many more
- qualitative
- sentiment analysis
- more...
- measurements
- tons of these...
Inputing data
- stdio
- program args
- command line
- reading from other source
- gui
- input boxes
- forms
- many others
Storing descriptions of data
- internal
- graph
- array
- list
- set
- map
- graph
- external
- database
- local
- cloud
- database
- writing data
- stdout
- stderr
- writing to other source
- file
- tape
- socket
Manipulating data
- algorithms
- sort
- filter
- math functions
- trigonometric
- statistics
- calculus
- many more
- Validating data
- business rules
- constraints
- formulas
Displaying data
- objects
- 3d models
- 2d models
- graphs
- tables
- infographics
- written output
- ai generated text
System/World Objects
- Viewing objects in nth dimensional space
- Animations
- moving the objects in space
- manipulating objects
- Interaction from user input on objects in space
- Creating
Communication
- Sending and receiving data
- protocols
- Controlling real world objects
- embedded programs
- web programs
- mobile
- desktop
- smart devices (IOT)
- Encryption
- hashing
- keys
- more ...
Meta
- documentation
- tutorials
- generating objects automatically like
Data Description
- windowing system
- window
- terminal
- web browser
- form of the object (description)
- version number
- fields
- forms
- what dimensional object
- unit form / measurements
- display
- What the UI default should be
- type of display
- position in space
- user controls
- validations
- communications
- CRUD
- create
- read
- update
- delete
ghun at a high level.
ghun should be thought of as more of a virtual machine more than a programming language.
ghun 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.
- 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"
frm «form_token» impls «this_form», «that_form» {
version : [0, 0, 1] ! version number for auto saving to a database or whatnot
migrate : <> ! this is to migrate from the previous version to new, in case of interface changes, or None
dimensions : 0 ! this returns how many dimensions it can exist in, 0th means non drawable, 2 means 2D GUI usually, 3 means 3D object, and >3 is somthing you will have to implement yourself, e.g. miegakure
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
}
Substantial Forms
numeric
bit (or unsigned units)
u8, u16, u32, u64
integer (signed)
i8, i16, i32, i64
real
f32, f64
string
str
matching ''
for char
matching ""
for string
strings are always utf8, other formats will need to be done manually
measurement
- forms
- time
- unit
- seconds (s)
- subforms
- date
- Default is ISO 8601
- date
- unit
- length
- unit
- metre (m)
- subforms
- angle
- radian (rad)
- angle
- unit
- mass
- unit
- kilogram (kg)
- unit
- electric current
- unit
- ampere (a)
- unit
- temperature
- unit
- kelvin (K)
- unit
- amount of substance
- unit
- mol (mol)
- unit
- luminous intensity
- unit
- candela (candela)
- unit
- time
logical
bool
true
/ false
Also follows the style boolean 'c' rules of nonzero / zero, but the interpreter will make fun of you
null values
ghun does not have null, it stole some monads from Rust and Haskell, they never saw it coming
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
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
datastructures
list
syntax
(item1 item2 ...)
set
same as list except does not allow duplicates, allows set operations
n is the starting size of the set
let «atom_token» as «form»{}
sets also have the following transforms associated with them
map
a simple form to form storage
«form» «form» map «atom_token» set
tunnel
described in "tunnel" section
uri
matching `` (backtics)
Basic operators
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
\
lambda function
+
addition
-
subtraction
negation
*
multiplication
/
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
..
expander
(1..10) is the same as writing (1,2,3,4,5,6,7,8,9,10)
++
inline add 1
--
inline subtract 1
+=
inline add n
-=
inline subtract n
*=
inline multiply n
\=
inline divide n
**=
inline power n
basic transforms
eq
equal to
ne
not equals to
mod
modulo
not
logical not
and
logical and
or
logical or
nor
logical nor
nand
logical nand
xor
logical xor
band
bitwise and
bor
bitwise or
bnor
bitwise nor
bxor
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. For those of you coming from an object oriented language this is similar to creating an object on the heap using "new" keyword or the like
Atoms persist in the universe until they are not needed. 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», …)
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
Tunnel
Represents a path to a file, url endpoint, other process endpoint (like a socket, etc.)
Tunnels are inspired by translators in gnu/hurd, plan9 9p protocol, and unix sockets
tunnels are invoked like atoms, but have scope like control flow end scope closes the tunnel
note the form must always be of a form which is "tunnel-able" i.e. Files, sockets, etc
transforms for tunnels
tunnel? : attach(tunnel_atom)
-> open communication
success? : tunnel_atom.clunk()
-> close communication
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
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
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
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
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()
endpoint.clunk()
in "terminal mode" the default tunnel is std
in "web mode" the default tunnels are log, info, trace, warn, error, but note these are all special tunnels which only accept write commands
Transforms
tf «transform_token» («form» «parameter», ...) «return_form», ... {
«instructions»
}
You can also create a lambda/closure form by using the syntax
\«form» «parameter», ... {
«instructions»
}
- Built in transforms
- sort
- filter
- trig functions
- calc functions
- statistical functions
Control flow
do
do «token» in «collection», +/-/iter { «body» }
iterates through each object in the collection setting it to token
do «boolean expression» { «body» }
loops until the expression is false
do { «body» }
loops infinitely until break or return
match
match «token» {
'a' -> actionA
'x' -> actionX
'y'..'z' -> {
actionY
actionZ
}
someTransformOfTokensForm -> actionSomeTransform
\«token's form» t { t <= 5 and t > 0 } -> actionLambda
_ -> actionNoMatch
}
exceptions
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»)
Libraries and “includes”
In most languages the include or use statements get libraries which link to other files and so on. This quickly gets confusing and so requires package managers and installers, etc. The other way to do this would be to just specifically “name” the paths using a tunnel and import it. You can even use localization tokens to create config files. 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 `./some_local_file.igk`
Universe
All forms and complications exist within the universe. The universe can be thought of as the "global" namespace in an object oriented language or as the kernel for the "atom processes" to exist in. a "main" space should be created that invokes the required startup atoms of the syntax. 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. 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>"
}
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) Tasks are spawned whereas daemons are summoned Message passing can be achieved by using tunnels.
probably should take concurrency stuff from golang; its very nice
Testing
Tests are done inside of a test
block
test some_test {
someTransform() -> true
}
assertion
«error or none» : assert(«expression», «expected output»)