|
|
|
|
|
by sparkie
363 days ago
|
|
Kernel has first-class environments which aren't just lists, but can be constructed from lists. Environments are encapsulated, so we can't simply peek into them with car and cdr - we can only obtain the value associated with a given symbol by evaluating the symbol in that environment. ($define! foo
($bindings->environment
(bar "Hello World")
(baz 1234)
(qux #f)))
($remote-eval bar foo) ==> "Hello World"
foo ==> #[environment]
We could perhaps make something a bit more friendly. Lets create an encapsulated `struct` type which could give us the contents as a plain list, or let us look up each field: ($provide! ($struct struct? destruct $get)
($define! (struct-intro struct? struct-elim)
(make-encapsulation-type))
($define! destruct
($lambda (struct)
(cdr (struct-elim struct))))
($define! $get
($vau (struct member) e
($let ((record (car (struct-elim (eval struct e)))))
(eval member record))))
($define! zip
($lambda (keys values)
($if ($and? (null? keys) (null? values))
()
(cons (list (car keys) (car values)) (zip (cdr keys) (cdr values))))))
($define! $struct
($vau kvpairs env
($let* ((keys (map car kvpairs))
(values (map ($lambda (pair) (eval (cadr pair) env)) kvpairs))
(record (apply (wrap $bindings->environment) (zip keys values))))
(struct-intro (cons record values))))))
Example usage: ($define! foo
($struct
(bar "Hello World")
(baz (+ 12 43))
(qux #f))) ==> #inert
(struct? foo) ==> #t
(pair? foo) ==> #f
(environment? foo) ==> #f
(destruct foo) ==> ("Hello World" 55 #f)
($get foo bar) ==> "Hello World"
($get foo baz) ==> 55
($get foo qux) ==> #f
($get foo foo) ==> ERROR: Unbound symbol: foo
foo ==> #[encapsulation]
Kernel: https://web.cs.wpi.edu/~jshutt/kernel.htmlKlisp (essentially complete implementation of Kernel): https://github.com/dbohdan/klisp |
|