Mercerenies / gdlisp

Lisp on the Godot platform
GNU General Public License v3.0
140 stars 1 forks source link

Anonymous class closures can conflict with parent instance variables #82

Open Mercerenies opened 2 years ago

Mercerenies commented 2 years ago

The following code works as intended.

(defclass Foo (Reference))
(defn foo (x) (new Foo (defvar x 2) (defn g () (list self:x x))))

The conflict between the (public) instance variable x and the closure variable x is detected, and the latter is renamed to x_0 in the generated code. However, if the instance variable is declared in a parent class.

(defclass Foo (Reference) (defvar x 2))
(defn foo (x) (new Foo (defn g () (list self:x x))))

Then the conflict is not detected and erroneous code is produced.

Parsing the instance variables of all parent classes is difficult and, in general, requires parsing GDScript as well as GDLisp, which would be a significant undertaking. So we need to reconsider how to ensure uniqueness of closure names in lambda classes.

This issue does not exist for ordinary classes, since they never close over variables, and it does not exist for lambda functions, since they cannot have explicit instance variables or parent classes. The conflict occurs when we have both instance variables and closure variables in one construct.