>>20
Pretty good, but we should take advantage of the ability to name or not name blocks as we wish.
[define]
add-pair
[+]a b[/+]
[/define]
# [add-pair]1 5[/add-pair]6
# [add-pair]1 5 [atom name=lol]``code''[/atom][/add-pair]6
Numbers and strings written alone are shorthand for [atom]value[/atom]. If they are given as parameters to a function, they get the names a, b, c, etc. The symbol "args" is a list of all unnamed arguments. When a function foo (e.g. [foo]) is followed by one or more parameters of the form n=x (e.g. [foo n=x]), those symbols are bound to those values in the environment that function is evaluated in. They go out of scope when it ends. However, a function may also return a named value which enters the environment "the next level up". So, in the last example, [add-pair] is evaluated, then its arguments 1 and 5 are evaluated and assigned the symbols a and b, respectively. Then the next argument is evaluated. Atom's environment contains the binding 'name = "lol"', and creates the binding 'lol = 7' in its caller's environment. If we were to add the code [when][boundp]lol[/][return]``idk, 60 million lol''[/return][/when] to add-pair, then the second example would return the string ``idk, 60 milion lol'' in the second example, rather then the correct answer of 6. Also note that [/] may be used to close a block if your typing finger is tired, and that quotes are written ``'' for enterprise-grade nestability.