Как сопоставить макрос со списком - или - Как использовать макросы для определения типов данных

Мне нравится создавать REPL с моими собственными типами данных, но я не люблю писать одни и те же шаблонные функции снова и снова.

Так что это орех, который беспокоит меня.

У меня есть собственный набор примитивных типов данных (define primitives '("mytrue" "myfalse" "mynumber" ...))

Также у меня есть (define primitiveTesters (list "mytrue?" "myfalse?" "mynumber?" ... )

Теперь проблема в том, что я просто хочу применить (карту) или макрос, чтобы получить тип данных? процедуры, которые в основном просто проверяют, существует ли автомобиль записи (mynumber . ( . )).

Так что что-то похожее на (mynumber? (car (mynumber.(1.))) => #t в конце. Но для этого мне нужно (define mynumber? (lambda (...)(...))

Мой макрос для пакетной обработки выглядит так, но мне просто не повезло добавить <variable>.

(define-syntax define-batching
(syntax-rules () 
((_ value expr)(define value expr))
((_ value) value)
((_ value1 value2 ...)  (begin (define value1 expr) (define-batching test2...)))
))

Так я зашел в тупик схемы?

Я видел нечто подобное, кажется, в Emacs Lisp.

В итоге я ищу:

 (define checker '(audi? volkswagen? mercedes?))
 (define datatype '(audi volkswagen mercedes))

 (map define-checker checker datatype )
 or
 (define-checker (car checker) (car datatype))

person Georg Summer    schedule 23.05.2012    source источник
comment
Что касается (типа данных map define-checker checker ), вы не можете сопоставлять макросы со списком. В (define-checker (car checker) (car datatype)) предполагая, что define-checker является макросом, расширение происходит во время компиляции, поэтому средство проверки еще не имеет значения. Это происходит во время во время выполнения. Если вам нужно иметь значения списка во время компиляции (в отличие от синтаксических объектов, вам нужно взглянуть на более продвинутые системы макросов. Но см. Приложение к моему ответу ниже.   -  person soegaard    schedule 24.05.2012


Ответы (2)


Если я правильно понял вопрос, вам нужен макрос для определения собственных средств проверки типов?

Вот один из способов сделать это:

(define-syntax define-checker
  (syntax-rules ()
    [(define-checker name tag)
     (define (name object)
       (and (list? object)
            (not (null? object))
            (eq? (car object) 'tag)))]))

(define-checker my-car? car)

(my-car? '(car audi black))   ; evaluates to #t
(my-car? '(truck ford pink))  ; evaluates to #f

Приложение:

Если вы пишете

(define checker '(audi? volkswagen? mercedes?))
(define datatype '(audi volkswagen mercedes))

значения станут доступны во время выполнения. Поэтому вам нужен другой подход.

Вы могли бы, например, написать:

(define-checker+datatype (audi? audi) (volkswagen? volkswagen?))

Вот код:

(define-syntax define-checker
  (syntax-rules ()
    [(define-checker name tag)
     (define (name object)
       (and (list? object)
            (not (null? object))
            (eq? (car object) 'tag)))]))


(define-syntax define-checkers+datatype
  (syntax-rules ()
    [(define-checkers+datatype (name tag) ...)
     (begin
       (define-checker name tag)
       ...)]))

(define-checkers+datatype (audi? audi) (wv? wv))


(audi? '(audi black))
person soegaard    schedule 24.05.2012
comment
Хорошо, я вижу. Отличный вариант вы предлагаете. Большое спасибо за поддержку. - person Georg Summer; 24.05.2012

define-syntax является гигиеничным, т. е. не может влиять на родительскую среду, т. е. не может определять в ней символы. Вы можете попробовать использовать макропреобразователи er-, ir-, которые позволяют явно переименовывать символы.

ключевые слова для Google в документации по вашей схеме: «er-macro-transformet» и «ir-macro-transformet».

person paul    schedule 24.05.2012
comment
Относительно syntax-rules; нет ничего плохого в define внутри макроса, особенно в этом случае идентификатор value передается пользователем, поэтому определение будет видно. - person leppie; 24.05.2012
comment
syntax-rules гигиеничен, но syntax-case преобразователь может создавать негигиеничные макросы. Вы можете ввести новые символы, чтобы нарушить гигиену с помощью datum->syntax . - person FooBee; 25.05.2012