But currently lexp.Imm only supports sexp we cannot add the table as a sexp because of circular references plus it would not make much sense.
Agreed.
but we could have a Imm value type that would allow us to something like:
Right. I don't think it matters much in the end.
Basically, it all falls within what is considered as "predefined constants" in the theoretical presentation. This includes the Imms, the Builtins, and the AttributeMaps (actually, the SortLevels as well could be in there).
What would be good would be to make Builtins *closed* (and same thing for AttributeMap, regardless if it's stored within Builtin, within Imm, or within its own constructor). IOW make it so that "push_susp e s" is always equal to just e when e is of the form (Builtin ...), just as it is the case of Imm. So they're really just constants, like integers.
Currently Builtins are "morally closed" (the way we define them in types.typer, they're always defined within a context where all vars are LetDef, so they're known and could be replaced with their definitions, so as to get a closed type).
But add-attribute can occur "anywhere" rather than in a few controlled places like Builtin, so the attributemaps can contain lexps which refer to variables which are function arguments (i.e. have no value), so they're really not closed at all. Such things should be disallowed, I think. IOW in add-attribute we should check that the free variables of the lexp we add are all `LetDef`s rather than `Variable`s.
We should perform the same check when we `eval` a macroexpander (since the macroexpander can similarly refer to `Variable`s rather than `LetDef`s).
And of course, every one of the `LetDef`s used should itself only refer to other `LetDef`s etc... (IOW, be *closed*).
Stefan