1
1
mirror of https://github.com/kanaka/mal.git synced 2024-09-17 16:47:22 +03:00

mal: Use a keyword to link each environment to its outer one.

Heretofore, the mal implementation has linked each environment to its
outer environment by defining a special symbol, '--outer--' in that
environment.  This causes that symbol to be unusable by programs running
under that implementation.  For instance:

  (def! foo 123)
  (def! f (fn* (--outer--) foo))
  (f)

gives an error because overwriting '--outer--' breaks the environment
chain.

Happily, mal provides a way around this.  Keywords are guaranteed to
work as hashmap keys, so by using a keyword instead of a string as the
key for the outer environment, it can be hidden from user code.  This
also provides a motivation for keywords, which aren't otherwise used by
the mal implementation.
This commit is contained in:
Ben Harris 2019-05-27 22:17:53 +01:00
parent 4aa1c85b88
commit c20b346487

View File

@ -12,8 +12,8 @@
(def! new-env (fn* [& args]
(if (<= (count args) 1)
(atom {"--outer--" (first args)})
(atom (bind-env {"--outer--" (first args)}
(atom {:outer (first args)})
(atom (bind-env {:outer (first args)}
(nth args 1) (nth args 2))))))
(def! env-find (fn* [env k]
@ -21,8 +21,8 @@
data @env]
(if (contains? data ks)
env
(if (get data "--outer--")
(env-find (get data "--outer--") ks)
(if (get data :outer)
(env-find (get data :outer) ks)
nil)))))
(def! env-get (fn* [env k]