Jeffrey Meunier has an implicit Curry macro here, which uses defmacro. I was wondering if someone has ever written this with syntax-rules?
问题:
回答1:
There are a number of curry implementations for Scheme -- none can be as elegant as Haskell, since there functions are always unary functions, so everything can be curried. (But this can of course be implemented in a sufficiently powerful Scheme like Racket.)
As for the macro that you've dug up -- it's a pretty bad one: not only does it use an unhygienic macro, it's also calling eval
explicitly, and relies on an implementation of environments etc. But it's easy to do that with a simple syntax-rules
macro. AFAICT, this is what it implements:
(define-syntax-rule (clambda (x ... . r) b ...)
(let ([len (length '(x ...))] [real (lambda (x ... . r) b ...)])
(let loop ([argss '()] [n 0])
(lambda args
(let ([n (+ n (length args))] [argss (cons args argss)])
(if (>= n len)
(apply real (apply append (reverse argss)))
(loop argss n)))))))
But there's an important note here. The page that you reference says that an problem of the function version is that it's explicit -- but it also has an important advantage: with the macro implementation you must define a function using clambda
, whereas the functional version can be used with any built in function. In many Scheme implementations there are facilities to inspect a function's arity, and using this it's possible to implement a currying function version that knows when to call the original function.