Jeffrey Meunier ha un Curry implicita macro here, che utilizza defmacro. Mi stavo chiedendo se qualcuno lo abbia mai scritto con le regole della sintassi?Corrispondenza implicita in Schema con regole di sintassi?
risposta
Esistono numerose implementazioni di curry per Scheme: nessuna può essere elegante come Haskell, poiché le funzioni sono sempre funzioni unarie, quindi tutto può essere curato. (Ma questo può naturalmente essere implementato in uno schema sufficientemente potente come Racket.)
Come per la macro che hai scavato - è piuttosto brutto: non solo usa una macro non igienica, è anche chiamando eval
esplicitamente, e si basa su un'implementazione di ambienti ecc ma è facile farlo con un semplice syntax-rules
macro. AFAICT, questo è ciò che implementa:
(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)))))))
Ma c'è una nota importante qui. La pagina di riferimento indica che un problema della versione della funzione è esplicito, ma ha anche un vantaggio importante: con l'implementazione della macro è necessario definire una funzione utilizzando clambda
, mentre la versione funzionale può essere utilizzata con qualsiasi versione integrata funzione. In molte implementazioni di Scheme ci sono strutture per ispezionare l'aritmetica di una funzione, e usando questo è possibile implementare una versione di funzione currying che sa quando chiamare la funzione originale.