Вот простой макрос destructuring-bind
для схем с case-lambda
(например, Racket или Chez Scheme):
(define-syntax bind
(syntax-rules ()
((_ arg pat def body)
(apply
(case-lambda
[pat body]
[x def] )
arg ))))
Вот пример, который побудил меня написать этот макрос.Установка значения по умолчанию перед тем, как тело делает для читаемого кода:
(define (permutations l)
;
(define (psub j k y)
;
(define (join a b)
(bind a (ah . at) b
(join at (cons ah b)) ))
;
(define (prec a b z)
(bind b (bh . bt) z
(prec (cons bh a) bt
(psub (cons bh j) (join a bt) z) )))
;
(if (null? k)
(cons (reverse j) y)
(prec (list) k y) ))
;
(psub (list) (reverse l) (list)) )
Вот тесты для вычисления перестановок длины 9 на различных схемах:
0m0.211s Chez Scheme
0m0.273s Bigloo
0m0.403s Chicken
0m0.598s Racket
Перевод в GHC Haskell - 5xбыстрее чем Chez Scheme.Guile намного медленнее, чем любая из этих схем.
Помимо простоты использования существующего кода case-lambda
, мне нравится, как этот макрос принимает тот же синтаксис, что и списки аргументов определения функции.Я люблю простоту схемы.Я достаточно взрослый, чтобы помнить программирование Фортрана на перфокартах, где допустимый синтаксис сильно различался в зависимости от контекста.Схема должна быть лучше, чем это.Стремление подавить лилию на макросах, подобных этому, огромно.Если вы не можете оправдать изменение синтаксиса для определений функций, то не меняйте здесь и этот синтаксис.Важно иметь ортогональную грамматику.