Поиск:

Ответ в темуСоздание новой темы Создание опроса
> глобальные переменные в макросах 
V
    Опции темы
kosmonaFFFt
Дата 16.8.2010, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 538
Регистрация: 14.4.2008
Где: Иннополис

Репутация: нет
Всего: 5



Доброго времени суток... Столкнулся с проблемой при использовании в макросе глобальной переменной:

Код

(defparameter *defined-generic-getters* (make-array 0 :fill-pointer 0 :adjustable T))

...

(defmacro ...
      (let* ((defgeneric-getters (remove-if #'null
                                          (loop
                                             for slot in slots-list
                                             collect (unless (find slot *defined-generic-getters*)
                                                       (vector-push-extend slot *defined-generic-getters*)
                                                       `(defgeneric ,slot (self))))))
...


делаю так, чтобы не генерировать макросом одинаковых generic'ов...
Проблема в том, что данный код компилируется только после повторного объявления в REPL переменной *defined-generic-getters*,
а при попытки загрузки модуля через ASDF или простой загрузки файла, выдается что переменная *defined-generic-getters* не объявлена...

Можно ли как-либо с этим бороться, и если да, то как?
Заранее спасибо...


--------------------
user posted image
PM MAIL ICQ   Вверх
k0rvin
Дата 17.8.2010, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 24.1.2010

Репутация: нет
Всего: 5



сейчас времени нет подробней разбираться, но можно объявлять глобальную переменную в теле макры, типа

Код

(defmacro ...
  (defvar *var* ...)
  (let* ...))

defvar объявляет переменную в глобальном окружении, независимо от того в каком окружении вызван + не пересвязывает ее в случае повторного объявления


--------------------
“Object-oriented design is the roman numerals of computing.” — Rob Pike
All software sucks
PM MAIL   Вверх
k0rvin
Дата 17.8.2010, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 24.1.2010

Репутация: нет
Всего: 5



вообще должно работать нормально. какой компилятор ты юзаешь?



Это сообщение отредактировал(а) k0rvin - 17.8.2010, 20:51


--------------------
“Object-oriented design is the roman numerals of computing.” — Rob Pike
All software sucks
PM MAIL   Вверх
kosmonaFFFt
Дата 18.8.2010, 18:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 538
Регистрация: 14.4.2008
Где: Иннополис

Репутация: нет
Всего: 5



SBCL под виндой и линуксом, и там и там поведение одинаковое...
Попробую в теле макроса объявить, отпишусь чего получится...


--------------------
user posted image
PM MAIL ICQ   Вверх
k0rvin
Дата 18.8.2010, 19:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 24.1.2010

Репутация: нет
Всего: 5



а если такой тестовый код скомпилить:

Код

(defparameter *x* "x")

(defmacro foo ()
  (print *x*))

(foo)

?

просто уж больно похоже, что у тебя в теле макры опечатка в имени переменной, но судя по приведённому тобой коду, опечатки нет =/


--------------------
“Object-oriented design is the roman numerals of computing.” — Rob Pike
All software sucks
PM MAIL   Вверх
adejneka
Дата 18.8.2010, 21:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 105
Регистрация: 8.7.2005
Где: Москва, Россия

Репутация: 9
Всего: 11



Выдает ошибку
Цитата
; caught ERROR:
;   (during macroexpansion of (FOO))
;   The variable *X* is unbound.

Под SBCL работает такой вариант:
Код

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defvar *x* "x"))

(defmacro foo ()
  (print *x*))

(foo)

Правда, я не уверен, что он будет работать под Allegro CL.
PM MAIL   Вверх
k0rvin
Дата 19.8.2010, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 24.1.2010

Репутация: нет
Всего: 5



Цитата(adejneka @ 18.8.2010,  21:53)
Выдает ошибку
Цитата
; caught ERROR:
;   (during macroexpansion of (FOO))
;   The variable *X* is unbound.

Под SBCL работает такой вариант:
Код

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defvar *x* "x"))

(defmacro foo ()
  (print *x*))

(foo)

Правда, я не уверен, что он будет работать под Allegro CL.

действительно, если выполнить (load "file.lisp"), то ошибки не будет, а при (load (compile-file "file.lisp")) она появляется. причину можно увидеть так:
Код

CL-USER> (pprint (macroexpand '(defvar *x* 0)))

(PROGN
 (EVAL-WHEN (:COMPILE-TOPLEVEL) (SB-IMPL::%COMPILER-DEFVAR '*X*))
 (EVAL-WHEN (:LOAD-TOPLEVEL :EXECUTE)
   (SB-IMPL::%DEFVAR '*X* (UNLESS (BOUNDP '*X*) 0) 'T NIL 'NIL
                     (SB-C:SOURCE-LOCATION))))
; No value
CL-USER> 


Цитата

Под SBCL работает такой вариант:
Код

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defvar *x* "x"))

(defmacro foo ()
  (print *x*))

(foo)

Правда, я не уверен, что он будет работать под Allegro CL.

скорее всего будет, но можно сделать и так:
Код

#.(defvar ...)
...

тогда переменная будет определена во время чтения до раскрытия макр времени компиляции


--------------------
“Object-oriented design is the roman numerals of computing.” — Rob Pike
All software sucks
PM MAIL   Вверх
kosmonaFFFt
Дата 19.8.2010, 18:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 538
Регистрация: 14.4.2008
Где: Иннополис

Репутация: нет
Всего: 5



Спасибо за evel-when, мне кроме как под sbcl не надо... )


--------------------
user posted image
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума LISP
Void
  • Пожалуйста, создавайте темы с содержательными названиями.
  • Lisp — это целое семейство языков. Всегда указывайте в теме используемый диалект (Common Lisp, Scheme и т.д.).
  • Уважаемые учащиеся, здесь всегда рады помочь Вам, но не делать за Вас вашу работу. У вас гораздо больше шансов получить помощь, если Вы приложите усилия и поделитесь с нами проблемами и результатами. В противном случае добро пожаловать в раздел Центр Помощи.
  • Получив ответ на интересующий Вас вопрос, не забудьте пометить его как решённый.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Void.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | LISP | Следующая тема »


 




[ Время генерации скрипта: 0.1047 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.