[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Mon, 9 Jul 2007 23:11:58 +0100
Ok, as I mentioned previously, in Wings I'm defining a dynamic wings
environment to pass resources into request handlers.
Naturally, it's nice to use proper SRFI parameters where one can; the
environment is for things where they won't work elegantly, such as
structured names (data source "foo" has getters called (get foo),
setters called (set! foo), etc) and situations that are just too
Now, I'm writing some code to wrap Spiffy request handlers, so that
if there's a file called foo.wings when a file called foo is being
handled, the contents of it are read and treated as an alist of
bindings for use within the dynamic scope of this request.
Since this happens at runtime, I think these bindings will have to go
into the Wings local environment, but an (admittedly slightly tipsy)
scheme on IRC says he's sure he can write a (parameterize-from-alist
alist body) macro that takes an alist of parameter names at runtime
and executes the body within their dynamic scope.
I think this could only be done with eval hackery:
(parameterize-from-alist alist . body) =>
(let ((body-lambda (lambda () body))
(eval `(parameterize ,alist ,body-lambda)))
...with some processing of the alist to convert ((a . b) (c . d)) to
((a b) (c d)). Which is hacky.
If that'd even work; I'm not sure who compiled Chicken code passes
environments to eval-ed Chicken code. I guess each time eval occurs
the compiler has to encode the environment in some way so it can be
accessed at runtime.
[On a tangent, it'd be kinda cool if (eval '(lambda (foo) (bar baz)))
actually returned a compiled lambda. As I understand it, Chicken just
returns a closure whose code is the evaluator, closed over the
definition of the lambda, so calling it just evaluates the body.
However, I note that Felix has written eggs for the GNU Lightning
runtime code generator and a C compiler that can compile straight to
memory... I wonder what his plans are...]
He suggested I ask on The List, so here it is. Is there a way to
write parameterize-from-alist without eval hackery, or shall I just
use the wings dynamic environment?
To put it in perspective, here's a sample .wings file, tests/test.wings:
(foo ,(+ 1 2))
rest (baz ...))
(wings:let (('foo 1)
(it's evalled inside a quasiquote, so you can do ,(...))
Let's test lookup of the 'arguments' key:
#;9> (wings:call-with-metadata "tests/test" (lambda () (wings:get
((positional (foo 3) (bar ...) rest (baz ...)) (named (foo ...)
(bar ...) (baz ...)) (derived (foo ...) (bar ...) (baz ...)))
And let's also test things bound via the wrapper function which, if
present, wraps handling of that file:
#;10> (wings:call-with-metadata "tests/test" (lambda () (wings:get
And, just for completeness, a global binding:
#;11> (wings:env-global-bind 'fish 'hello)
#;12> (wings:call-with-metadata "tests/test" (lambda () (wings:get
- [Chicken-users] parameterize-from-alist,
Alaric Snell-Pym <=