LINUX.ORG.RU

История изменений

Исправление q0tw4, (текущая версия) :

Ну короче я опять немного потыкал макросы сабжа. Выходит довольно мудреный код, потому что мне приходится из макроса вызывать функцию, которая заворачивает синтакс в структуру. Благополучно починил веселый баг «no #%datum syntax transformer is bound», догадавшись, что просто забываю прописать синтаксу биндингс, когда собираю его с помощью (datum->syntax #f <tratata>). Никогда раньше не задумывался о том, что синтакс это не только номер строки, а еще и биндинг. Скотина ракет не говорит ничего о том, что тут зашит какой-то биндинг, когда смотришь на синтакс в репле. Ну и выходят довольно интересные пляски, когда тебе надо и выполнять некие вычисления в компилтайме и использовать удобство шаблонов. Собственно вопрос на засыпку: как кошерно запустить на выполнение в компилтайме шаблон, собранный с помощью syntax-case. Упрощенный пример для мотивации:

#lang racket
(define-syntax (lt stx)
  (syntax-case stx ()
    [(_ ([var expr] ...) body)
     (datum->syntax stx
                    (eval #`(let ([var expr] ...)
                              #,(let ([t (if (symbol? (syntax-e #'body))
                                             (assoc #'body
                                                    (map syntax-e (syntax->list #'([var . expr] ...)))
                                                    free-identifier=?)
                                             #f)])
                                  (if t (cdr t) (car (syntax-e #'(var ...)))))))
                    stx)]))

> (lt ([a 1][x 2]) a)
1
> (lt ([a 1][x 2]) x)
2
> (lt ([a 1][x 2]) 5)
1

Мда, такой простой демо функционал и час плясок с бубном чтоб его поднять....

Исправление q0tw4, :

Ну короче я опять немного потыкал макросы сабжа. Выходит довольно мудреный код, потому что мне приходится из макроса вызывать функцию, которая заворачивает синтакс в структуру. Благополучно починил веселый баг «no #%datum syntax transformer is bound», догадавшись, что просто забываю прописать синтаксу биндингс, когда собираю его с помощью (datum->syntax #f <tratata>). Никогда раньше не задумывался о том, что синтакс это не только номер строки, а еще и биндинг. Скотина ракет не говорит ничего о том, что тут зашит какой-то биндинг, когда смотришь на синтакс в репле. Ну и выходят довольно интересные пляски, когда тебе надо и выполнять некие вычисления в компилтайме и использовать удобство шаблонов. Собственно вопрос на засыпку: как кошерно запустить на выполнение в компилтайме шаблон, собранный с помощью syntax-case. Упрощенный пример для мотивации:

#lang racket
(define-syntax (lt stx)
  (syntax-case stx ()
    [(_ ([var expr] ...) body)
     (datum->syntax stx
                    (eval #`(let ([var expr] ...)
                              #,(let ([t (if (symbol? (syntax-e #'body))
                                             (assoc #'body
                                                    (map syntax-e (syntax->list #'([var . expr] ...)))
                                                    free-identifier=?)
                                             #f)])
                                  (if t (cdr t)
                                      #'(let ([var expr] ...) (+ body 1))))))
                    stx)]))

> (lt ([x 1]) 44)
45
> (lt ([x 1]) x)
1

Мда, такой простой демо функционал и час плясок с бубном чтоб его поднять....

Исходная версия q0tw4, :

Ну короче я опять немного потыкал макросы сабжа. Выходит довольно мудреный код, потому что мне приходится из макроса вызывать функцию, которая заворачивает синтакс в структуру. Благополучно починил веселый баг «no #%datum syntax transformer is bound» догадавшись что просто забываю прописать синтаксу биндингс когда собираю его с помощью (datum->syntax #f <tratata>). Никогда раньше не задумывался о том, что синтакс это не только номер строки, а еще и биндинг. Скотина ракет не говорит ничего о том что тут зашит какой-то биндинг, когда смотришь на синтакс в репле. Ну и выходят довольно интересные пляски, когда тебе надо и выполнять некие вычисления в компилтайме и использовать удобство шаблонов. Собственно вопрос на засыпку: как кошерно запустить на выполнение в компилтайме шаблон, собранный с помощью syntax-case. Упрощенный пример для мотивации:

#lang racket
(define-syntax (lt stx)
  (syntax-case stx ()
    [(_ ([var expr] ...) body)
     (datum->syntax stx
                    (eval #`(let ([var expr] ...)
                              #,(let ([t (if (symbol? (syntax-e #'body))
                                             (assoc #'body
                                                    (map syntax-e (syntax->list #'([var . expr] ...)))
                                                    free-identifier=?)
                                             #f)])
                                  (if t (cdr t)
                                      #'(let ([var expr] ...) (+ body 1))))))
                    stx)]))

> (lt ([x 1]) 44)
45
> (lt ([x 1]) x)
1

Мда, такой простой демо функционал и час плясок с бубном чтоб его поднять....