// Expr represents an arbitrary expression.
type Expr struct {
// An Expr is either an atom, with atom set, or a list, with car and cdr set.
// Car and cdr can be nil (empty) even if atom is nil.
car *Expr
atom *token
cdr *Expr
}
Instead of using interface types for expressions, there is a simple expression structure type with fields that may or may not be set depending on what type of value it is.
I probably never would have done it that way, I would probably use an interface type instead. This way actually saves space in cons objects… in the above version, a cons is 24 bytes, and below it would be 32:
type Expr interface { }
type Cons struct { car, cdr Expr }
Not efficient compared to modern Lisp interpretations, but an interesting choice.
I probably never would have done it that way, I would probably use an interface type instead. This way actually saves space in cons objects… in the above version, a cons is 24 bytes, and below it would be 32:
Not efficient compared to modern Lisp interpretations, but an interesting choice.