LINUX.ORG.RU

Где можно почитать больше про CK-макросы на syntax-rules?

 , ,


1

2

В теоретической информатике есть такая штука как CK-автомат. Помимо написания заумных статей, у него есть и более приземлённое предназначение. Он позволяет записывать call-by-value макросы в Scheme.

Вот, собственно, он:

(define-syntax $
  (syntax-rules (quote)
    (($ e) ($ () e))
    (($ () 'v) v)
    (($ (((! ...) a ...) . s) 'v) ($ s #f (! ... 'v) a ...))
    (($ s #f (! va ...))          (! s va ...))
    (($ s #f (! ...) 'v a ...)    ($ s #f (! ... 'v) a ...))
    (($ s #f (! ...) a aa ...)    ($ (((! ...) aa ...) . s) a))
    (($ s (! a ...))              ($ s #f (!) a ...)) ) )
Вот так пишутся простейшие функции:
(define-syntax $cons
  (syntax-rules (quote)
    ((_ s 'a 'd) ($ s '(a . d)))) )

(define-syntax $map
  (syntax-rules (quote)
    ((_ s 'f '() ...)      ($ s '()))
    ((_ s 'f '(a . d) ...) ($ s ($cons (f 'a ...) ($map 'f 'd ...)))) ) )

(define-syntax $filter
  (syntax-rules (quote)
    ((_ s 'p '())      ($ s '()))
    ((_ s 'p '(a . d)) (p a ($ s ($cons 'a ($filter 'p 'd)))
                            ($ s           ($filter 'p 'd)) )) ) )

(define-syntax $quote
  (syntax-rules (quote)
    ((_ s 'x) ($ s ''x)) ) )
(Я ещё не придумал, как написать нормальный if.) CPS-предикаты для $filter:
(define-syntax ?bool
  (syntax-rules ()
    ((_ #f t f) t)
    ((_ #t t f) t)
    ((_ :: t f) f) ) )

(define-syntax ?symbol
  (syntax-rules ()
    ((_  (a . d) t f) f)
    ((_ #(x ...) t f) f)
    ((_ a-symbol t f)
     (let-syntax
         ((? (syntax-rules ()
               ((_ a-symbol tt ff) tt)
               ((_ else     tt ff) ff) )))
       (? ! t f) )) ) )
И можно делать вот такое:
($ ($quote
     ($map '$cons
       ($filter '?symbol '(a b 1 2))
       ($filter '?bool   '(3 #t #f 4)) ) ))  ===>  '((a . #t) (b . #f))
Так вот, можно ли где-то почитать про практический аспект применения данного макроса? Или это тайные знания Олега Киселёва?

★★★

Последнее исправление: ilammy (всего исправлений: 1)

Практический аспект простой — вычисления во время компиляции.

Хотя, imho, проще что-то вроде:

(define-syntax (immediate stx)
  (syntax-case stx ()
    [(_ cmd) #`(quote #,(eval #'cmd))]))

(immediate (map cons 
                (filter symbol? '(a b 1 2)) 
                (filter boolean? '(3 #t #f 4))))

monk ★★★★★
()
Ответ на: комментарий от monk

Да я понял, зачем оно. Мне бы какую-то библиотеку готовых функций, разбор их и т. п. Не хочу изобретать колесо.

syntax-case нет в R7RS-small, так что мне по религиозным причинам его нельзя; каким бы соблазнительным он ни был.

ilammy ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.