Version 57 of Neil Madden

Updated 2006-10-11 23:46:02 by NEM

Email: nem AT cs.nott.ac.uk

Web
http://www.cs.nott.ac.uk/~nem/
Location
Nottingham, UK.
Date of Birth
27 October 1980.

I am a PhD student at the University of Nottingham[L1 ] in the UK. Pages I have created:


Experimenting with a Tcl version of 3-Lisp's reflective lambdas. In 3-Lisp, a reflective function receives 2 extra arguments: the environment of the caller and the continuation of the caller. IIRC, it also receives the other arguments in unevaluated form. This allows you to do loads of things: lazy evaluation, various kinds of meta programming etc. They are pretty much as powerful as Lisp macros, but I think they fit Tcl's model much better - e.g. they could be a replacement for uplevel that doesn't explicitly reference the stack. Anyway, here's a first stab at emulating them in current Tcl using uplevel/upvar:

 namespace eval meta {
     namespace export proc apply
     namespace ensemble create
     ::proc proc {name params body} {
         interp alias {} $name {} ::meta::apply [list $params $body ::]
     }
     ::proc apply {proc args} {
         set env [capturelevel 1]
         uplevel 1 [linsert $args 0 ::apply $proc $env]
     }
     ::proc capturelevel level {
         incr level
         set env [dict create]
         foreach name [uplevel $level { info vars }] {
             upvar $level $name value
             catch { dict set env $name $value } ;# no arrays
         }
         return $env
     }
 }

This version is very limited: it captures the caller's variable environment as a dict and passes it to the meta-proc. So, read-only and variables-only. Still, it demonstrates the idea. Now, imagine this was read/write, and that the environment contained vars and commands. (Perhaps if we unified command/var names in Tcl 9?) Now also imagine that you get the current continuation as another arg...

Example:

 % meta proc get {env name} { dict get $env $name }
 get
 % proc foo {a b} { puts "a = [get a], b = [get b]" }
 % foo 1 2
 a = 1, b = 2

[ Category Home Page | Category Person ]