-
Notifications
You must be signed in to change notification settings - Fork 2
environment
TurtleKitty edited this page May 11, 2019
·
4 revisions
Environments map names to values.
Whenever you bind a name (def name value), you are changing the environment.
Functions and operators close over the variables in their lexical parent environments.
Environments are append-only.
The current environment can be accessed by the dynamic variable env.
(let (foo 2)
(env.def! 'bar 3)
(say env.type) ; (env)
(say (env.get 'foo)) ; 2
(say (env.has? 'bar)) ; true
(say (env.has? 'baz)) ; false
env) ; #(env foo 2 bar 3)
; lookup and parent
(let (foo 2)
(let (bar 3)
(env.lookup 'foo) ; 2
(env.lookup 'bar) ; 3
(env.lookup 'baz) ; null
env ; #(env bar 3)
env.parent)) ; #(env foo 2)
; extend - create a new environment with the receiver as parent
(let (foo 2)
(def x-env (env.extend 'bar 3))
x-env ; #(env bar 3)
x-env.parent ; #(env foo 2 x-env #(env bar 3))
(x-env.lookup 'foo)) ; 2
; eval - interpret quoted s-expression as code
(let (x 7)
(env.eval '(* x 100))) ; 700
; expand - show final macroexpansion of all operators
(let ()
(env.expand '(cond
(= x 0) 'zero
(< x 7) 'less-than-seven
else: 'bigger-than-7)))
; (if (= x 0) (quote zero) (if (< x 7) (quote less-than-seven) (quote bigger-than-7)))
; load - read code from a stream and inject it into the environment
(let (x 1 code "(def y 2)")
(env.load code.to-stream) env) ; #(env y 2 x 1 code "(def y 2)")