From c20b346487601ce46683cc80735663684e661951 Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Mon, 27 May 2019 22:17:53 +0100 Subject: [PATCH] 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. --- mal/env.mal | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mal/env.mal b/mal/env.mal index 40937c58..bec21c37 100644 --- a/mal/env.mal +++ b/mal/env.mal @@ -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]