[plt-scheme] macros that expand into top-level definitions with computed names
On Aug 11, 2009, at 11:39 PM, Lee Spector wrote:
>
> Thanks Matthias,
>
> That certainly is a different approach than defmacro! But it does
> seem to get me most of the way there and I think I could get the
> rest of the way (and maybe understand and appreciate more of what
> I've been reading in the Macros section of the reference) if I
> could see how to modify your example so that it evaluated its first
> argument, as in:
>
> (define partial-name "yours")
>
> (def partial-name x (sqrt x))
>
> (my-yours 4) => 2
>
> BTW this isn't for prefixing or suffixing per se -- it's for a
> version of a stack based language in which there are a bunch of
> types, a bunch of instructions that work the same way on all types
> but with different names and accessing different stacks, and I want
> to generate functions by looping over the two lists and executing a
> definition for each type/instruction pair. (These aren't PLT types,
> they're types in my language -- http://hampshire.edu/lspector/
> push.html -- and I'm not interested at the moment in doing this in
> any way that depends on PLT types... I just want to be able to
> generate and execute definitions with computed names and bodies,
> which is something I often find handy in CL.)
The above conflates two different things:
-- partial-name is a variable that maps to the run-time value "yours"
-- def is new syntax, which like definitions in mathematics, is
removed before run-time
We call these phases.
Now, if you happen to know the value of partial-name when you expand,
this is no problem. Just refer to partial-name in the macro (roughly
speaking). If you are figuring out these names at run-time, you're
looking at an extremely dynamic problem and macros may not be your
friend.
(Indeed, I don't know how CL would cope with this issue. When you
compile the code, macros go away, too.)
-- Matthias
>
> Thanks,
>
> -Lee
>
> On Aug 11, 2009, at 10:27 PM, Matthias Felleisen wrote:
>
>>
>> Do you mean this kind of thing:
>>
>> #lang scheme
>>
>> (define-syntax (def stx)
>> (syntax-case stx ()
>> [(_ f x body ...)
>> (identifier? (syntax f))
>> (let* ([f:sym (syntax-e (syntax f))]
>> [my-f:str (string-append "my-" (symbol->string f:sym))]
>> [my-f:sym (string->symbol my-f:str)]
>> [my-f:id (datum->syntax stx my-f:sym)])
>> #`(define #,my-f:id (lambda (x) body ...)))]))
>>
>> (def yours x (sqrt x))
>>
>> (my-yours 4)
>>
>> I recommend creating a module in your personal collects that
>> provides for adding prefixes and suffixes and importing it when
>> needed. It's in my standard collection
>>
>> -- Matthias
>>
>>
>>
>> On Aug 11, 2009, at 9:31 PM, Lee Spector wrote:
>>
>>>
>>> I'm still transitioning from Common Lisp (thanks for all of the
>>> pointers so far) and I'm having trouble doing something that I
>>> could easily do with a CL macro.
>>>
>>> I'd like to write a macro (or whatever) that takes two strings
>>> and defines a function named with the symbol formed from
>>> interning the concatenation of the strings. For example if the
>>> arguments have the values "my-" and "function" in a particular
>>> call then I'd like the effect of the call to be the same as
>>> something like (define my-function <more stuff here>).
>>>
>>> This is straightforward using defmacro in CL, but looking through
>>> the section of the PLT reference on macros I don't see where to
>>> start. In CL if I didn't know about defmacro, and if I didn't
>>> mind having my definitions evaluated in a null lexical
>>> environment, then I could hack it with eval. So with my new (but
>>> still minimal) understanding of eval and namespaces in PLT I
>>> tried this:
>>>
>>> -------
>>> #lang scheme
>>>
>>> (define-namespace-anchor nsa)
>>> (define ns (namespace-anchor->namespace nsa))
>>>
>>> (eval `(define ,(string->symbol (string-append "my-" "function"))
>>> (lambda () 'runs))
>>> ns)
>>>
>>> (my-function)
>>> -------
>>>
>>> This doesn't work -- expand: unbound identifier in module in: my-
>>> function -- although if I get rid of the call to my-function in
>>> the definitions pane then it does compile and allow me to call my-
>>> function (which then does the right thing) in the interactions
>>> pane. But that's not good enough for my purposes.
>>>
>>> Of course this hack with eval is probably the wrong approach
>>> anyway -- it would be a bad way to do it in CL and I'm guessing
>>> that a completely different approach would be appropriate in PLT.
>>> And I think I'm just not seeing the right part of the PLT docs
>>> because of the differences in terminology.
>>>
>>> Can someone point me in the right direction on this?
>>>
>>> Thanks,
>>>
>>> -Lee
>>>
>>> --
>>> Lee Spector, Professor of Computer Science
>>> School of Cognitive Science, Hampshire College
>>> 893 West Street, Amherst, MA 01002-3359
>>> lspector at hampshire.edu, http://hampshire.edu/lspector/
>>> Phone: 413-559-5352, Fax: 413-559-5438
>>>
>>> Check out Genetic Programming and Evolvable Machines:
>>> http://www.springer.com/10710 - http://gpemjournal.blogspot.com/
>>>
>>> _________________________________________________
>>> For list-related administrative tasks:
>>> http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
> --
> Lee Spector, Professor of Computer Science
> School of Cognitive Science, Hampshire College
> 893 West Street, Amherst, MA 01002-3359
> lspector at hampshire.edu, http://hampshire.edu/lspector/
> Phone: 413-559-5352, Fax: 413-559-5438
>
> Check out Genetic Programming and Evolvable Machines:
> http://www.springer.com/10710 - http://gpemjournal.blogspot.com/
>
> _________________________________________________
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme