Open jevdplas opened 2 years ago
The identifiers used for the parameters of a lambda
(and similarly, the variable names introduced by a let
-form) do not need to have a SchemeVar
wrapper around them, because we already know that we can only have identifiers in those positions. In contrast, for variable references encountered in “expression positions”, you obviously need to know what kind of SchemeExp
you are dealing with, so that’s why SchemeVar
is used there.
I also don’t think Identifier
itself should be made a SchemeExp, as it is basically just a naked string with a position attached to it.
Currently, for the analysis of Scheme, the expression type
SchemeExp
is used, which subclasses the general type of expressions,Expression
. One of the classes of Scheme expressions isSchemeVar
, which in essence wraps aroundIdentifier
, that in turn subclassesExpression
but notSchemeExp
.It is expected for
SchemeVar
to be used whenever variables appear in a Scheme expression, such as in lambdas and let constructs. However, often,Identifier
s are used directly (e.g., theargs
variable inSchemeLambdaExp
is a list of identifiers. This causes issues, asIdentifier
is not part of theSchemeExp
hierarchy. Hence, when e.g., the subexpressions of a Scheme expression are collected, it can not be guaranteed that these expressions are Scheme expressions as well. Clearly, this does not follow the intuitive and logical hierarchy that is to be expected.Several solutions to this issue are possible:
Identifier
also in theSchemeExp
hierarchy, and in all hierarchies it is required. This causesIdentifier
to be part of multiple hierarchies, but keeps things simple.SchemeVar
in a more consistent manner. The downside is that this class is a wrapper class that provides little additional functionality, so creating more variable objects can entail needless overhead.