PLT Scheme seems to have procedure-arity so perhaps there's some hope
for me, but that's of course not sufficient, what I'd need would be
something like get-procedure-body-as-a-data-structure... Is it
possible, or is there a better approach to the whole problem (runtime
introspection)?
There is nothing in the R5RS standard to help here. If your
implementation provides an usable API for introspection, then be
happy. Otherwise, thanks to the metalinguistic properties of scheme,
you can easily implement your own introspective scheme, in scheme.
--
__Pascal Bourguignon__ http://www.informatimago.com/
HEALTH WARNING: Care should be taken when lifting this product,
since its mass, and thus its weight, is dependent on its velocity
relative to the user.
So I suspected. Thanks.
> Otherwise, thanks to the metalinguistic properties of scheme,
> you can easily implement your own introspective scheme, in scheme.
Could you (or anyone else) give me some pointers or ideas as to how to
get started with that? I'm an utter newbie with Scheme and it's really
not obvious how to go about it.
For practical purposes, you're probably better off using the
facilities provided by some "real" Scheme implementation, but still,
if you're interested in how to implement an introspective Scheme in
Scheme, then Queinnec's "Lisp in Small Pieces" is probably an ideal
introduction.
Lauri
Study SICP.
Then in the scheme implementation it gives, modify eval-assignment and
set-variable-value! to keep in addition to the value (evaluated), the
source form.
Basically:
(define (eval-assignment exp env)
(set-variable-value! (assignment-variable exp)
(eval (assignment-value exp) env)
env)
'ok)
becomes:
(define (eval-assignment exp env)
(set-variable-value! (assignment-variable exp)
(assignment-value exp) ; the source form
(eval (assignment-value exp) env) ; its value
env)
'ok)
Then add a primitive to retrieve the source form you'll have kept in
the environment.
This would allow to write:
(define a (* 2 3))
a --> 6
(source-form 'a) --> (* 2 3)
(define (f x) (* 2 x))
(f 3) --> 6
(source-form 'f) --> (lambda (x) (* 2 x))
Another way would be to keep the source form along with the procedures
[assuming you don't care about (* 2 3) vs. (+ 2 4)], thus allowing this:
(define (f x) (* 2 x))
(f 3) --> 6
(source-form f) --> (lambda (x) (* 2 x))
(source-form (lambda (x) (+ x x))) --> (lambda (x) (+ x x))
In this case,
(source-form 'f) --> f
Alternatively, if your implementation provides the optional procedure:
(interaction-environment) then you could add the needed bookkeeping
implementing just a REPL, somewhat like I did for Common Lisp in:
http://www.informatimago.com/develop/lisp/small-cl-pgms/ibcl/
What you can do is implement your own lambda macro, which allows you to
record whatever information inside the lambda form is interesting to
you. For example, you can associate that information with the resulting
function object(s) in an association list or hashtable (if they are weak
tables, then you don't even have problems with garbage collection).
However, in the general case you need information about the lexical
environment that is captured in the function object. This is not
something that you can add on top of Scheme without implementing a new
Scheme interpreter with first-class lexical environments from scratch.
If you want to use existing implementations with support for first-class
environments, your best bets, to the best of my knowledge, are Guile and
clisp in interpreted mode (the latter of which is not a Scheme, but a
Common Lisp). I am not aware of any other implementation that provides
first-class lexical environments.
Pascal
--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
>Is there any nice way to perform procedure introspection in Scheme?
>That is, I'd like to be able to inspect, at runtime, the internal
>structure of a procedure; what arguments does it take and what does
>the procedure body look like?
You might look into MIT Scheme. I have heard tell that it has some
of the best or at least, very good introspection facilities.
Aaron
--
+++++++++++++++ ((lambda (x) (x x)) (lambda (x) (x x))) +++++++++++++++
Email: <arc...@sacrideo.us> | WWW: <http://www.sacrideo.us>
Scheme Programming is subtle; subtlety can be hard.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
You might be interested in an API that dates back to 1996,
and has been implemented (at least partially) in Larceny
and in several other implementations of Scheme:
http://larceny.ccs.neu.edu/doc/user-manual-alt.html#procedure-arity
Note that this API is intended only for heuristic uses.
If you need something truly reliable, you'll probably have
to roll your own.
Will