Я изучаю макросистему на Схеме, и я думал, что реализация карри-функций станет хорошим началом. Это то, что я приготовил:Функции currying в схеме с использованием макросов
(define-syntax function
(syntax-rules()
((_() body ...) (lambda() body ...))
((_ (param) body ...) (lambda (param) body ...))
((_ (param_1 param_2 params ...) body ...) (lambda (param_1 . rest)
(let ((k (function (param_2 params ...) body ...)))
(if (null? rest) k (apply k rest)))))
((_ name params body ...) (define name (function params body ...)))))
Этот код работает, как ожидалось. Например, я могу определить add
функцию следующим образом:
(function add (x y) (+ x y))
Тогда я могу назвать это нормально:
(add 2 3) ; => 5
Кроме того, я могу легко частично применить его:
(map (add 10) '(2 3 5 7)) ; => (12 13 15 17)
Теперь я Предполагая, что функции с параметрами отдыха будут заправлены. Поэтому я добавил новое правило синтаксиса:
((_ (param . params) body ...) (lambda (param . params) body ...))
К сожалению, когда я пытаюсь создать функцию, используя это правило дает мне ошибку:
(function add (x . y) (apply + `(,x ,@y)))
Это сообщение об ошибке:
Error: invalid syntax in macro form: (x . y)
Call history:
<eval> (##sys#= len7 0)
<eval> (loop11 (##sys#cdr l6) (##sys#+ len7 -1))
<eval> (##sys#cdr l6)
<eval> (##sys#+ len7 -1)
<eval> (##sys#= len7 0)
<eval> (loop11 (##sys#cdr l6) (##sys#+ len7 -1))
<eval> (##sys#cdr l6)
<eval> (##sys#+ len7 -1)
<eval> (##sys#= len7 0)
<eval> (##sys#eq? l6 (quote()))
<eval> (##sys#car tail15)
<eval> (##sys#cdr tail15)
<eval> (##sys#cons (rename14 (##core#syntax lambda)) (##sys#cons param body))
<eval> (rename14 (##core#syntax lambda))
<eval> (##sys#cons param body)
<syntax> (##core#lambda add (x . y) (apply + (quasiquote ((unquote x) (unquote-splicing y))))) <-
Что я делаю неправильно?
Это ** не ** создание _curried_ функций; он создает _partially прикладные_ функции. С помощью '(define (fxyz) (+ x (* yz))) (define g (curry f 1))', '((g 2) 3)' должен возвращать 7. Но вы должны называть '((curry g 2) 3) 'для этого.Принимая во внимание, что код OP, после '(функция g (xyz) (+ x (* yz)))', '(g 1 2 3)' == '((g 1 2) 3)' == '(((g 1) 2) 3) '== 7. –