2015-06-02 3 views
0

Я хочу создать перегруженный макрос схемы для простой формы полиморфизма. То есть, макрос достаточно умный, чтобы расширяться по-разному при заданных параметрах разных типов, так что (контейнер для поиска ключей) делает «правильную» вещь для разных видов контейнеров.Scheme define-macro и/или define-syntax

(define-macro (look-up key container) 
    (cond 
    ((table? container) `(table-ref ,key ,container)) 
    ((pair? container) `(assoc ,container ,key)) 
     etc. 
    (else `(error "Unknown type to look-up)))) 

Идеи?

ответ

0

Я думаю, что Крис прав в том, что это не работа для макросов. Простая процедура может быть то, что вы ищете:

(define (lookup key container) 
    (cond ((type1? container) 
      (type1-lookup key container)) 
     .         ; repeat for whichever types.. 
     . 
     ((typeN? container) 
      (typeN-lookup key container)) 
     (else 'undefined-lookup)))   ; or default value or ... 

Или, может быть, вам нужно только, чтобы узнать, что вы имеете дело с когда-то, так что вы можете построить построить более специализированную процедуру на лету. Ваша make-lookup процедура может выглядеть очень похож на приведенный выше код, за исключением того, что вы вернетесь процедуру, а не вызывать поиск сразу:

(define (make-lookup container) 
    (cond ((type1? container) 
      type1-lookup) 
     .         ; repeat for supported types.. 
     . 
     ((typeN? container) 
      typeN-lookup) 
     (else default-lookup-procedure))) 

(define lookup (make-lookup container)) 

Можно даже добавить дополнительный аргумент make-lookup, что бы процедуру и использовать это, а не один из типов, которые вы определили ранее.

+0

спасибо. Мой план состоял в том, чтобы исключить тестирование типа контейнера во время выполнения для повышения производительности; эти процедуры будут называться много раз. Я пытался создать разрешение типа контейнера во время компиляции, но теперь я понимаю о времени макрорасширения и времени компиляции. Ваши предложения указали мне в гораздо лучшем направлении. Еще раз спасибо. – Brengle

+0

@Brengle - проблем нет. Как вы получаете эти данные? Является ли это случайным ассортиментом различных структур или более похожими на наборы одного типа? – oobivat

+0

он больше похож на большие наборы одного типа; много записей из нескольких таблиц SQL. – Brengle

2

Макросы - это время компиляции, а не время выполнения. Таким образом, вы не сможете запросить, является ли container таблицей или парой, а также отсутствием времени макрорасширения. Вам нужно будет использовать процедуру для этого.

Итак, почему бы не просто использовать процедуру?