LINUX.ORG.RU

[Common Lisp] Объявление глобальной переменной внутри макроса

 


0

0

Ковыряю кейбиндинги в StumpWM - возникла надобность в создании глобальных переменных внутри макроса. Имена глобальных переменных - генерируются из некоторых данных, но defvar и defparameter не хотят работать с символами вроде #:|symbol| и #:G12345, что генерятся gensym'ом и make-symbol'ом. Кто сталкивался - помогите пжлста.

А код где?

И можно use-case, где это понадобилось?

Sectoid ★★★★★
()

Фраза «глобальная переменная внутри макроса» не имеет значения. Уточните, что имеется в виду.

dmitry_vk ★★★
()
Ответ на: комментарий от zahardzhan

> Нифига. РЕПЛу не нравится.

Что за REPL? У меня всё хорошо работает. Я так в restas в нескольких местах делаю и всё работает.

archimag ★★★
()
Ответ на: комментарий от zahardzhan

>Нифига. РЕПЛу не нравится.

РЕПЛу все нравится. Просто второй раз ввести символ, полученный из gensym, невозможно - в этом и есть смысл gensym'а (и вообще символов, не находящихся в пакетах).

dmitry_vk ★★★
()
Ответ на: комментарий от zahardzhan

STUMPWM> (eval `(defparameter ,(gensym) 'value)) #:G914 STUMPWM> #:G914 The variable #:G914 is unbound.

Ты обращаешься не к тому символу, который объявляешь динамической переменной. То, что у них одинаковые имена еще не означает, что это одинаковые объекты. (gensym) возвравщает неинтернированный символ. А чтобы обратится к нему по имени тебе нужно засунуть его в какой-то пакадж.

Sectoid ★★★★★
()
Ответ на: комментарий от Sectoid

Лисп - SBCL.

А чтобы обратится к нему по имени тебе нужно засунуть его в какой-то пакадж.

Можно пример кода засовывания генсимов в пакадж?

zahardzhan
() автор топика
Ответ на: комментарий от zahardzhan

>Можно пример кода засовывания генсимов в пакадж?

Нельзя. Символ уже принадлежит какому-либо package или никому. Можно в своём package создать символ с таким-же именем.

(intern (symbol-name (gensym)) my-package)

yyk ★★★★★
()
Ответ на: комментарий от zahardzhan

>Можно пример кода засовывания генсимов в пакадж?

(intern (gensym) (find-package :your-package))

Только при чем тут gensym, уже не понятно. gensym, прежде всего, используется для генерации «локальных» имен в макросах.

Может быть, имеет смысл генерировать осмысленные имена переменных?

Например, для вашего кода:

`(defparameter ,(intern (str key1 "-MAP") (find-package '#:keymap-package))

(конечно же, подразумевая, что keymap-package где-то определен:

(defpackage #:keymap-package)

)

dmitry_vk ★★★
()
Ответ на: комментарий от yyk

>Нельзя. Символ уже принадлежит какому-либо package или никому. Можно в своём package создать символ с таким-же именем.

Да вы что? Вполне можно. Можно добавлять символы в пакет и удалять их из пакета.

dmitry_vk ★★★
()
Ответ на: комментарий от zahardzhan

Я таки не понял, зачем там глобальная переменная, а вы? ;)

archimag ★★★
()
Ответ на: комментарий от zahardzhan

юзай одну глобальную переменную - хеш( или лучше алист), куда складывай префиксы и соответствующие кей мапы. можно делать рекурсивно - запоминать в значении кеймап и ещё алист/хеш следующего уровня, если это поддерживается wm.

anonymous
()
Ответ на: комментарий от yyk

>запятая нужна и перед (gensym)

Нет, не нужна, этот макрос используется в другом макросе, и (gensym) исполнится внутри тела другого макроса.

dmitry_vk ★★★
()
Ответ на: комментарий от dmitry_vk

>Да вы что? Вполне можно. Можно добавлять символы в пакет и удалять их из пакета.

Я надеюсь вы сейчас не про импорт? Ибо это из другой оперы. Удалять - можно.

yyk ★★★★★
()
Ответ на: комментарий от yyk

Спасибо за просвещение насчет интернов - код заработал как следует.

ИМХО, в коде

Вопросы насчет этого кода - к Сейбелю.

юзай одну глобальную переменную - хеш( или лучше алист), куда складывай префиксы и соответствующие кей мапы. можно делать рекурсивно - запоминать в значении кеймап и ещё алист/хеш следующего уровня, если это поддерживается wm.

Авторы StumpWM уже напридумывали - у них на каждый префикс - своя глобальная переменная, так что для динамического изменения кеймапов глобальные переменные тоже нужно генерить динамически.

zahardzhan
() автор топика

Суровые челябинские лисперы

Вам ещё самим-то не смешно от утверждения, что «лисп — язык общего назначения, и для написания прикладных программ более эффективен, чем любой другой язык»? Если такая элементарщина как «настроить кейбиндинг» превращается в многочасовой квест с ковырянием потрохов программы, привлечением «гуру» с форума, разбирательстве в том, как работают внутренние механизмы языка? В то время как пользователь программы, написанной на мейнстрим-языке, просто пойдёт и поменяет кейбиндинг за секунду.

Или, может, это такой квест для посвящения новичков? смог поменять кейбиндинг в StumpWM = клерик 1-го левела, смог заточить под себя поведение новых окон = 2-го уровня, и так далее. Уровню к десятому появится доступ к тайному знанию, которое часто проявляется в фразах лисперов типа «да на лиспе пишут софт, но это хай-энд, вам его никто не покажет, быдло».

Секта такая секта.

anonymous
()
Ответ на: Суровые челябинские лисперы от anonymous

Ну если есть в софте кривизна by design (мешок глобальных(!) переменных надо) то, ессно, даже с серебряной пулей придется повозиться.

impfp
()
Ответ на: Суровые челябинские лисперы от anonymous

Вам ещё самим-то не смешно от утверждения, что «лисп — язык общего назначения, и для написания прикладных программ более эффективен, чем любой другой язык»? Если такая элементарщина как «настроить кейбиндинг» превращается в многочасовой квест с ковырянием потрохов программы, привлечением «гуру» с форума, разбирательстве в том, как работают внутренние механизмы языка? В то время как пользователь программы, написанной на мейнстрим-языке, просто пойдёт и поменяет кейбиндинг за секунду.

Утопись, человечеству от твоего невежества пользы не будет.

mv ★★★★★
()
Ответ на: Суровые челябинские лисперы от anonymous

> Вам ещё самим-то не смешно от утверждения, что «лисп — язык общего назначения, и для написания прикладных программ более эффективен, чем любой другой язык»? Если такая элементарщина как «настроить кейбиндинг» превращается в многочасовой квест с ковырянием потрохов программы, привлечением «гуру» с форума, разбирательстве в том, как работают внутренние механизмы языка? В то время как пользователь программы, написанной на мейнстрим-языке, просто пойдёт и поменяет кейбиндинг за секунду.

ты просто лузер и твой пук никому не нужен.

CL-USER
()
Ответ на: Суровые челябинские лисперы от anonymous

Не путай, StumpWM - реально весьма кривое поделие, и да, на Common Lisp можно писать криво, никто ведь обратного не утверждал. Собственно, проблемы StumpWM с языком никак не связаны. Ну и потом, нет уверенности, что автор правильно понял, что именно нужно делать для изменения кейбиндингов, ибо озвученная идея вызывает серьёзные сомнения.

archimag ★★★
()
Ответ на: комментарий от archimag

Не путай, StumpWM - реально весьма кривое поделие

Доводы в защиту этого мнения будут?

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

Конечно, не надо.

(define-key *top-map* (kbd "XF86Eject") "exec eject")
mv ★★★★★
()
Ответ на: комментарий от mv

> Доводы в защиту этого мнения будут?

Я два дня изучал исходники StumpWM, и страшно при этом ругался, ибо декомпозиция никуда не годится. Лучше всего я запомнил, что понятие фрэйма очень слабое, а workspace наоборот берёт на себя слишком много. В итоге, изменить существенным образом поведение системы (я хотел скратчпады как в Ion3) почти не реально (разве что всё переписать). Одного этого достаточно для вывода о кривизне, но подобная «плохая» декомпозиция там встречается постоянно.

Т.е. я сравнивал декомпозицую в Ion3 и StumpWM и пришёл к выводу, что StumpWM надо закапывать (ну или переписывать).

archimag ★★★
()
Ответ на: комментарий от archimag

> декомпозиция никуда не годится

«плохая» декомпозиция там встречается постоянно

надо закапывать (ну или переписывать)



Лол, лисп с его хвалёным CLOS в архитектурных вопросах феерично просирает смеси из Си и Lua.

anonymous
()
Ответ на: комментарий от anonymous

> Лол, лисп с его хвалёным CLOS в архитектурных вопросах

феерично просирает смеси из Си и Lua.


Нет, вы забыли о роли личности разработчиков. Мнение о том, что «все лисперы ацкая элита» глубоко неверно. Ещё раз: в данном случае проблема не в языке, а в голове разработчиков.

archimag ★★★
()
Ответ на: комментарий от archimag

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

(define-key *top-map* (kbd "XF86Eject") "exec eject")

Статическое определение цепочек кейбиндингов а-ля \M-d\M-a\M-w - оно без проблем сделать из-каробки можно, благо fill-keymap есть, а вот с динамическим - всё сильно хуже. Другого способа, как через генерацию глобальных переменных я не нашол.

zahardzhan
() автор топика
Ответ на: комментарий от zahardzhan

> Другого способа, как через генерацию глобальных переменных

я не нашол.


Так зачем нужны глобальные переменны то? define-key это фукнция, которая принимает структуру kmap. Из чего следует, что это должна быть глобальная переменная?

archimag ★★★
()
Ответ на: комментарий от archimag

Я два дня изучал исходники StumpWM, и страшно при этом ругался, ибо декомпозиция никуда не годится. Лучше всего я запомнил, что понятие фрэйма очень слабое, а workspace наоборот берёт на себя слишком много. В итоге, изменить существенным образом поведение системы (я хотел скратчпады как в Ion3) почти не реально (разве что всё переписать).

Это потому, что ты Ratpoison не использовал. StumpWM - это Ratpoison на Лиспе.

Одного этого достаточно для вывода о кривизне, но подобная «плохая» декомпозиция там встречается постоянно.

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

mv ★★★★★
()
Ответ на: комментарий от mv

> Это потому, что ты Ratpoison не использовал.

StumpWM - это Ratpoison на Лиспе.


Я использую Ion3, ИМХО, лучший фрэймовый WM (кстати, разработчик изменил лицензию, за которую его все ругали, мотивировав это тем, что код очень стабилен и вообще он ушёл на винду :)). И я был бы счастлив иметь аналог Ion3 на Common Lisp. Когда я увидел StumpWM, то подумал: «во, почти то же самое, немного допилить и получу нужный функционал». Однако попытка допилить закончилась плачевно, ибо допилить до уровня Ion3 его просто нельзя, только если основательно переписать.

тебя могу уверить, что у тебя на десктопе столько кривого софта с

плохой декомпозицией/архитектурой крутится, что проще сразу


застрелиться. Начать хотя бы с ядра.



Не буду спорить насчёт ядра, я его разработкой не занимался ;) Да и с другим софтом... я не могу на всё влиять. Но у меня есть выбор среди некоторых категорий софта, в частности, я могу выбирать WM. Я предпочитаю фрэймвоые WM и просмотрел большинство из них. И StumpWM один их худших. Но проблема не в этом, а в том, что это нельзя изменить, его не исправить.

Ion3 написал один человек, который даже патчей не принимал, а в рассылке StumpWM крутиться толпа народа. Один C+Lua кодер уделал по всем статьям команду CL программистов - ситуация выглядит именно так.

archimag ★★★
()
Ответ на: комментарий от archimag

> Я предпочитаю фрэймвоые WM и просмотрел большинство из них. И StumpWM один их худших.

я ни разу не пробовал stumpwm, но может все дело в том, что он - динамический tiling wm, а ion3 - статический?

paranonymous
()
Ответ на: комментарий от paranonymous

> но может все дело в том, что он - динамический tiling wm,

а ion3 - статический?


Хм.. Что означает данная терминология?

archimag ★★★
()
Ответ на: комментарий от mv

> Я понял твой критерий хорошести WM: похож на ион -

пять баллов, совсем не похож - кол.


Нет, не понял. Прежде всего я говорю об архитектуре. Можно было бы ожидать, что WM на Common Lisp обладал бы большей гибкостью, чем Ion3 или тот же XMonad, но на деле совсем другая картина. StumpWM - это очень плохая реклама Common Lisp.

Кстати, я запускал StumpWM совместно с Swank, подключался к нему с помощью Slime и пытался вносить по-большей части довольно безобидные изменения в код. Примерно в 70% случаев это приводил к немедленному вылету X-ков. Это вообще что-то ненормальное...

archimag ★★★
()
Ответ на: комментарий от archimag

это очень плохая реклама Common Lisp.

2005 год, три профессора mit не удержались тоже от плохой рекламы в работе для AOL.

http://philip.greenspun.com/tcl/introduction.adp

If in reading this introduction, you've come to realize that «Hey, Tcl is just like Lisp, but without a brain, and with syntax on steroids», you might wonder why Lisp isn't a more popular scripting language than Tcl. Lisp hasn't been a complete failure, by the way; it is used as an extension language by users of some popular programs, notably AutoCAD. But Tcl has been much more successful. It has been compiled into hundreds of larger programs, including AOLserver, which is why we wrote this book.

As a software developer, you're unlikely to get rich. So you might as well try to get through your life in such a way that you make a difference to the world. Tcl illustrates one way:

* make something that is simple enough for almost everyone to understand * give away your source code * explain how to weave your source code in with other systems

In the case of AOLserver, for example, Jim Davidson and Doug McKee had only a few months to build the whole server from scratch. They wanted users to be able to write small programs that ran inside the server process. They therefore needed a safe interpreted language so that a programming error by one user didn't crash the server and bring down all the Web services for an organization.

Tcl was available. Tcl was easy to download and designed to fit inside larger application programs. But the Tcl interpreter as distributed had one terrible bug: it wasn't thread safe, i.e., you couldn't have two copies of the Tcl interpreter running inside the same program at the same time. Doug and Jim had to read through the Tcl source code and modify it to be thread safe. So it was critically important for them that Tcl was open-source and simple enough so as to not require months or years of study to understand the whole system.

Compare this to Lisp. Some of the best and brightest computer scientists raised money to build commercial Lisp implementations that they then went out and hawked in an indifferent and confused marketplace. They succeeded only in breaking their hearts and their investors' wallets. A handful of academics produced free open-source implementations, notably CMU Common Lisp (see http://www.cons.org/cmucl/) and various versions of Scheme (see http://www-swiss.ai.mit.edu/scheme-home.html; Scheme 48 is the closest to Tcl in spirit). But these multi-megabyte monsters weren't designed to fit neatly into someone else's program. Nor was there any document explaining how to do it.

Lisp developers have the satisfaction of knowing that they got it right 30 years before anyone else. But that's about all they have to show for 40 years of hard work and hundreds of millions of dollars in government and private funding. These days, most former Lisp programmers are stuck using Unix and Microsoft programming environments and, not only do they have to put up with these inferior environments, but they're saddled with the mournful knowledge that these environments are inferior.

elipse ★★★
()
Ответ на: комментарий от archimag

Можно было бы ожидать, что WM на Common Lisp обладал бы большей гибкостью

Можно было бы ожидать, что лисп-машины не умрут, и что такой мощный язык в 80-х годах уж точно всё остальное задавит, и что Бангалор будет по миллиону лисперов, а не джаверов в год штамповать. Много чего ещё можно было от Лиспа ожидать. Но этого при всей мощности Лиспа не случилась. Что теперь с того толку?

StumpWM - это Ratpoison, переписанный тем же автором на Лиспе. О чём вообще идёт речь? Речь идёт про то, что тебе нравится Ion, и не нравится Ratpoison/StumpWM. Ах, у StumpWM архитектура не как у любимого Ion'а, какое горе...

StumpWM - это очень плохая реклама Common Lisp.

Это сугубо субъективно. Лично мне вот веб не нравится, и все лисповые вебфреймворки, по моему мнению, - антиреклама Лиспа. Типа, язык для веба.

Примерно в 70% случаев это приводил к немедленному вылету X-ков. Это вообще что-то ненормальное...

Прям иксов? Действительно, несерьёзно для иксов.

mv ★★★★★
()
Ответ на: комментарий от jtootf

Так зачем нужны глобальные переменны то? define-key это фукнция, которая принимает структуру kmap. Из чего следует, что это должна быть глобальная переменная?

(defun define-key (map key command)
  "Add a keybinding mapping for the key, @var{key}, to the command,
@var{command}, in the specified keymap. If @var{command} is nil, remove an
exising binding.  For example,

@example
\(stumpwm:define-key stumpwm:*root-map* (stumpwm:kbd \"C-z\") \"echo Zzzzz...\")
@end example

Дело не в структуре kmap, а в аргументе command. Для создания цепочек кейбиндингов нужно определять глобальные переменные-карты биндингов и передавать символы, а не строки, в качестве аргумента command:

(defvar *all-bindings* nil) ;; a→ all
(defvar *delete-bindings* nil) ;; d→ delete
(defvar *delete-all-bindings* nil) ;; d→a→ delete all
(defvar *window-bindings* nil) ;; w→ window
(defvar *frame-bindings* nil) ;; f→ frame
(defvar *go/group-bindings* nil) ;; g→ go/group
(defvar *run-bindings* nil) ;; r→ run
 
(setf *top-map* nil)
 
(fill-keymap *top-map*
             *escape-key* '*root-map*
             (kbd "s-a") '*all-bindings*
             (kbd "s-d") '*delete-bindings*
             (kbd "s-w") '*window-bindings*
             (kbd "s-f") '*frame-bindings*
             (kbd "s-g") '*go/group-bindings*
             (kbd "s-r") '*run-bindings*
             (kbd "s-Return") "exec urxvt"
             (kbd "s-quoteleft") "exec urxvt"
             (kbd "s-x") "colon"
             (kbd "s-X") "exec")

(fill-keymap *delete-bindings*
             (kbd "a") '*delete-all-bindings*
             (kbd "s-a") '*delete-all-bindings*
             (kbd "W") "kill-window"
             (kbd "s-W") "kill-window")

(fill-keymap *delete-all-bindings*
             (kbd "f") "only"
             (kbd "s-f") "only")

zahardzhan
() автор топика
Ответ на: комментарий от zahardzhan

> Для создания цепочек кейбиндингов нужно определять глобальные

переменные-карты биндингов и передавать символы, а не строки, в

качестве аргумента command:



Да ничего подобного. Символ действительно требуется в макросе fill-keymap, но он даже не экспортируется и как бы предназначен для внутреннего пользования. Это просто вспомогательный макрос, делающий довольно тривиальную вещь. Можно совершенно спокойно обойтись из без него.

archimag ★★★
()
Ответ на: комментарий от zahardzhan

В конце концов структура должна быть такой:

STUMPWM> *top-map*
#S(KMAP
   :BINDINGS (#S(BINDING
                 :KEY #S(KEY
                         :KEYSYM 116
                         :SHIFT NIL
                         :CONTROL T
                         :META NIL
                         :ALT NIL
                         :HYPER NIL
                         :SUPER NIL)
                 :COMMAND *ROOT-MAP*)
              #S(BINDING
                 :KEY #S(KEY
                         :KEYSYM 100
                         :SHIFT NIL
                         :CONTROL NIL
                         :META NIL
                         :ALT NIL
                         :HYPER NIL
                         :SUPER T)
                 :COMMAND *DELETE-BINDINGS*)))

STUMPWM> *delete-bindings*
#S(KMAP
   :BINDINGS (#S(BINDING
                 :KEY #S(KEY
                         :KEYSYM 97
                         :SHIFT NIL
                         :CONTROL NIL
                         :META NIL
                         :ALT NIL
                         :HYPER NIL
                         :SUPER NIL)
                 :COMMAND *DELETE-ALL-BINDINGS*)))

STUMPWM> *delete-all-bindings*
#S(KMAP
   :BINDINGS (#S(BINDING
                 :KEY #S(KEY
                         :KEYSYM 102
                         :SHIFT NIL
                         :CONTROL NIL
                         :META NIL
                         :ALT NIL
                         :HYPER NIL
                         :SUPER NIL)
                 :COMMAND "only")))

zahardzhan
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.