LINUX.ORG.RU

Синдром Эллочки-людоедки и lisp

 


3

4

В целом, мне нравится lisp - импонирует сама концепция lisp-a, я без особых проблем читаю s-выражения, нравиться его поддержка в emacs. И я использую emacs lisp как язык для всякой мелочевки.
С другой стороны простота концепции, когда первый аргумент s-выражения - функция, а остальные єлементы - параметры, имеет свой неприятный побочный эффект: огромное, неструктурированное пространство имен. Примерно за это я не люблю python - надо помнить кучу тонких особенностей и фич языка. А в lisp надо помнить кучу нужных функций. В книжке Грема их приблизительно 1000. В противопложность java - минимум ключевых слов, а вся функциональность вынесена в методы, которые выясняются по автодополнению и доктипу.
Второй нюанс, ХЗ, может зависит от конкретной реализации. Все функции из заргуженных пакетов валятся в одно пространство имен. Т.е. если Васян по глупости или злому умыслу перепишет стандартный car можно поиметь проблем, особенно если такой car подгружаю в составе какой-то библиотеки. Хотелось бы импорта a-la python import my-package as mp с последующим доступом типа (mp.foo).
Собственно, вопрос. Как борются с этими проблемами местные лисперы. Особенно с первой. Лично я запомнил около полусотни функций, примерно из списка снипеттов, к части прибавляю p и автоматом получаю знание новых. Может есть компактный список must know функций как перечень самых популярных коменд для emacs?
Вторая проблема больше для собственного кругозора, я сомневаюсь, что буду в большой команде использовать lisp, та и не годиться он для этого.

С пакетами вопрос решился. А с насышенным и неструктурированным пространством имен или с кратким справочником на манер такого - нет.

★★★★

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

Как борются с этими проблемами местные лисперы. Особенно с первой.

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

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

как запомнить кучу классов в стандартной библиотеке

Я использую сразу несколько языков, буду путаться и все такое. Я уже писал, в той же java мне нужно помнить минимум ключевых слов, а также приблизительно что именно импортировать. А дальше IDE подскажет и выдаст доктип. Emacs тоже подскажет, но функции неструктурированны и вынесены в общее пространство имен.

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

Читаем «The Complete Idiot’s Guide to Common Lisp Packages».

Bobby_
()

что буду в большой команде использовать lisp, та и не годиться он для этого

На clojure|clojurescript масса крупных проектов, особенно в веб-разработке.

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

И не путай CL и emacs lisp. Не понимаю как можно писать на нем что-то серьезное когда он создавался как язык расширения emacs. Там даже классов нету (вроде).

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

На clojure|clojurescript масса крупных проектов, особенно в веб-разработке.

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

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

Не понимаю как можно писать на нем что-то серьезное когда он создавался как язык расширения emacs.

Мне как-то было лень на новом маке поднимать всю девелоперскую обвязку. Потому, начал писать на emacs lisp. Оказалось довольно практично, плюс немалый кусок CL там реализован. Ну и батареек для моих задач полно. Когда завезут FFI и нормальную многопоточность из коробки, будет годный язык общего назначения. И уже сейчас он быстрее python будет, правда в виде байт-кода. Кроме того не исключено появление JIT-компилятора

Там даже классов нету (вроде).

давно

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

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

loz ★★★★★
()
Последнее исправление: loz (всего исправлений: 1)

С другой стороны простота концепции, когда первый аргумент s-выражения - функция, а остальные єлементы - параметры, имеет свой неприятный побочный эффект: огромное, неструктурированное пространство имен.

Во-первых, в Common Lisp есть пакеты. Они могут быть использованы как квалификаторы при обращении к именам из пакета: (foo:bar baz). Во-вторых, несмотря на «во-первых», в Лиспе принято использовать префиксы в именах функций и методов, т.е., если имеется класс baz, и его метод bar, то называть этот метод следует как baz-bar, а не просто bar. Да, это избыточно, но так делают почти все опытные лисперы-практики, а не теоретики-кукаретики.

Второй нюанс, ХЗ, может зависит от конкретной реализации. Все функции из заргуженных пакетов валятся в одно пространство имен.

Это ты про Emacs Lisp. Есть такой момент, поэтому нормальные люди просто используют префиксы к именам.

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

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

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

Просто это вот все - джентельменское соглашение, правила хорошего тона. Проходит для тебя любимого или маленькой притертой команды.

Совершенно верно. Классический Лисп больше подходит для одиночек-исследователей или для небольшой «притёртой» команды.

А галлеру, с ее текучкой, похоронит.

А вот для этого уже лучше Racket с его модулями и контрактами.

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

А по вопросу №1 можешь что-то сказать?

Если я правильно понял, первый вопрос о проблеме загрязнения пространства имён какого-нибудь пакета. Я уже ответил - в Лиспе принято использовать префиксы в именах функций и методов, т.е., если имеется класс baz, и его метод bar, то называть этот метод следует как baz-bar, а не просто bar. Например,

(defpackage my-package
  (:use cl)
  (:export person person-name set-person-name))

(in-package :my-package)

(defclass person ()
  ((name :reader person-name
         :writer set-person-name)))

Как видишь, имена методов имеют префиксы person- и set-person-, хотя можно было бы использовать имена name и set-name. Т.е. это, по сути, «правило джентльменов», да.

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

А галлеру, с ее текучкой, похоронит.

Естественно. CL - это огромная гибкость и динамизм. Нужно иметь выдержку и дисциплину чтобы проект не превратился в нагромождение из костылей.

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

ИМХО этой выдержке и дисциплине нужно учиться самому программисту, а не оставлять специально язык с ограничениями типа того как своим путём пошёл проект Racket.

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

Просто это вот все - джентельменское соглашение, правила хорошего тона.

Я тебе больше скажу: соглашения — это единственный 100% работающий инструмент. Все остальные способы, не смотря на бравурные рапорты о достижении небывалой эффективности — имитация «правильного поведения», которая работает на 100% только при использовании тех же соглашений.

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

...и emacs lisp. Не понимаю как можно писать на нем что-то серьезное когда он создавался как язык расширения emacs. Там даже классов нету (вроде).

В базовом языке нет, но на нем сделали объектную систему. Кое-чего нет в реализации, но в целом сойдет. Но я эту библиотеку не использую.

https://www.gnu.org/software/emacs/manual/html_node/eieio/index.html

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

Лиспе принято использовать префиксы в именах функций и методов, т.е., если имеется класс baz, и его метод bar, то называть этот метод следует как baz-bar, а не просто bar.

В функциях смысл имеет такое, а вот с методами обобщённых функций большого смысла не вижу.

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

Вот чем этот код лучше чем:

(defpackage my-package
  (:use cl)
  (:export person name))

(in-package :my-package)

(defclass person ()
  ((name :accessor name)))

(defmethod (setf name) :after (value (person person))
  ...)

?

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

В функциях смысл имеет такое, а вот с методами обобщённых функций большого смысла не вижу.

Смысл в том, что это как раз решает проблему ТС - «огромное, неструктурированное пространство имен», потому что все обобщённые функции имеют префикс класса, тем самым, структурируя пространство имён и делая работу автодополнения внятной Так делают все опытные лисперы (привет Эдмунду Вайтсу). Посмотри на его код, например.

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

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

Не. Про то, что кучу встроенных функций хорошо бы разнести по пакетам. Например acos вынести в math/acos, а row-major-aref в arrays/row-major-aref, sbit в arrays/sbit и т.д.

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

в lisp ключевых слов ещё меньше

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

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

Например, тем, что теперь в пакете my-package могут быть 2 или 10 функций name, которых не видно в автодополнении этого вашего SLIME.

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

В базовом языке нет, но на нем сделали объектную систему

Не совсем так. В CL тоже нет. CLOS там в виде библиотеки. Ну и eieio входит в стандартную поставку emacs-а. Так что теперь это лишь детали реализации.

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

Это то же самое, что задать им префиксы.

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

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

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

Очень убого, только для твоих модулей.

The most important things this file defines is:
An emacs_value opaque type which is used to pass Lisp values to and from Emacs.
An emacs_runtime structure which is used to get an environment pointer.
An emacs_env structure that contains function pointers to the API.
...
You need to build Emacs with module support (it is disabled by default) and you need the emacs_module.h header.
...
Emacs modules must be GPL compatible. To enforce that Emacs checks for the presence of the plugin_is_GPL_compatible symbol before it loads a module.


Здесь лучше, хоть и не из коробки.

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

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

Для галер строгого режима в промышленых реалиазациях включая sbcl есть блокировка паакетов. Паэтому случайно организовать там нестандартный cl:car не получится из-за умолчальной блокировки #<PACKAGE «COMMON-LISP»>. Свои пакеты тоже можно блокировать. Сверху можно повесить надзорный обработчик исключения.

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

Для галер строгого режима в промышленых реалиазациях включая sbcl есть блокировка паакетов

like

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

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

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

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

если имеется класс baz, и его метод bar, то называть этот метод следует как baz-bar, а не просто bar

Угу. А если потом появился наследник baz'а foo, то его новые методы будут foo-*, а унаследованные — baz-*. Как в GTK при работе из Си: методы одного объекта gtk_font_button_set_title, gtk_button_set_label, gtk_bin_get_child, gtk_container_child_get, gtk_widget_child_focus. Обрати внимание, что *child* размазаны по трём разным префиксам. И всё это надо помнить.

Не говоря уже, что писать (sequence-build (sequence-first x) (sequence-rest x)) после двадцатого повторения sequence начинает утомлять и если вдруг решил заменить тип переменной со списка на массив, то приходится исправлять все функции доступа.

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

Видишь костыль - сделай его библиотекой и нет костыля

Это в цитатник. Прямо таки закон развития любых программных систем.

monk ★★★★★
()

методы, которые выясняются по автодополнению и доктипу

Смотрю, программирование вслепую очень популярно.

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

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

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

Смотрю, программирование вслепую очень популярно.

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

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