Форум программистов, компьютерный форум, киберфорум
Lisp
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/8: Рейтинг темы: голосов - 8, средняя оценка - 4.88
defun
603 / 617 / 44
Регистрация: 30.04.2011
Сообщений: 702
1

Почему не работает макрос?

24.10.2011, 17:26. Показов 1636. Ответов 6
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
CL-USER> (setq list-user '((a b) (c d) num))
((A B) (C D) NUM)
CL-USER> (defmacro person (list-user &optional that)
       `(if (null ,that) ()
        (cond
          ((eq (quote ,that) 'name) (caar ,list-user))
          ((eq (quote ,that) 'username) (second (car ,list-user)))
          ((eq (quote ,that) 'mother) (car (second ,list-user)))
          ((eq (quote ,that) 'father) (second (second ,list-user)))
          ((eq (quote ,that) 'age) (third ,list-user))
          (t ()))))
PERSON
CL-USER> (macroexpand '(person list-user name))
(IF (NULL NAME) NIL
    (COND ((EQ 'NAME 'NAME) (CAAR LIST-USER))
          ((EQ 'NAME 'USERNAME) (SECOND (CAR LIST-USER)))
          ((EQ 'NAME 'MOTHER) (CAR (SECOND LIST-USER)))
          ((EQ 'NAME 'FATHER) (SECOND (SECOND LIST-USER)))
          ((EQ 'NAME 'AGE) (THIRD LIST-USER)) (T NIL)))
T
CL-USER> (person list-user name)
; Evaluation aborted.
CL-USER>

если переписать эти части - (quote ,that) и делать запрос как обычно - (person list-user 'name)
то работает, но мне интересно без апострофа
как сделать?
1
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.10.2011, 17:26
Ответы с готовыми решениями:

Почему макрос работает не на всех компьютерах??
Здравствуйте, товарищи программисты!Требуется Ваша помощь, ибо надежды в своих силах уже нет(...

Почему не работает макрос изменения шрифта в не выделенном тексте
Нужно создать макрос изменения шрифта на синий полужирный для текущего абзаца, за исключением...

Почему макрос работает, если создавать и запускать его в Командной строке, а если в пакетном файле, то нет?
Подскажите почему если вводить последовательно в командной строке DOSKEY npp="C:\Program...

Макрос делает копию листа и сохраняет в новую книгу, но макрос в новой не работает
Есть макрос в книге. Он копирует текущий лист, создает новую книгу и копирует в новую книгу лист. ...

6
Эксперт С++
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
24.10.2011, 18:03 2
Потому что в тестовой форме if'а name не зацитачивается. В остальном-то, в принципе, у тебя все правильно было. Так работает:
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
(defmacro person (list &optional what)
  `(if (quote ,what)
       (cond ((eq (quote ,what) 'name)
          (caar ,list))
         ((eq (quote ,what) 'username)
          (cadar ,list))
         ((eq (quote ,what) 'mother)
          (caadr ,list))
         ((eq (quote ,what) 'father)
          (cadadr ,list))
         ((eq (quote ,what) 'age)
          (caddr ,list)))))
Lisp
1
2
3
4
5
6
7
8
9
10
CL-USER> (person '((a b) (c d) e))
NIL
CL-USER> (person '((a b) (c d) e) name)
A
CL-USER> (person '((a b) (c d) e) father)
D
CL-USER> (person '((a b) (c d) e) age)
E
CL-USER> (person '((a b) (c d) e) address)
NIL
0
defun
603 / 617 / 44
Регистрация: 30.04.2011
Сообщений: 702
24.10.2011, 18:13  [ТС] 3
Цитата Сообщение от Nameless One Посмотреть сообщение
... name не зацитачивается.
почему?
0
Эксперт С++
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
24.10.2011, 18:24 4
Цитата Сообщение от transformator.t Посмотреть сообщение
`(if (null ,that) ()
потому (см. пример):
Lisp
1
2
(defmacro test (name)
  `(if ,name nil))
Т.к. перед name стоит comma, то ее значение при разворачивании макроса будет вычисляться. Пример:
Lisp
1
2
3
4
CL-USER> (macroexpand '(test non-quoted))
(IF NON-QUOTED
    NIL)
T
При таком раскрытии макроса non-quoted неизвестна, получается ошибка. Если же сделать так:
Lisp
1
2
(defmacro test (name)
  `(if (quote ,name) nil))
то все будет в порядке:
Lisp
1
2
3
4
CL-USER> (macroexpand '(test non-quoted))
(IF 'NON-QUOTED
    NIL)
T
Короче, ты зацитачил параметр макроса name везде (строки 6-10), кроме тестовой формы if (строка 4), поэтому возникала ошибка
0
defun
603 / 617 / 44
Регистрация: 30.04.2011
Сообщений: 702
24.10.2011, 20:18  [ТС] 5
ну да, разобрался, благодарю)

Добавлено через 24 минуты
Nameless One,
Lisp
1
2
(setq var 100)
(setq bar 'pivo)
кстати, как получить имя переменной, ну типа я хочу написать
Lisp
1
2
3
4
5
CL-USER> (bind var) 
"значение var - 100"
 
CL-USER> (bind bar) 
"значение bar - PIVO"
может я уже слишком туплю? но чтот не пойму.

Добавлено через 47 минут
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CL-USER> (setq test '(+ 0 0))
(+ 0 0)
 
CL-USER> (defmacro print-bind (var value)
       `(progn
          (if (quote ,var) (format t "Значение: ~S" ,var) (format () "Значение - не связан"))
          (terpri)
          (setq ,var (eval ,value))
          (format t "Новое значение: ~S" ,var)))
 
CL-USER> (print-bind test '(list '+ 20 30))
Значение: (+ 2 3)
Новое значение: (+ 20 30)
NIL
 
CL-USER> test
(+ 20 30)
вот об этом я говорил, как получить имя переменной?

ещё вопросы -
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CL-USER> (list * 30 20)
(NIL 30 20)
 
CL-USER> (list * 30 20)
((NIL 30 20) 30 20)
 
CL-USER> (list * 30 20)
(((NIL 30 20) 30 20) 30 20)
 
CL-USER> (list * 30 20)
((((NIL 30 20) 30 20) 30 20) 30 20)
 
CL-USER> (list * 30 20)
(((((NIL 30 20) 30 20) 30 20) 30 20) 30 20)
 
CL-USER> (list * 30 20)
((((((NIL 30 20) 30 20) 30 20) 30 20) 30 20) 30 20)
как это понимать? почему я не могу сделать (trace list) в sbcl?

Добавлено через 25 минут
там в 7-ой строке надо заменить (quote ,var) на (boundp (quote ,var))
но почему в if не срабатывает else, когда
Lisp
1
2
CL-USER> (boundp 'miss)
NIL
Lisp
1
2
3
4
CL-USER> (print-bind miss '(list '+ 20 30))
Новое значение: (+ 20 30)
NIL
CL-USER>
0
Эксперт С++
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
25.10.2011, 04:39 6
Цитата Сообщение от transformator.t Посмотреть сообщение
вот об этом я говорил, как получить имя переменной?
передавай функции format не ,var, а (quote ,var)
Цитата Сообщение от transformator.t Посмотреть сообщение
как это понимать? почему я не могу сделать (trace list) в sbcl?
http://www.lispworks.com/docum... _stst_.htm
Цитата Сообщение от transformator.t Посмотреть сообщение
но почему в if не срабатывает else, когда
Видать, что-то со скобками напутал, так все работает:
Lisp
1
2
3
4
5
6
(defmacro print-bind (var &optional (val nil val-supplied-p))
  `(if ,val-supplied-p
       (format t "New value of ~S is ~S~%" (quote ,var) (setq ,var (eval ,val)))
       (if (boundp (quote ,var))
       (format t "Value of ~S is ~S~%" (quote ,var) ,var)
       (format t "~S is unbound ~%" (quote ,var)))))
1
defun
603 / 617 / 44
Регистрация: 30.04.2011
Сообщений: 702
25.10.2011, 12:25  [ТС] 7
ок. с этим разобрался)
0
25.10.2011, 12:25
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.10.2011, 12:25
Помогаю со студенческими работами здесь

Макрос не работает с полным диапазоном текста, работает только до 99 ячейки
Добрый вечер. Вот есть макрос. Он должен брать из диапазона в столбце А данные (их дофига и...

Макрос работает, а код, преобразованный из макроса - не работает
Здравствуйте! Подскажите пожалуйста, почему функция выдаёт ошибку "32538: в TempVar можно хранить...

Почему макрос отрабатывается невзирая на значение чекбокса?
Загадочным образом вдруг макрос перестал реагировать на состояние чекбокса. Буквально несколько...

Почему макрос TRACE не может вывести строку?
Почему макрос TRACE не может вывести строку? Вылетает неопознаная ошибка. CString sss("<H2...

Почему новый макрос вставляется рядом со старым?
Создаю новый макрос в Excel ('Сервис/Макрос/Начать запись'). Затем захожу в него...

Почему кода я добавляю макрос выдает ошибку
Почему кода я добавляю макрос выдает ошибку команда или макрокоманда ""ЗаписьНовая"в данное время...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru