Kernel
Glossary
Basic objects
Variable
A symbol to be evaluated
Combination
A pair to be evaluated. Basically (a . b)
?
Operator
The unevaluated car
of a combination.
- So pretty much the function of an s-expr?
Operand tree
The unevaluated cdr
of a combination
Operands
The operand tree is usually a list, e.g. (+ 1 2 3 4)
, in which case any element of that list is an operand
Arguments
The results of evaluating operands - this is the usual case, where the evaluated values are used, rather than the operands themselves.
- This is the difference between a function’s arguments and a macro’s ones? Functions have arguments, while macros have operands
Combiner
The result of evaluating the operator (if type correct (?)), as it says how to evaluate the combination
Operative / Operative combiner
A combiner that acts directly only on its operands.
- a macro?
Applicative / Applicative combiner
A combiner that acts only on its arguments.
- a func?
Combiner states
Active
A combiner call is active if the called combiner may still return. This can be because:
- it’s currently being evaluated
- it’s called a different function and waiting for it to return
- continuations magic (e.g. python generators)
Tail context
The last expression of a combiner? Or something that can trivially be deemed as so? This includes function calls if the are obviously the last thing, i.e. of the value returned from the combiner is the result of calling the combiner that is the tail context
Tail call
A combiner call that is evaluated as a tail context. Kernel implementations must properly support unbounded tail calls
Naming conventions
Operatives
Start with “$”
Predicates
The names of combiners that always return a boolean always end with a “?”
Mutators
The names of combiners that modify previously existing objects always end in “!”. The value returned by a mutator is inert.
Transformers (my name)
The name of combiners that take an object of one type and return an analogous object of another type should contain “->”
Identifiers
The basic lisp approach, basically. Must start with a something that is not \d, “+”, “-” or “.”, and the following are also valid:
! $ % & * + - . / : < = > ? @ ^ _ ~
Illegal characters
’ ‘ , ,@ - to avoid confusion with macro escaping in other lisps
Data Types
Cyclic data structures
- explicitly allowed
- operations on them should only process each item once when that makes sense (e.g.
$equal?
) - implementations of Kernel must refrain from endorsing any particular order of processing for combiners. Does this mean that short curcuiting should not be assumed to work?
#inert
Sort of like void
in C - it means that nothing is returned from a combiner.
The result of any combiner that is used for side effects must be #inert
- separation of pure functions? Seem legit.
#ignore
Pairs
A tuple of (<car> . <cdr>)
- basic stuff. When printing, should do as few parenthesis as possible, e.g. (1 . (2 . (3 . nil)))
-> (1 2 3)
null
As expected
Environment
A set of bindings + a list of parents. There are no facilities for enumerating all variables, nor for identifying parents
Lambda vs Vau
This seems to be the most important aspect. Lambda receives an evaluated list of parameters, while Vau gets unevaluated ones (plus a local environment). So lambda is a subset of vau, sort of like:
(lambda params) == (apply vau (map eval params))
wrap
This pretty much transforms a vau into a lambda:
(wrap (vau params env body)) ~= (lambda params body)
It takes a combiner and returns it as an applicative.
Strange stuff
- How does equal? work?