LINUX.ORG.RU
Ответ на: комментарий от baverman

это всё чёртовы фиды. просил макскома добавить в начале фида теги, а не в конце...

jeuta ★★★★
()
Последнее исправление: jeuta (всего исправлений: 1)
Ответ на: комментарий от dave

разве mv(хотябы) и всякий анонимус заходит на лиспер.ру?

Bad_ptr ★★★★★
()

Надо подумать, а лучше попробовать, но с первого взгляда кажется неплохой идея использоватт для идентификации пакетов не string-designator, а символ, как в named-readtables. Тогда и локальные пакеты будут, и локальные никнеймы станут не нужны (можно просто добавить глобальный никнейм на локальный символ).

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

А, да. Проблема. Как пакеты доступные по цепочке символов писать и читать в текст?

naryl ★★★★★
()

Лично мне нынешние пакеты кажутся неудобными, что-то вроде с++ных нэймспейсов было бы более логичным.

staseg ★★★★★
()

более удобный экспорт из пакета, задалбливает каждый символ отдельно экспортировать. Я для этого писал какой-то макрос раньше - типа defun-and-export

pseudo-cat ★★★
()

1. Иерархические пакеты

2. Локальные никнеймы для пакетов

3. Удобный механизм экспорта (хотя тут, наверное, можно обойтись просто макрами, все-равно всем не угодить)

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

более удобный экспорт из пакета

Тут как раз проблем нет. Начиная от (defun* ...), (def function e ...), заканчивая (do-symbols (sym) (when (fboundp sym) (export sym))

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

Иерархические пакеты, локальные никнеймы

Если только это, то реализаций куча. Кроссплатформенная https://github.com/Kalimehtar/advanced-readtable + по штуке для каждого популярного CL.

Удобный механизм экспорта

А как он должен выглядеть синтаксически?

monk ★★★★★
() автор топика

Как в .Net или в Java вполне ок.

Norgat ★★★★★
()

Ну можно ещё посмотреть:
Clojure Programming Chas Emerick, Brian Carper, and Christophe Grand
“Defining and Using Namespaces” page 322

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

Если только это, то реализаций куча. Кроссплатформенная https://github.com/Kalimehtar/advanced-readtable + по штуке для каждого популярного CL.

ООООО! Красота! Спасибище, забрал в букмарки, будем тестировать-внедрять

А как он должен выглядеть синтаксически?

А хз пока, см. приписку в скобках моего первоначального коммента: тем, кому надо много и по хитрым правилам экспортировать, просто нужно написать макру.

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

про defun* не в курсе, в CLHS не нашел. def аналогично. fboundp возвратит t в том числе для экспортированных в пакет символов из других пакетов? Для акессоров, если не ошибаюсь, это не работает, но сейчас нет возможности запустить лисп.

Просто, если во многих ЯП можно написать что-то типа public и всем понятно, что этот класс/метод/ф-ция будут видны вне наймспейса, то в CL приходится: или где-то в отдельном месте руками писать ф-цию обхода всех внутренних символов пакета и фильтровать их, или писать что-то типа макроса, делающего export, ну или руками прописывать каждый символ в объявлении пакета. Последний вариант впрочем меня вполне устраивает, но в больших пакетах утомляет или когда много классов. Как вариант можно сделать ф-цию в емаксе, записывающую символ в export пакета, что еще немного усложнит жизнь новичкам в емаксе.

pseudo-cat ★★★
()
Ответ на: комментарий от monk

Можно.

Во-первых, иерархичность. Ниже ты привел ссылки, я потом посмотрю.

Во-вторых, в лиспе мне видится совершенно инопланетным, что содержимое пакета описывается под выражением (in-package), а не внутри, имхо логичней было бы:

(in-package :lor
 (defun foo ()
  42))
Естественно на такую запись органично ложился бы и синтаксис вложенных пакетов.
(in-package :lor
 (in-package :development
  (defun bar (x) x)))
; or
(in-package lor:development
 ...)

В-третьих, не очень удобен в использовании механизм импорта и экспорта (частично решается макросами), а когда начинаются конфликты символов, вообще труба. Например функцию фу из пакета лор было бы удобно локально импортировать так:

(using lor:foo
 (foo))

(using (lor:development:bar lor:foo)
 (bar (foo)))

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

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

Если только это, то реализаций куча. Кроссплатформенная https://github.com/Kalimehtar/advanced-readtable + по штуке для каждого популярного CL.

Посмотрел чуть подробнее: не нашел там иерархических пакетов. Куда смотреть?

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

Во-вторых, в лиспе мне видится совершенно инопланетным, что содержимое пакета описывается под выражением (in-package), а не внутри

Есть такое понятие как «текущий пакет», и есть оно неспроста. in-package мог бы ещё получать &body и читать в указанном пакете только его (правда, это реализуется только костылями), но я сомневаюсь в необходимости. Единственный эффект - весь файл получит ещё один уровень отступа. Сомневаюсь, что это сильно улучшит понятность кода.

Естественно на такую запись органично ложился бы и синтаксис вложенных пакетов.

:development - это кейворд. Его значение не зависит от текущего пакета.

(using (lor:development:bar lor:foo)
  (bar (foo)))

lor:development:bar

Это вообще что? sbcl говорит слишком много двоеточий.

Вы смогли наступить на те самые грабли, которые я описал за шесть минут до вашего коммента. :)

Пакеты. Как должно быть? (комментарий)

Для вложенных пакетов можно было бы использовать обычные символы (не кейворды)

(in-package :lor
 (in-package development
  (defun bar (x) x)))

Но тогда к этой функции глобально не обратиться никак, только из пакета где она объявлена, потому что у самого пакета глобального имени нет. Может это и хорошо. :) Можно было бы объявлять один глобальный интерфейсный пакет, а внутри него пакеты для модулей. А интерфейсные символы из этих модулей переэкспортировать из :lor.

naryl ★★★★★
()
Последнее исправление: naryl (всего исправлений: 1)
Ответ на: комментарий от naryl

Конечно, проблему можно решить изменением синтаксиса для чтения-записи имён символов. Но про это лучше не думать.

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

Есть такое понятие как «текущий пакет», и есть оно неспроста. in-package мог бы ещё получать &body и читать в указанном пакете только его (правда, это реализуется только костылями), но я сомневаюсь в необходимости. Единственный эффект - весь файл получит ещё один уровень отступа. Сомневаюсь, что это сильно улучшит понятность кода.

Я знаю, что он есть, но лучше бы его не было. Или он мог бы быть «текущим» внутри формы in-package. В топике вопрос не «как в ненешнем CL накостылить другой интерфейс к пакетам», а «как бы лучше это могло быть».

:development - это кейворд. Его значение не зависит от текущего пакета.

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

lor:development:bar

Это вообще что? sbcl говорит слишком много двоеточий.

Это локальный экспорт в текущий пакет символа bar из пакета development, вложенного в пакет lor. SBCL все верно говорит, он ничего не знает о моей вымышленной пакетной системе.

Но тогда к этой функции глобально не обратиться никак, только из пакета где она объявлена, потому что у самого пакета глобального имени нет. Может это и хорошо. :) Можно было бы объявлять один глобальный интерфейсный пакет, а внутри него пакеты для модулей. А интерфейсные символы из этих модулей переэкспортировать из :lor.

А еще лучше не разделять пакеты на «внешние» и «вложенные» и тем более не думать о «внешнем» пакете кейвордов. Просто есть пакет, у него может быть родитель и несколько дочерних пакетов, для которых он выступает родителем и у которых тоже могут быть дети и т.д. Естественно, должен быть какой-то один самый top-level пакет.

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

Я знаю, что он есть, но лучше бы его не было.

И получится питончег или эрланг со специальным костылём для репла. В попытках починить одно не надо ломать другое, тем более когда единственным «профитом» от «исправления» станут ещё два пробела в начале каждой строки в файле.

naryl ★★★★★
()
Последнее исправление: naryl (всего исправлений: 2)
Ответ на: комментарий от staseg

Похоже, вы просто хотите пакетную систему из Tcl. :) Одобряю почти полностью, кроме устранения сущности *package*.

:asdf - глобальный символ asdf. Можно все глобальные символы сделать кейвордами.
:lor:development - символ development в пакете :lor.
:lor:development:foo - символ foo в пакете :lor:development

(in-package :lor)
(defun development:foo () ; Функция :lor:development:foo)
(defun :development:foo (); Функция :development:foo)
naryl ★★★★★
()
Последнее исправление: naryl (всего исправлений: 2)
Ответ на: комментарий от staseg

ну ладно, и я прорекламирую.

http://code.google.com/p/def-symbol-readmacro/wiki/GeneralDescription

Когда-то это была переносимая библиотека, но т.к. была никому не нужна, теперь она только под лиспворкс.

Иерархические пакеты у меня были, взяты были отсюда: http://www.tfeb.org/programs/lisp/hierarchical-packages.lisp а он в свою очередь позаимствовал их у Allegro.

Но как-то оказались невостребованы мной.

Реально удобная вещь, которой пользуюсь постоянно - это локальные псевдонимы пакетов и def-symbol-readmacr-ы.

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

in-package сейчас получает одно имя. Можно для изменения пакета «на время» разрешить ещё передавать ему body, но этом будет костыль, объединяющий read и macroexpand. Кроме того, сочувствующие схемке обязательно начнут пихать в него файл целиком. Поэтому не стоит.

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

локальная смена пакета, a:(a b c) тоже не прижилась на практике, поскольку она ломает IDE. Для того, чтобы она не создавала мусорных символов,нужно гарантировать, что при работе в IDE никогда не произойдет чтения символа a из *package* - он там не нужен. Я не знаю, как это реализовать, практически тут придётся постоянно читать reader-ом текущую форму, а это может оказатья дорого и глючно из-за возможности побочных эффектов во время чтения.

Все вещи,к-рые у меня анонсированы, мной проверены на практике и показали себя не создающими новых глюков. Исключением явяляется CamelCase в сочетаании с *print-case* = :downcase, которой я пользуюсь совсем недавно.

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

И получится питончег или эрланг со специальным костылём для репла. В попытках починить одно не надо ломать другое.

Да можно оставить и *package*, проблем нет. По умолчанию он - top-level пакет, внутри форм in-package ему присваивается локальный пакет. Сам символ *package* очевидно должен находиться в top-level пакете.

Похоже, вы просто хотите пакетную систему из Tcl. :)

Я к сожалению пока не знаю тикель и не уверен, узнаю ли его когда-нибудь вообще. С моей стороны это скорее попытка притащить с++-ные неймспейсы, которыми пользоваться удобно, в лисп, работать с пакетами которого лично мне не особо приятно.

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

Я пакеты Tcl дальше в комменте описал. Там можно обращаться глобально, начав полное имя символа с двоеточия, а можно относительно текущего пакета. Ну и пакеты иерархичные, что потребует изменения синтаксиса read для полных имён символов.

Кстати, у всех package-local-nicknames в CL есть проблема с write/read локально-переименованных пакетов. Появляются такие штуки как find-package-using-package. С иерархическими пакетами и этой фичёй из Tcl можно локально-переименованные пакеты представлять просто как локальные пакеты, являющиеся псевдонимами других. Например:

(in-package :my-app)
(local-nickname threads :bordeaux-threads)
(defun start ()
  (threads:make-thread #'my-entry-point))

После этого символы из :bordeaux-threads окажутся доступны по, например, :my-app:threads:make-thread. И никаких костылей с write/read, кроме самого изменения синтаксиса полного имени символа.

/me кастует обратно Monk

naryl ★★★★★
()
Последнее исправление: naryl (всего исправлений: 6)
Ответ на: комментарий от naryl

Именно это делается так:

(in-package :my-app)
(advanced-readtable:!)
(push-local-nickname :bordeaux-threads :threads)
(defun start ()
  (threads:make-thread #'my-entry-point))

Чтобы после этого было (eq (find-package «my-app.threads») (find-package «bordeaux-threads»)) сегодня сделаю. Кстати, интересная идея.

Классическую иерархию я так и не сделал (пока не быо причины использовать). Просто для дерева пакетов есть

(push-import-prefix :hu.dwim)
...
далее можно использовать вместо hu.dwim.def просто def, вместо hu.dwim.perec просто perec и т.д.

Вложенные пакеты классически в CL делаются через точку. Пример http://www.informatimago.com/develop/lisp/doc/flat-package-index.html

(in-package :lor
 (in-package development
  (defun bar (x) x)))

при доделанном иерархическом парсере будет

lor::(progn
  .development::(defun bar (x) x)))

Поэтому локальный in-package уже есть (и почти стандарт, взято из http://www.sbcl.org/manual/index.html#Reader-Extensions)

Идея насчёт (using symbol-list &body body) мне тоже весьма нравится. Хотя тут вопрос как логичнее (или красивее)

(using (lor:development:bar lor:foo)
 (bar (foo)))
или
#@(lor:development:bar lor:foo)
 (bar (foo))

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

ЕМНИП точка по стандарту (clhs, а не маны sbcl) ничего не значит. Я именно поэтому хотел допилить read/write чтобы они двоеточие понимали как разделитель пакетов в иерархии. Но решение с точкой проще и вроде много кода сломать не должно.

(advanced-readtable:!)

Пошёл почитать сорцы, посмотреть почему не named-readtables и увидел страшное. В advanced-readtable символы могут быть только в ascii. Конечно, юникодные идентификаторы - это недокументированное расширение некоторых реализаций вроде sbcl, но всё-же...

Идея насчёт (using symbol-list &body body) мне тоже весьма нравится.

Вот в этом случае думаю будет больше вреда чем пользы. ИМХО полную информацию о связях с другими пакетами должна быть возможность записать в defpackage. Там уже есть import-from, который должен быть достаточно хорош, если у автора нет цели писать спагетти-код.

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

А как advanced-readtable скрестить с commonqt? Последний использует named-readtables.

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

ЕМНИП точка по стандарту (clhs, а не маны sbcl) ничего не значит

По стандарту нет, но некоторые, например, http://www.gigamonkeys.com/book/programming-in-the-large-packages-and-symbols... рекомендуют их так именовать.

В advanced-readtable символы могут быть только в ascii.

Не только. В ascii должны быть первые буквы имен пакетов и символов-макросов. На остальное ограничений нет.

По-другому сделать сложно. Можно добавить произвольный явный набор символов (например, русский алфавит) и всё. Потому что при попытке установить set-macro-character на весь юникод ОЧЕНЬ долго ждать приходится.

А как advanced-readtable скрестить с commonqt? Последний использует named-readtables.

Самый простой вариант: (advanced-readtable:activate :force t) после in-readtable. А если правильно, то надо в commonqt менять set-macro-character + named-readtables на set-macro-symbol.

monk ★★★★★
() автор топика
Последнее исправление: monk (всего исправлений: 1)
Ответ на: комментарий от naryl

окажутся доступны по, например, :my-app:threads:make-thread

Сделал. Теперь можно делать

(advanced-readtable:!)
(advanced-readtable:enable-global-nicknames)
(advanced-readtable:push-local-nickname 'threads :bordeaux-threads)
(eq 'threads:make-thread 'my-app.threads.make-thread)

Более того, работает

(advanced-readtable:enable-hierarchy-packages)
(in-package my-app.test)
(eq 'bordeaux-threads:make-thread '..threads.make-thread)

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

(eq 'threads:make-thread 'my-app.threads.make-thread)

(eq 'threads:make-thread 'my-app.threads:make-thread) ?

А эти фичи (advanced-readtable:enable...) работают для текущего пакета или глобально? Если глобально, то есть смысл либо отмечаться в *features*, либо наоборот заставить пользователя положить их в *features* прежде чем загружать advanced-readtable.

Остальные отличия от ожидаемого мной поведения - в гитхаб.

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

Делая имя пакета символом, не следует забывать о редакторе: он ищет форму in-package в начале файла. Если SLIME можно пропатчить, чтобы оно вело себя как угодно, то закрытые среды типа Allegro или Lispworks пропатчить может не получиться. Т.е., данное решение потенциально имеет изъян в переносимости, т.к. проприетарные IDE сломаются на (in-package символ).

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

Точка в начале имени может вызвать проблемы, например, не факт, что правильно считается список '(a .b)

Я в своё время даже писал об этой ошибке в ридере SBCL, не знаю, поправили ли они её.

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

С другой, обидно, что я за 3-4 года существования своей библиотеки не смог никого привлечь, а Monk сразу нашёл сторонников, хотя его библиотека по фичам и законченности с моей даже рядом не стояла. Видимо, что-то со мной не так... Но хорошо, во всяком случае, что в SBCL ввели local-nicknames. Не исключено, что тут есть и моя доля заслуг, потому что свою библиотеку уже неоднократно на c.l.l. рекламировал.

У меня, например, всё декларативно, никаких push-ей. Был этап с push-ами и у меня, но уже год, как я от всех от них избавился. И def-symbol-readmacro у меня тоже декларативны.

Было бы гораздо проще портировать мою библиотеку в её новом виде на SBCL, чем идти путём ошибок проектирования. Ошибки проектирования такой низкоуровневой библиотеки очень дороги, потому что по мере их исправления приходится править и код, который на них ссылается. Я всё это уже проделал и нашёл годные решения.

В общем, есть мне над чем подумать...

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

P.S. никакие изменения ридера не нужны, если они не сопровождаются патчами для IDE. Completion не должен переставать работать. В Lispworks я поимел трудности с Completion, но вот-вот они будут решены, путём полного переписывания COmpletion заново. SLIME я никогда не трогал, но вы должны её поправить, если хотите, чтобы ваша библиотека была полезной.

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

С другой, обидно, что я за 3-4 года существования своей библиотеки не смог никого привлечь, а Monk сразу нашёл сторонников, хотя его библиотека по фичам и законченности с моей даже рядом не стояла. Видимо, что-то со мной не так...

Да, не так. Дайте хотя бы здесь ссылку на свою библиотеку и подскажите Monk на какие именно грабли ему ещё предстоит наступить.

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

http://code.google.com/p/def-symbol-readmacro/

Если это оно, то проблема не с вами, а с проектом. Он рассчитан только на одну закрытую реализацию. Переносимость - это хорошо, но 99% пользователей других реализаций (что, учитывая их общее количество, превращается в 100% :]) дальше «Currently only runs with Lispworks» не читают.

naryl ★★★★★
()
Последнее исправление: naryl (всего исправлений: 1)
Ответ на: комментарий от naryl

то есть смысл либо отмечаться в *features*,

Работают глобально. Согласен, добавлю в *features* :hierarchy-packages и :global-nicknames соответственно.

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

Так в том-то и дело, что ссылка присутствует в данной теме выше. Не говоря о том, что и раньше я давал эту ссылку раз 10 с рекламными анонсами. Видимо, это что-то на космическом плане не так.

Я не могу предсказать все грабли, ибо это зависит от направления движения Monk. Я мог бы сказать про грабли, которые встретились на _моём_ пути, но это не нужно, поскольку все эти знания уже содержатся в моей библиотеке. История библиотеки Monk такова, что он взял мою библиотеку, выбросил из неё, наверное, 90%, взял только одну идею и решил делать что-то своё. Видимо, мой опыт ему не нужен, но меня не это заботит, а именно то, о чём я написал выше.

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

Если это оно, то проблема не с вами, а с проектом.

До этого он года 4 был переносимым, а непереносимым стал буквально пару месяцев назад, когда я понял, что идея, на которой ныне построена библиотека Monk, в случае Lispworks является тупиковой и вырезал для новой версии большой кусок ридера из SBCL.

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

Так в том-то и дело, что ссылка присутствует в данной теме выше.

Да, это однозначно в астрале помехи.

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

желающие могут скачать версию до 19 декабря.

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

Здесь может быть очень много проблем. Во-первых, не понятно где теперь вызывать эти enable-... У my-app некоторые зависимости могут на них смотреть, например, так что я не могу включать их в toplevel packages.lisp.

Во-вторых, надо подумать в чём смысл *не* включать эти фичи и какие будут последствия от их неожиданного состояния (включены, когда автор проекта рассчитывал на выключенные и наоборот). ИМХО лучше всего как-нибудь сделать их file-local как *readtable*. Это логично, учитывая что влияют они как-раз таки только на ридер и больше ни на что.

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

Он рассчитан только на одну закрытую реализацию.

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

Основной причиной форка послужило моё неумение использовать этот пакет. А именно, как включить его «частично». Ну не надо мне, чтобы после загрузки пакета (eq MyList mylist) выдавало nil. И всякие мелочи в коде, типа переопределения (defmethod print-object ((obj readtable) stream) ...) тоже слегка пугали. В общем, как труды Аристотеля: вроде умно, круто, но без толкователя очень тяжело разобрать.

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

Во-вторых, надо подумать в чём смысл *не* включать эти фичи и какие будут последствия от их неожиданного состояния

В общем-то никаких. Первый поиск идёт через cl:find-package, и, если тот что-то вернул, то проверка иерархии и псевдонимов уже не производится. Поэтому единственное последствиие: будет работать (читаться в смысле read) тот код, который без enable- не работает.

Но, с другой стороны, сейчас advanced-readtable:! полностью совместим с типовым ридером, а если сделать enable-... сразу, то уже не полная совместимость. Хотя, наверное, действительно лучше включить по-умолчанию.

как-нибудь сделать их file-local как *readtable*

Можно прикрутить к named-readtables/in-readtable... думаю, в этом направлении и буду двигать.

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

Вопрос про named-readtables: этот проект ещё жив? Последний коммит 3 года назад, последняя активность в рассылке — два года назад.

monk ★★★★★
() автор топика
Последнее исправление: monk (всего исправлений: 1)
Ответ на: комментарий от monk

Просто там нечему ломаться. Но можешь спросить на #lisp.

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