Skip to content

evaluation

pannous edited this page Nov 18, 2020 · 17 revisions

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

⚠️ In the shell, assignments are treated symbolically! 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={info:"there is no help "}
> help # nothing happens, help is **uncharged data**
to help={print "there is no 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} 

repeated symbol execution

In which situations does a symbol get executed multiple times?

square x:=xx # only once: x is argument square x=xx # only once: x is argument square:=xx # twice (or never if kept symbolically) square=xx # only once: x is context variable, or twice?

result keyword

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. ⚠️ since everything in angle is an expression, the special 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.

it keyword

In lambda expressions, 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

Home

Philosophy

data & code blocks

features

inventions

evaluation

keywords

iteration

tasks

examples

todo : bad ideas and open questions

⚠️ specification and progress are out of sync

Clone this wiki locally