dok/syntax
Various decisions
The syntax of a PL has many low-level details. The current decision taken are:
- use
()
for function call - use
[ ]
for declaring structural things and DSL declarations - use
{ }
for declaring executable things - use
{[ ]}
for declaring executable things in DSL syntax - same prefix keyword like “slot” has different meaning if it is used inside
()
or[]
or{}
: inside[ ]
it declares a slot, inside.( )
it assign the slot value to cloned value. T
is not allowed, only../T
or some explicitType/.../T
slot ~::Color
meansslot color::Color
and it is used when the slot name has the same name of the type. In the type there can be also parameters instantiation- in nested
{ }
, “self” is still the current object of the method - methods starting with
_
are private :
is used for meta-info/annotations involving the parent scope:^
is used for meta-info involving the previous code
Compact notation for lists
var x* Int*[ 10, 20, 30]
:^# the type of `x*` is inferred, and the init expression uses the `Int*` DSL syntax for declaring it
Special names clashes
Inside a lambda like self.filter({~.isa(../Var)})
the ~
is related to ~this
that is the unique lambda term. In case of conflict with a parent ~
representing another lamda term, or a parent visit something { ... }
, then it is mandatory to use ~this
for the lambda term.
Dok statements starts always with a prefix
Dok syntax follow a uniform pattern:
- instruction type (e.g.
fun
,var
,slot
,data
,set
) - identifier name
- params inside parens
- etc…
Sigils
Sigils are used for
*
for a stream of values+
for a stream of values with at least one value!
for a method changing the slots of an object, and that it is backtrable if in Dok, or not dangerous if in a DSL. It returns by default the new version ofself
!!
for non-backtrable operations, changing the state of the system and returning a result?
for a predicate returning true or false$
for a mutable reference, i.e. it is not a value