From: Trevor D. (Twylite) <tw...@cr...> - 2012-10-18 16:23:37
|
Hi, On 2012/10/18 05:39 PM, Alexandre Ferrieux wrote: >>> OK, then I realize that the underlying feature I am after is a >>> preprocessor/inliner (possibly coupled with TAL), so that all the >>> variants mentioned in the tip discussion can be written in script. >> - when pproc itself is called (long before the function is called), >> the body is parsed, a nested list representing the parse tree is >> passed as arg to a user-defined preprocessor-hook function. >> - the value $v returned by the hook is the new tree to use. >> - then a normal proc is stored, whose body is [list ::tcl::parsed $v] If I'm understanding you correctly, one of my lines of thought has been similar. But this approach would mean that you cannot define a macro that can be called from a regular proc (unless you redefine ::proc as ::pproc)? Are there equivalently-enhanced versions of [apply], oo::define method, etc? This approach also conceptualises a macro as a compile-time transformation rather than a run-time command. So one cannot treat a macro like a regular command and do things like 'set cmd $macroname; {*}$cmd param ...'. >> Note this is the bare-metal API, with a single hook. It is trivial >> (and highly bikesheddy) to layer on top of it a primitive like [macro] >> with a more declarative (and practical) usage. Practically such bikeshedding is required (in my opinion). There needs to be a way for enhancements ("macros") to be provided in different packages by different authors, which means a defined infrastructure should exist above the single hook. For example, how would a C extension "register" a transform? (Aside: I have a vague prototype of something called [annotate] that I'll be putting on my blog soon [well, soonish; bit snowed under at the moment]. It's a slightly more general framework to preprocess definitions include proc, apply, method, etc. that allows rewriting of the arglist and the body as well as the sort of things you can do with c#/.net or java annotations). My other line of thought has been to define a command ::macro {name args} that defines a proc and has a second body that returns a script to be compiled in place of "$name {*}$args". For example: macro assert {body} { if { $::DEBUG } { uplevel 1 $body } } { list if {$::DEBUG} $body } When a macro is defined a command proc and a compile proc are added to the Tcl command table. The compile proc executes the second body and compiles the returned string/list. This should permit reasonably easy definition (by developers) of a macro that acts like a command in both evaluated and compiled contexts, and handles the case I am most interested in: overcoming the performance penalty of proc calls and uplevel for debug-only calls (e.g. assert), parameter checking helpers, and control constructs. I _think_ I may even know how to go about implementing this ;) but I'm not sure how widely applicable it is outside the scope of my interests. Do you have any interesting use-cases that this [macro] can't cover? Regards, Twylite |