out
keyword when the program ends execution will be output by the program.
out
has a default value of {}
until reassigned.
Each complete EON program must be enclosed within eon{}
delimiters to indicate it's bounds.
eon{
out: "Hello World!"
// returns "Hello World!"
}
eon{
message: "Hello World!"
name: "Hello Bob!"
/(-
out: message
out:+ name)
/*
prints:
Hello World!Hello Bob! */ }
Except for the last line, commands in a command list must always terminated by a new line character.
Commands in a command list can be spread onto multiple lines by placing a //
before the next new line character.
fn
keyword converts the expression list on it's right into an executable process.
Processes are named expression lists that are executed when accessed.
eon{
printAll: fn {
my_var: "World"
/(-
out: "Hello"
out:+ my_var
out:+ "!" )}
(-out: printAll)
/* prints:
HelloWorld! */ }
cfn
keyword is a type of process like fn
, but after each execution the process's input and output
are cached so that future calls to the process can skip execution for duplicate inputs.
This increases program speed when a process is known to be deterministic like in mathematical functions.
eon{
add5: cfn (-
out: sum [in 5])
/(-out: add5 5)
/* prints:
10 */ }
pfn
keyword is a type of process like fn
,
but the function executes on each of its inputs concurrently and waits until all are done before progressing.
Consequently, the inputs to the function must be in a list []
otherwise void
will automatically be returned.
However the src
input may be singular to enable other passing in other parameters.
Outputs are returned in a list in the same order as the inputs.
This can reduce overall execution time compared to loops when hardware supports concurrency or parallelism.
eon{
add5: pfn (-
out: sum [in 5])
/(-out: add5 [5 6 7 8])
/* outputs:
10 11 12 13 */ >
It is idiomatic to use camelCase to name processes and snake_case to name cards.
Capitalized keys are Public and all other keys are private (similar to Golang)
:?
passes the input in to the process by a pointing reference instead of by copying it, which is the default behavior.
eon{
printHello:? fn(-
out: "Hello "
out:+ in )}
EON does not have null values in the way that most other programming languages do.
Instead other constructs are used depending on the particular context and type.
Empty, but initialized, values return {}
, []
, [:]
, ()
, ""
, or 0
.
Attempting to access an undefined value returns a void
card.
When the void
expression is typically executed it immediately exits the current expression list ()
.
The best way to understand how the void
keyword works is to think of it as a function whose output triggers a context dependent behavior.
It takes the card input into it, if any, and makes it the body of a returned void{}
card.
Within an executing expression list, any expression that evaluates to a card of type void
,
sets out
to the void card's body and ends execution of the expression list.
With no input it returns an empty but typed card void{}
.
This behavior enables void to fill the roles that break, null, throw, and false keywords in other languages serve,
as well as enabling custom error handling and treatment of errors as data.
{}
and removed by assigning them void
.
eon{
card: { tag1 }
/(-
card.tag2: {}
card.tag1: void)
// now the card is { tag2 }
}
void
card if it does not.
eon{
(-{tag1 tag2}.tag_3)
// if yes, then execution continues
// if no, then a void card results
}
eon{
(- "string"/[:])
// if yes, then execution continues
// if no, then a void card results
}
eon{
(-{tag1 tag2}/[])
// if yes, then execution continues
// if no, then a void card results
}
try
keyword executes the commands in the list to its right in order until the void
keyword is called or execution of the card finishes.
If the expression list is unordered (executed in parallel) then all expressions in the list are always executed.
eon{
try(-
printAll
out: "Success!")}
try
keyword can emulate the behavior of if-elseif-else patterns by instead passing a list of expression lists to attempt.
Each successive expression list is only executed if the prior's execution was interrupted by a void.
eon{
try[
(-
void
out: "Success!")
(-
out: "Error!")]}
esc
keyword immediately ends execution in the current loop
(similarly to 'break' in other languages).
eon{
try[
(-
loop(-
esc
out: "Fail!"))
(-out: "Loop Completed!")]}
loop
keyword repeatedly executes the commands in the list to its right until the esc
keyword is called or the next
keyword triggers another iteration.
eon{
loop(-
printAll
esc)}
next
keyword triggers another iteration of the loop without waiting until the current iteration of the loop has completed.
eon{
loop(-
out: "This is an infinite loop"
next
esc)}
void
and esc
keywords can be returned to be executed by the encapsulating command-list in order to conditionally exit a command-list (scope) or loop.
eon{
loop
try[
(-
forceExitLoop // outputs void to exit the if
out: "Fail!")
(-
out: fn (void)
out: "Success!" // this is still executed
// because the output is not retrieved until after
// the or finishes executing or a void/esc has been used
)]}
loop
interface.
In each iteration the current key and its value will be referenced by the reserved names key
and val
.
eon{
list: [ "hello" "world" ]
/(-list.loop(-
out:+ key
out:+ val))
// prints "1hello2world"
}
key
or val
is referencing.
eon{
list1: [ "A" "B" ]
list2: [ "I" "II"]
/(-
list1.loop(-
list2.loop(-
out:+ list1.key
out:+ list1.val
out:+ list2.val
out:+ " "))
// prints "1AI 1AII 2BI 2BII"
}
void
card.
eon{
try[
(-
undefined
out: "Success!")
(-
out: "Error!")]}
$
operator concatenates the bodies of a list of cards of the same type and merges their indexes.
The values of duplicate keys are combined into a list []
.
eon{
(-
$["Hello " "World"]
// combines into "Hello World"
$[
{ tag1 key1: "Hello"}
{ tag2 key1: "World"}]
// combines into:
// { tag1 tag2
// key1: ["Hello" "World"]
// }
)]
ini
keyword is a reserved index that is only executed after its parent card is initialized or when a copy of the parent is initialized.
Changing a card's type does not trigger ini
.
eon{
my_card: {
var: "Hello"
ini: fn(-
var: $[var "!"])
message: fn(-
out: var)}
out: my_card.message
// prints Hello!
}
del
keyword is a reserved index that is only executed immediately before its parent card is deleted or when a copy of the parent is deleted if defined in a type.
Changing a card's type does not trigger del
.
eon{
my_card: {
var: "Bye"
del: (-
var: $[var "!"])
message: fn(-
out: var)}
out: my_card.message
// prints Bye!
}
free
keyword is used to delete data and references subsequently freeing up a key or index for reuse.
Using this keyword triggers execution of any code defined in an card's del
index followed by recursively calling free on each internal key and index.
Finally the card's internal reference counter is checked and if 0 the memory containing the card is released, otherwise a void is returned.
eon{
my_card: {
var: "Bye"
del: (-
var: $[var "!"])
message: fn(-
out: var)}
out: free my_card
// prints Bye!
}
in
keyword is actually a reserved name to the card passed into a process.
eon{
printName: fn(-
out: $["Hi! My name is " in])
myName: "Jane"
out: printName myName
// prints Hi! My name is Jane
}
out
keyword is actually a reserved name to the card a process returns.
It can be used to not only set the process's output, but to reference it within the process, and modify it prior to the end of the process.
eon{
echo: fn(-
out: in
out: $[out "!"])
out: echo "Hello"
// returns "Hello!"
}
type
keyword creates a type interface (essentially a library of values and functions only accessible by the given type of card).
This enables defining and consolidating class-like behaviors and values for cards based on their type.
The src
keyword accesses the card to the left of the process being called.
eon{
(-
type str{
echo: fn(-out: src)
ping: fn(-out: $[src in])}
"Hello World".echo
"Hello World".ping "... and John.")}
has
keyword returns void
if the left card does not have all the same type, key-value pairs, and body that are in the right card.
eon{
bowl: [ "milk" "cereal" ]
cup: [ "cereal" "milk" ]
isBreakfast: fn(-
try[
(-
in.has [ "milk" "cereal" ]
out: "yes")
(-out: "no"))]
// prints yes
}
os
keyword provides an interface with the host operating system's API similar to a terminal or CLI.
The functions and interface options available depend on the operating system, but there will always be a version
function that returns the os name and version.
eon{
/(-
os.version // returns something like "BSD 13.0"
os.cd "../project/"
os.git.commit < a m /"commit message">)
// in Powershell this is equivalent to:
// cd ../project/
// git commit -am "commit message"
}
vol
keyword so that they are ignored by a compiler's optimizer.
eon{
key1: "data"
key2: "volatile data"
/(-vol key2)}
conc
keyword.
This executes its input concurrently to the main process.
Its returned output, if earmarked for a variable/list, becomes a promise that will await fulfillment the next time it is accessed (like async/await in other languages).
If not earmarked, it will be automatically terminated (if still running) when its calling scope is exited.
eon{
name: "placeholder"
start: "My name is "
sentence1: ""
sentance2: ""
/(-
name: conc getName // outputs "John"
sentence1: $[ start name "." ]
name: vol "placeholder"
sentence2: $[ start name "." ]
/*
if getName takes 1 sec to finish
then sentence1 becomes
"My name is John."
and sentence2 becomes
"My name is placeholder."
*/
)}
use
keyword is used to set the namespace that will be prepended to each subsequent identifier until changed again.
eon{
(-
use "os."
cd "../project/"
// prepends "os." to cd
use "" // "exits" namespace
)}
lib
keyword indicates that the code in the given file belongs to the named library.
This is similar to Golang's package keyword.
eon{
lib myLibrary}
import
keyword opens the designated .eon library and returns it as a card.
eon{
myLib: import "./libraries/myLibrary.eon"
// imported code is now available using myLib
// as library name. ie: myLib.printName("Bob")
}
insert
keyword opens the designated .eon file and directly inserts it into the current scope and executes it as-is.
eon{
insert "./helloWorld.eon"
// prints Hello World!
}