2017-01-17 5 views
0

у меня есть:Как создать одно слово из аргументов макросов в Common Lisp?

(defmacro test (a b c) 
    `'(,a ,b ,c)) 

Запуск (test apple banana cuba) дает (APPLE BANANA CUBA), как ожидалось.

Как сделать макропроизводство APPLEBANANACUBA?

Я пробовал:

(defmacro test (a b c) 
     `'(,a,b,c)) 

но работает (test ant bites chris) все еще возвращает (ANT BITES CHRIS) в виде списка из трех отдельных аргументов.

Я пробовал варианты, и ни один из них не работает. Как это:

(defmacro test (a b c) 
    `(apply #'concatenate 'symbol '(,a ,b ,c))) 

Очевидно, что это ошибки вне, потому что «символ не является допустимым типом вывода для СЦЕПИТЬ.

Я уверен, что это является одним из основных недоразумений с моей стороны о том, как работают макросы, и есть простой способ сделать это. Что мне не хватает?

+0

@JoshuaTaylor Несмотря на то, другой вопрос включает в себя информацию, является ответом на этот вопрос, он встроен во многие другие сведения как в вопрос, так и в ответ. Вы можете поместить ссылку в комментарий к этому вопросу, говоря, что там есть «больше» информации, но называть два вопроса «одинаковыми» (это то, что означает дубликаты) является плохим сервисом для всех, кто может воспользоваться быстрым ясным решением в будущее. Достаточно, но, пожалуйста, передумайте. –

ответ

6

Объедините их в строку, а затем создайте символ из этой строки.

(defmacro test (a b c) 
    (intern (concatenate 'string a b c))) 

INTERN будет стажер строка в текущем пакете, вы можете также использовать MAKE-SYMBOL создать uninterned символ.

5

Путаница макросов и их реализация

Я уверен, что это какое-то основное недоразумение с моей стороны о том, как макросы работают

Да:

  • Макросы и создание «слов» - это полностью независимые ортогональные понятия.

  • Концепция «слова» не существует в Лиспе. Но есть символы, строки, цифры, ...

  • Если вы думаете о , значит, вы, вероятно, имеете в виду символ .

Решение проблемы

  1. сначала решить проблему как создать символ из списка символов
  2. реализации макро

Если вы хотите создать новый символ, который является конкатенацией символов, тогда вам необходимо:

  1. получить символы, взять их имена как строки
  2. создать строку, которая является конкатенацией этих имен
  3. создать символ из этой строки, возможно, в пакете.

операция Implode

Давайте назовем эту операцию Implode, который является историческое название для него:

(defun implode-symbols (symbols &optional (package *package*)) 
    (when symbols 
    (values 
    (intern (with-output-to-string (stream) 
       (dolist (symbol symbols) 
       (write-string (symbol-name symbol) stream))) 
      package)))) 


CL-USER 30 > (implode-symbols '(a - b - c - foo - bar)) 
A-B-C-FOO-BAR 

Теперь можно сделать более общий вариант, который может implode все вещи:

(defun implode (things) 
    (when things 
    (values 
    (intern (with-output-to-string (stream) 
       (dolist (thing things) 
       (princ thing stream))))))) 

CL-USER 31 > (implode '(a - b - c - foo :bar - 42 - "BAZ")) 
A-B-C-FOOBAR-42-BAZ 

Макрос взрывающиеся некоторые аргументы

Учитывая, что мы функция, которая создает символ из списка вещей, мы можем легко написать макрос:

CL-USER 37 > (defmacro test (a b c) 
       `',(implode (list a b c))) 
TEST 

CL-USER 38 > (macroexpand-1 '(test foo bar baz)) 
(QUOTE FOOBARBAZ) 
T 

CL-USER 39 > (test foo bar baz) 
FOOBARBAZ 

Атомы, взрывается и взрываются

Символы - это атомы. Это означает, что они не являются cons-ячейками, которые являются основным строительным блоком связанных списков.

Вы можете взорвать и взорвать атом, вот символ.

  • взрываются символы FOO и BAR ->FOOBAR
  • взрываются символ FOOBAR ->F, O, O, B, A, R
+0

Это отличное разъяснение. Благодарю. Что такое текст, который передается макросу? То есть, я могу позвонить (проверить foo bar baz), не указывая аргументы как «foo» bar 'baz.Однако, если тест был функцией, а не макросом, (test foo bar baz) будет искать переменные foo bar baz. Что происходит с макросом? Атом? Символ? Или что-то другое? Кажется, это просто текст ... –

+1

@ λ-: почему бы не попробовать? Задайте макрос, какие значения имеют значения A, B и C. DESCRIBE - ваш друг. Макросы Lisp не имеют ничего общего с * текстом *. Это все данные. –

 Смежные вопросы

  • Нет связанных вопросов^_^