Macro - function problems
[1/4] from: robbo1mark::aol::com at: 12-Mar-2002 12:57
Hi everybody, Iam looking for help to write a MACRO transformation function. Iam looking for the guru's on this list to help me with some lexical scoping and "Hygienic" problems I've been having with regards to my 'MACRO function. My MACRO function takes three arguments which are these 'name [word!] args [block!] body [block!] and should construct a transformer function which allows named words to produce an executable expression (ie a paren! or alternatively a 'DOES function) which can be bound to a word and properly handles (lexically substitutes) the correct arguments and which can also allow for nestable macro expressions! here are some simple examples of what I mean
>> MACRO nil ['word] [set word zero] >> nil b
== (set 'b zero) ; or func  [set 'b zero]
>> source b
b: (set 'b zero) ; or func  [set 'b zero]
>> source b
b: 0 and another example
>> MACRO printer ['word 'value] [print value] >> printer test "Hello"
== (print "Hello) ; or func  [print "Hello"]
>> source test
test: (print "Hello") ; or func  [print "Hello"]
Hello Obviously you could imagine more advanced and / or exotic examples. I can produce these functions individually making use of things like 'compose, 'to-paren and 'quote which is defined thus, quote: func ['val] [:val] However the deeper / more general solution and lexical intricacies escape me and thus I need your help. Thanks in advance, mark Dickson
[2/4] from: rotenca:telvia:it at: 13-Mar-2002 1:07
> My MACRO function takes three arguments > which are these
<<quoted lines omitted: 15>>> >> source test > test: (print "Hello") ; or func  [print "Hello"]
A solution (not a guru's one) could be: macro: func ['w spec body][ set :w func spec compose/deep [set get (first spec) does compose/deep [(body)]] ] which must be used with this syntax: macro printer ['word 'value] [print (value)] The substitution is made by compose, so the 'value must be between parens, this limits the use of parens in the body (but there is a workaround: (to-paren )). Another more general solution could be a closure func. In this example:
>> MACRO nil ['word] [set word zero] > b: (set 'b zero) ; or func  [set 'b zero]
the arg 'word is used twice: 1) like the name of word to assign the macro 2) like a value in the macro body The result is a macro which changes the word which points to itself. I think should be better to distingue the two. BTW, with my solution, the nil should be: macro nil ['word] [set (:word) zero] nil 'b source b b: func [set 'b zero] hope this helps --- Ciao Romano
[3/4] from: al:bri:xtra at: 13-Mar-2002 17:48
Mark Dickson wrote:
> I am looking for help to write a MACRO transformation function.
I'm not sure what you want, but something like this might be helpful: use [Weekdays Index] [ Weekdays: system/locale/weekdays forall Weekdays [ Index: index? Weekdays system/locale/weekdays do reduce [ to set-word! join first Weekdays "?" 'func [ "Is Date this weekday?" Date [date!] ] reduce ['= Index 'Date/weekday] ] ] ] which produces this:
>> source Wednesday?
Wednesday?: func [ "Is Date this weekday?" Date [date!] ][= 3 Date/weekday] and is used like:
>> Wednesday? 13/Mar/2002
== true Andrew Martin ICQ: 26227169 http://valley.150m.com/
[4/4] from: robbo1mark:aol at: 13-Mar-2002 2:37
Hi Romano, Your solution is a close approxmiation of what Iam looking for - which is basically a higher order 'MACRO function which return a function bound to the 'name argument which when evaluated binds a paren! or 'DOES function to the first 'SPEC or 'ARGS argument and in turn substitutes any / all remaining args in the 'SPEC correctly in the resulting paren! or 'does function 'BODY . As I said Iam sure it is possible to produce such a macro constructor function which even allows for "nested" macros within the 'args or 'body. Will think more about your solution, cheers & thanks, Mark In a message dated Tue, 12 Mar 2002 7:20:52 PM Eastern Standard Time, "Romano Paolo Tenca" <[rotenca--telvia--it]> writes:
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted