[plt-scheme] Runtime accounting for unbound identifiers
I'm in a situation where I want to evaluate code such as '(foo (bar
baz)) but foo, bar and baz may not be defined in the context of
evaluation. I will have a procedure somewhat like (find-identifier name)
that will (slowly) find an identifier by its name, whether foo, bar,
baz, or any of a hundred other identifiers I might have stored away
somewhere. But I'm not sure how to use find-identifier to make sure all
the identifiers specified in an arbitrary s-expression like '(foo (bar
baz)) are present and accounted for.
I don't want to find and re-evaluate all pieces of code in my database
every time I evaluate any s-expression. What I want is to get a list of
identifiers that need to be found, search for them, and only error out
if none of those identifiers are found anywhere. That's what I think I
absolutely need, is some way of analyzing code that will let me specify
which identifiers it depends on, that aren't satisfied by some global
already defined namespace.
It might also be nice to record where these runtime identifiers were and
associate that with some compiled representation of aforementioned code,
so that the next time it's evaluated my program won't have to search for
the identifiers by name, recursively.
I'm thinking like:
'(foo (bar baz))
(find-identifier 'foo) > '(a b c)
(find-identifier 'bar) > '(lambda (thing) (+ thing 19))
(find-identifier 'baz) > '23
(find-identifier 'a) > '(lambda (one two) display)
etc...
>>>
'((lambda (foo bar baz)
(foo (bar baz)))
((lambda (a b c)
(a b c))
(lambda (one two)
(lambda (num)
(display one)
(display two)
(newline)
(display num)
(newline))
2
3))
(lambda (thing) (+ thing 19))
23)
; display is already defined (built-in)
; so no need to try find-identifier on it