Kernel

3 minute read

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?