1

How would I go about in doing a define-syntax-rule that accepts a list as arguments and a list (or a quote, in case it is a single element) as body of a lambda? i would like to do something like:

    >(define a (lambdarize '(x y z) '(+ x y z)))
    #<procedure>
    >(a 1 2 3)
    6
    >(define b (lambdarize '(x) 'x))
    #<procedure>
    >(b 1)
    1

I have played around with define-syntax-rule and apply, but since lambda itself seems to be a macro and not a procedure, i have been stumped at trying to find it...

oh... And I would like a solution that does not use eval, as it is pernicious...

UPDATE

thanks for the answer, Ryan... that pretty much did it! =) the problem with eval was that it is no good at catching the current scope... this way i can do stuff like

    (let ([a 1])
        (begin
            (defmethod add ((x integer?) (y integer?)) (+ x y a))
            (add 1 2)
    )

which would fail miserably with eval... this is just an academic example, but i think it is a good test for correctness.

  • 2
    Can you say more about the context -- how/why you need/want this? Because, I don't understand the benefit of a macro to do what `define` and `lambda` can already do at _compile_ time with static lists in your source. Whereas, if you want this to work on data at _run_ time, I'm not sure I see how to avoid `eval`. But maybe I need more coffee. – Greg Hendershott May 08 '13 at 14:34
  • well, I'm defining a sort of generic methods and I would like it to construct a body which itself would turn into a lambda at method creation with the supplied var names and body. the problem is, that to keep the syntax-rule sane, I'm avoiding to do to much on the macro and instead call a function that deals with constructing a method. Plainly, I'm defining a method like this: `(define-syntax defmethod (syntax-rules () [(defmethod name ((var predicate)...) body) (add-to-generic name var... predicate... body)) ]))` .The predicate is there to allow type checking. – Carlos Filipe Costa May 08 '13 at 14:45

1 Answers1

2

It's not possible to create a function where the formal parameters and body are given as run-time values (S-expressions) without using eval.

But based on your answer to Greg's comment, you can change your defmethod macro to avoid this issue. Your current approach takes the variables and body expression (program terms), converts them to run-time values, then wants to reinterpret them as program terms. Instead, you should just combine the program terms into a lambda-expression in the macro, which you can then pass as a value to the helper function:

(define-syntax-rule (defmethod name ((var predicate) ...) body)
  (add-to-generic name
                  (list predicate ...)
                  (lambda (var ...) body)))

If you wanted to keep the variable names around (eg for error messages), you can also quote them, but separate from the lambda-expression:

(define-syntax-rule (defmethod name ((var predicate) ...) body)
  (add-to-generic name
                  (list predicate ...)
                  '(var ...)                 ;; for errors, debugging, etc
                  (lambda (var ...) body)))
Ryan Culpepper
  • 10,495
  • 4
  • 31
  • 30