Создать новый идентификатор с помощью макросов

Мне нужен макрос, который создает новый идентификатор, например

(new-name first second) => first-second

которые можно использовать для определения новых привязок верхнего уровня.

(define-syntax define-generic 
  (syntax-rules ()
    ((define-generic (name a b ...))
     (begin
       (define (new-name name data) 15)      ; <= create a new binding
       (define name (lambda (a b ...)
         (add (new-name name-data) 7))))))   ; <= use new identifier

Если я поставлю! значение привязки «новое имя», то оно должно повлиять на вновь созданную процедуру.


person knivil    schedule 28.01.2011    source источник
comment
Что ты пытаешься сделать? Вероятно, есть лучший способ сделать это.   -  person Chris Jester-Young    schedule 28.01.2011
comment
Трудно описать: я работаю по схеме курицы и реализовал oop-систему, похожую на coops (только проще). Процедуры могут быть украшены дополнительными данными (extend-procedure). Я хочу эмулировать это в Gambit-C, создав новую привязку name-data (где name — это имя процедуры) с помощью define. Если пользователь создает новую общую процедуру, то должны быть определены две новые привязки в соответствии с заданным именем: новая процедура и привязка процедура-данные.   -  person knivil    schedule 29.01.2011


Ответы (2)


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

(define-macro (new-name a b) (string->symbol (string-append (symbol->string a) "-" (symbol->string b))))

person SK-logic    schedule 28.01.2011
comment
-1 за правильный макрос системный тролль. Негигиеничные макросы очень проблематичны, и тем более для Scheme, потому что Scheme — это Lisp-1 без пакетов символов, в отличие от Common Lisp. - person Chris Jester-Young; 28.01.2011
comment
Это старая священная война. Я лично НЕНАВИЖУ гигиенические макросы. Они ограничивают. Они глупы. Я могу легко внедрить гигиеническую систему поверх ПРАВИЛЬНОЙ (да ладно, дайте еще -1), фундаментальной макросистемы, но вы не можете внедрить фундаментальную систему поверх гигиенической. См. пример того, что возможно при правильной системе макросов, здесь: meta-alternative.net/mbase. html - person SK-logic; 29.01.2011
comment
Я пробовал это в Gambit-C, но (define (new-name a b) 5) не работает (в разных вариантах). - person knivil; 29.01.2011
comment
@knivil, он не будет работать с define, let, let*, letrec и т. д. - только там, где ожидается выражение. Вам нужно определить макрос преобразователя, чтобы заставить его работать. Это поможет, если вы подробнее расскажете, зачем вам такая вещь. - person SK-logic; 29.01.2011
comment
Вы читали эту статью? okmij.org/ftp/Scheme/define-struct.html Это может быть уродливо, но я думаю, вы также можете быть удивлены некоторыми вещами, которые вы можете делать с помощью гигиенических макросов... - person all-too-human; 02.02.2011
comment
@ all-too-human, конечно, вы можете многое сделать с помощью макросов Scheme, этот язык является полным по Тьюрингу (как и язык шаблонов C ++), но проблема в том, что сама Scheme недоступна из этого языка. Это означает - никакого ввода-вывода, никаких манипуляций со строками и символами, никакого отражения, никакого доступа к окружению. Это просто слепой внешний препроцессор, не связанный с реальным кодом, который он преобразует. - person SK-logic; 02.02.2011

Несколько дней назад на Reddit была дискуссия по этому поводу. Возможно, стоит изучить опубликованную реализацию для получения более подробной информации - http://www.reddit.com/r/scheme/comments/f54dk/i_wrote_an_hygienic_definemacro_that_can_capture/

person Sid Heroor    schedule 28.01.2011