-
-
Notifications
You must be signed in to change notification settings - Fork 4
evaluation
Code is Data that is charged. Code that is evaluated is Data.
Objects are generally kept in their symbolic form until their lazy evaluation can no longer be delayed.
In root contexts and function calls objects get fully evaluated. Root contexts are the shell, files and the main function.
z=y*y
y=x+x
x=3
z=y*y
would be erroneous in a normal block, if y was not defined!
In the shell objects are printed in their symbolic form and evaluated until their final value is revealed:
>>> z
y*y
(x+x)*(x+x)
(3+3)*(3+3)
6*6
36
To see the final value of directly, objects are evaluated with o()
o?
or o!
>>> z!
36
The shell also has a direct mode in which the intermediate steps are omitted and just the final value is printed. Which way is default can be configured.
Objects being charged means that data is treated as code, and that their symbol gets evaluated.
help={print:"there is no help "}
> help # nothing happens, help is **uncharged data**
> help! # turns data into code and executes it
to help={print:"there is help "}
> help # prints the message, help was code
help={info:{get help}}
help # in root contexts like the shell help gets evaluated and ``get help`` is called
info:{get help}
info:"whatever get help returned"
Objects get charged with function keywords like to as can be seen above.
To uncharge symbols/functions they can be prefixed with function,code or data.
E.g. print function help
will print the function definition, and not call get help
.
When calling a function all parameters are fully evaluated (unless being explicitly uncharged as above)
It is important to note that help={data:{get help}}
will not call get help
until help is evaluated.
To create data with return values of evaluated functions on the spot, objects are evaluated with o() o? or o!
help={info:{get help!}}
help={info:"whatever get help returned"}
The exclamation operator '!' evaluates everything in an expression on its left side (on the spot).
Later: As in lisp there can be several levels of quoting. macros are just second order functions of auto-quoted data. To force arguments as being auto quoted, they can be denoted as data = quoted or code = block . To do: are these really equal synonyms, or does the block keyword act differently to the code class?
If in doubt, objects can be evaluated on the spot (in the current context) with o() o? or o!
The lisp concepts of quoted code as data closely resemble Angle's concept of uncharged symbols aka data. Unlike lisp in Angle charging and unchanging (un-quoting and quoting) are equal parts of the language.
While lisp is "function default" angle is "data default", that is: anything which is not a function is treated as data, unless (explicitly) evaluated in which case that data is treated as code.
The difference between code and charged symbols is subtle: A symbol which holds data is code once the symbol is evaluated. A charged symbol gets evaluated whenever it occurs. Code gets evaluated without being attached to a symbol. What sounds complicated shall be obvious in the examples from above
help={info:"there is no help "} # data
help={info:{get help}} # data until evaluated with help!
help={info:{get help!}} # data with value of `get help`
to help={print "there is no help "} # charged symbol, call with help! or just `help`
info:{get help} # code evaluated on the spot
() denotes code by default {} denotes data by default
Is it possible to write closures as x : x*x
?
so {x:x*x}(3)=9
?
map [1 2 3] x:x*x == [1 4 9] ?
Alternative syntax:
map [1 2 3] x:x*x
map [1 2 3] x=>x*x
map [1 2 3] x->x*x
map [1 2 3] (x){x*x}
map [1 2 3] {it*it}
map [1 2 3] it*it # no! it could be already evaluated!!
map [1 2 3] {|x| x*x} #meh
map [1 2 3] {x in x*x}
In which situations does a symbol get executed multiple times?
square x:=x*x # only once: x is argument
square x=x*x # only once: x is argument
square:=x*x # twice (or never if kept symbolically)
square=x*x # only once: x is context variable, or twice?
The result
keyword always refers to the last object in the stack, either the last declaration or the return value of the last function call. result
variable is also set in code such as
if 1>0 : print "hi" else : print "ho"
print result # => "hi" !
Functions which return void 'return' the last value in the result slot. Todo: bad concept? side effects and information leakage.
In lambda expression, the it
keyword refers to the first (implicit argument), otherwise it refers
to self or the last result.
double:=it*2 # it creates implicit argument for function 'double'
double=it*2 # instant evaluation or it as last result
double:it*2 # it may later be evaluated in contect
Todo: ambiguity
A block is executed by giving it a group on the right:
((fun f x -> f (f x)) ((+)3) 7) (* 13 *)
since groups of one element are the element itself (x)==x
, there is an ambiguity if the braces are omitted