Please stop me if you've heard this one before...
What would it take to add a macro facility to Tcl? What use would such a facility be?
Well, for starters, it would make syntatical sugar (attrocities) such as:
proc first {l} { lindex $l 0 } proc rest {l} { lrange $l 1 end }
cost less in terms of performance. Yes, yes, I know -- if performance really mattered I shouldn't be doing this in Tcl. But the difference between calling my own procs vs internal ones (especially in deep loops) count, right?
Well, what about immediate macros (or macros that have a compile time behavior). Common Lisp should come to mind, but I can't help thinking about Forth immediate words. So, I could do something like:
mac log {msg} { global debug if {$debug} { return "puts stderr $msg" } else { return "\;" } }
and use it thusly:
set debug 0 ... proc something {} { set stuff "contents not available for introspection by macro yet." log "Some noise I may not want to see depending on the value of debug" log $stuff; # if debug was 1, then the macro would expand to: puts stderr $stuff ... }
The above assumes that I have redefined proc to point to a macro evaluator to execute all macros before actually defining the real proc. The return value of the macro evaluation is what replaces the macro in the procedure. In this example, I can do conditional compilation!
This could all be done in plain Tcl if I gave Tcl access to the Tcl C parser code (to properly locate the arguments for the expanding macro). Note: You are limited by what context is available when executing the macro (you can for instance look into the surrounding proc's variables since we are in compile mode --- there aren't any values for the variables yet so the arguments to the macros are not eval'd!).
Another use for an immediate macro facility:
mac mloop {idx cnt cmd} { return "for {set $idx 0} {\$[set $idx] < $cnt} {incr $idx} {$cmd}" } proc something {} { mloop i 5 {puts "hello $i"} # above expands to: for {set i 0} {$i < 5} {incr i} {puts "hello $i"} }
My mind is often polluted by such sickness...
-- Todd Coram