LINUX.ORG.RU

Трагедия CommonLisp

 ,


0

3

https://esdiscuss.org/topic/the-tragedy-of-the-common-lisp-or-why-large-langu...

Для Ъ не будет.

Кратко суть:

Once a language gets beyond a certain complexity --- say LaTeX, Common Lisp, C++, PL/1, modern Java --- the experience of programming in it is more like carving out a subset of features for one's personal use out of what seems like an infinite sea of features, most of which we become resigned to never learning. Once a language feels infinite, the specific benefits of a new feature are still apparent. But the general costs in added complexity are no longer apparent. They are no longer felt by those discussing the new feature. Infinity + 1 === Infinity. Even aLargeNumber + 1 === approximatelyAsLargeANumber. This is the death of a thousand cuts that causes these monstrosities to grow without bound.


Ответ на: комментарий от Oxdeadbeef

Кстати, есть идея как запилить более быстрые (и более простые) классы. Как в Delphi. Реализуются в виде структур с запасными полями. По заполнении запасных полей добавляется поле «и остальное», к-рое содержит ссылку на вторую структуру и т.п. Статические акссессоры от структур.

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

Для всяких извращений с перекрытием слотов можно использовать defadvice/decorate-function.

Получится в 20-40 раз быстрее CLOS.

А там где этого не хватит - CLOS тоже можно использовать.

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

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

Похоже на https://en.wikipedia.org/wiki/Entity_component_system

Вообще было несколько этих ОО-фрейворков для CL. Можно наверное найти исходные коды и адаптировать, только вероятно пользоваться этим никто не будет :)

Получится в 20-40 раз быстрее CLOS.

Для простых вещей, да. Для сложных — получится недо-CLOS, только кривой.

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

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

Я ожидал ссылку не на термин, хотя и за него спасибо. А на конкретную реализацию OO, где сделано именно так. Впрочем, это не настолько трудоёмко. Может быть, проще запилить, чем искать. Вы решаете не все возможные задачи, ваш опыт не должен меня убеждать. Для меня одна из sale point лиспа, понятная всем, состоит в неоспоримом факте, что он на порядок быстрее питона

http://benchmarksgame.alioth.debian.org/u32/compare.php?lang=sbcl&lang2=p...

Не думаю, что в каком-то из бенчмарков использован CLOS, зато ясно, что везде оптимизация на скорость. Если я всерьёз хочу кого-то убедить перейти с питона на лисп, я должен быть готов сравнивать производительность ООП. Пока что я этого не делал. Но 40-кратная потеря производительности из-за родовых функций намекает на то, что можно и проиграть.

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

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

Даже без всяких измерений, я на 100% процентов уверен, что OO сделанное на CLOS будет быстрее питоньего ОО.

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

Получится в 20-40 раз быстрее CLOS.

ещё есть COS ([http://ldeniau.web.cern.ch/ldeniau/cos.html]страница статья) — на C макросах в духе CLOS.

в статье есть сравнение c Objective C, C++ по быстродействию.

а сам код на COS (на Си) можно и из лиспа кодогенерировать.

anonymous
()

Corman Lisp 3.02+, с открытыми исходниками под оффтоп

потыкал сборку из гитхаба, вполне годный Win32 общелисп с COM Server и примерами COM-автоматизации (или там, DirectX) на общелиспе. из плюсов: defasm и встроенный 32-битный ассемблер, naked функции на лиспе, Ephemeral GC, создание EXE и DLL в полпинка. pdf с описанием рантайма замечательный.

был бы близок к идеальному виндолиспу, кабы, зараза, не падал с CrashDump_Error.Log довольно регулярно.

среда чем-то неуловимо напоминает BlackBox Component Pascal : такое же сиротливое окошко Log , «коммандеры» то есть, выполнение S-выражений правым Enter или Shift-Enter, и настоящий общелисп внутри.

можно грабить корованы. ну или часть «проверенного временем» WinAPI оттуда перетащить в SBCL + COM сервер.

или годный Ephemeral GC, например.

с 64-битностью и кроссплатформой всё очень плохо, конечно же. Роджер Корман как бы выложил его ещё и потому что под новой студией и в WinSxS (32-битной подсистеме в Win64) какие-то трудно уловимые и трудно воспроизводимые глюки случаются. подтверждаю: глюки имеются.

anonymous
()

Трагедия CommonLisp: в том, что никто на нём не пишет

а вот и не надо писать на нём в основном, руками. нужны моделлеры и какая-то CASE автоматизация. скорее, MetaCASE.

BlackBox содержит годный компонентный документно-ориентированный интерфейс. и фреймворки типа MVC и персистентных объектов поверх всего этого и виндо COM, OLE, Compound Document. «замороженных персистентных объектов компонент».

Emacs org-mode babel показывает, в каком направлении нужно двигаться: структура plain text .org документа это по сути Compound Document (потому что можно прицеплять проперти :PROPERTIES: :foo: ... :end: к аутлайну и «блокам кода», «блокам данных»). и она же изоморфна XML DOM или SXML. или S-выражением (берём GNU Skribilo на Guile, читаем reader-ом .org, пишем в S-выражения).

это также среда для метамоделирования (где живут «блоки кода» и «блоки данных»): статическая, времени компиляции (Literate Programming, tangle) или динамическая, сессии интерпретатора (Reproducible Research, live coding). связанных метапеременными «блоков» через код-обёртку на Elisp. в соответствии со структурой метамодели.

осталось эти S-выражения генерировать не руками, а разными моделлерами, рисуя картинки с диаграммами. и заодно обеспечить reversability — из кода в модель, из модели в метамодель (назад; вперёд и сам tangle/org-mode babel export справятся). есть например progdoc, проект WEB-среды из LiterateProgramming : расставляем в сорцах комменты «начало/конец региона», он их сам выцепляет в «блоки кода».

что-то такое ввод можно допилить до ума, и допилить до «уравнения в морфизмах» и «амальгамы» из теории категорий. чтобы изоморфизмы MetaCASE само определяло, и предлагало годные, понятные (=«грамотные») трансформации, морфизмы (см. например откомментированный Д. Кнутом исходник ADVENTURE).

дальше можно развивать в сторону метакомпиляции (проект META II, курс по нему), суперкомпиляции (суперкомпилируемый лисп, ога) или чистого, незамутнённого теорката.

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

Infinity + 1 === Infinity

===

Равно. Точно равно! Мамой клянусь, равно!

а вот и не равно. это кардинальные числа, транфинитные, алеф ноль и выше. нужно построить транзитивное замыкание трансфинитных чисел: когда 1+(1+w)=2+w, но w+1+1=w.

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

Спасибо, но я думаю, что и придуманное мной не вполне нужно. А уж дальнейшее усложнение вообще неведомо зачем :)

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

ООП в BlackBox

ещё вот подумалось, а уж не ООП в Component Pascal (Oberon-2) ли ты предложил. очень похоже на «расширяемые записи» оттуда. там есть полная метаинформация о структуре модулей, стандартный модуль Meta (посредством которого генерируются например GUI формы через механизм «интеракторов»: в модуле описываются экспортированные наружу переменные типа запись/расширяемая запись/объект и «команды», то есть, процедуры без параметров. потом запускается пункт меню «создать форму» — и форма для GUI строится автоматически, по метаинформации).

есть некие параллели с лисп-системами: по спецификации языка от него требуется поддержка «динамической модульности» для загрузки/перезагрузки модулей — метаинформация модулей, загрузчик модулей и сборщик мусора работают совместно в рантайме: любой модуль можно выгрузить если у него нет клиентов, конфликты версий разруливаются через реализацию fingerprinting модулей на основе этой вот метаинформации.

параллели в том, что на REPL похож процесс модульной сборки, тестирования и перезагрузки: исходники пишутся «в ворде» в Compound document — с шрифтами, картинками, вьюшками к другим «замороженным компонентам» или COM-объектам.

вставляется в такой документ после конца модуля «коммандер» ^Q Модуль.Команда параметр1 параметр2 ... параметрN ~ (показываются иконками ^Q, ~  — знак кирпич и нижний такой треугольничек для начала и конца), потом кликаем на ^Q иконке коммандера => модуль загружается, команда вызывается с параметрами.

получается такое быстрое, простое тестирование или livecoding разработка.

в общем, это проще показать, чем рассказывать. BlackBox'у наступил End Of Life, и они отдали (открытые модули с сорцам, без сорцов закрытых, ЕМНИП, только байткод) в сообщество (с более понятной лицензией). официальная последняя версия 1.6, после чего сообщество наплодило свою кучку форков.

из них наиболее свежей является CPC (там же на сайте и «батарейки» — подсистемы). также интересными являются Red, XDev и школьная сборка.

школьная сборка поддерживает ключевые слова и идентификаторы на русском языке (что весьма напоминает 1С, например — только язык Оберон-2 компонентный паскаль). также CPC поддеживает уникод — идентификаторы на русском и греческом (ключевые слова всё ещё английские). уникод в последних 1.6+ поддерживается нормально, в каких-то были проблемы. ещё COM-автоматизацию в каких-то сборках выпилили, в CPC всё нормально.

в общем, если будет время, попробуй потыкай BlackBox сам — ощущения интересные: интерактивная разработка, livecoding, настоящая модульность.

ещё по СУБД: есть интересная технология MUMPS (в чём-то более функциональная, чем SQL) и интересная реализация MiniM. читаю книгу МУМПС СУБД этого автора, тыкаю примеры потихоньку, очень интересно.

не файрбёрдом единым же ;-))) даёшь ZDLL на лиспе вместо хранимок! ж;-))

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

господи, и у этого регистранта 4 звезды

anonymous
()
Ответ на: ООП в BlackBox от anonymous

любой модуль можно выгрузить если у него нет клиентов

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

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

В SBCL самый быстрый доступ к полю класса всего в 1,6 раз медленнее, чем к структуре. Это уже приемлемо. Хотя у структур остаётся ещё одно важное преимущество - их можно свободно печатать и читать, в т.ч. циклические графы из них. Как сделать такое для классов - я не знаю. Даже если наложить ограничения на конструкторы и делать «классы данных», конструкторы которых не имеют побочных эффектов, с печатью циклических графов будут проблемы. Думаю, их нельзя решить без влезания в исходники функции print.

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

да, там всё сводится к нормальному описанию модулей подсистемы на чём-то типа makefile. но поскольку это «вещь в себе», изобретают велосипед вместо makefile: берут список модулей, сортируют топологической сортировкой(1), потом скопом пересобирают(2), перезагружают(3). здесь (1),(2),(3) реализованы внутри BlackBox, как компилятор и StdIntertreper.

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

в итоге модулей в лиспе в понимании «компонтентно-ориентированного программирования», КОП из оберонов нет вообще. взамен них пакеты и monkey patching, когда любой символ может раскрыться во что угодно, т.к. исходное состояние разное и макросы могут быть разные.

а в оберонах по идее и линкер не нужен — у модулей может быть простейший лоадер.

В реальности у существенных модулей всегда есть клиенты и их нельзя перезагружать

ага, нужно как-то описать подсистему из модулей и жизненный цикл (и перезагружать с учётом него).

ссылка >> презентация

где-то там есть сравнение «оснований концепций» (метапарадигм, ога) в программировнии — если коротко, то из значения, не являющиеся first class objects (хрестоматийный пример: переменные-массивы и процедуры в паскале) они становятся first class objects, (и развиваются в типы типов, типы классов и зависимые типы, и далее), и позволяют теперь описать на себе модули (например, в MirageOS на Ocaml модуль это функтор, это по сути, монада).

в итоге, становится необходим сборщик мусора для таких first class objects, а язык движется к метаязыку, и компилятор простой модульный как в оберонах — становится компилятором подмножества («второклассных объектов»), а полноценный компилятор метаязыка («первоклассных объектов») усложняется.

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

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

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

трагедия эльбрусов и Эль-76

не только лисп-машины и потомки чипа SCHEME79 были одними из первых процессоров, ориентированных на поддержку языка высокого (и сверхвысокого уровня). там подробнее — он разбирал свою домашную лисп-машину Symbolics.

с Эль-76 и Эльбрусами случилось всё то же самое.

что вы скажете о процессоре, с поддержкой динамически типизированного языка высокого уровня (автокод), на котором были написаны модульная система, и затем — интегрированы другие, высокоуровневые компиляторы и системы программирования (все с прозрачно заменяемыми библиотеками) ?

в 1976 году? на русском языке? с батарейками («технологический инструментальный пакет», ТИПы)?

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

и всё это БЫЛО — у нас в СССР. на Эльбрусах.

... не говорите мне о дотнетах, как об чём-то новом...

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

а что там с нашими родными советскими лисп-машинами — ну и где оно всё ???

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

в общем, нужно писать бенчи и всё измерять.

но я практически солидарен с предыдущим оратором — что декомпозиция на CLOS объекты получается другая, и на уровне всей системы в целом накладные расходы в декомпозиции CLOS ООП vs. C++ ООП vs. Delphi ООП vs. Oberon-like ООП могут быть и меньше.

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

Я пробовал на дельфи такое сделать.

в D2 что-то подобное есть в докладе на Dconf, Emmanuel как его там, из Remedy, геймдев . они сделали перезагрузку модулями, плагинами и нормальный livecoding на D2.

думаю, что и на дельфи как-то так, не особо сложнее.

anonymous
()
Ответ на: трагедия эльбрусов и Эль-76 от anonymous

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

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

думаю, что и на дельфи как-то так

Да, в дельфи, помимо dll-ей, есть «пакаджи». В которых решены все проблемы динамической подгрузки классов. Но пакадж нельзя перегрузить, если есть экземпляры его объектов в памяти. Всё. Очень быстро я понял, что в реальной жизни этот механизм не работает.

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

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

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

den73 ★★★★★
()

Покойся с миром, Lisp.

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

в духе КОП и модульных систем это не канонично: компоненты в КОП должны зависеть только от интерфейсов, а не друг от друга.

Механизм горячей замены в лиспе, наоборот, вполне жизнеспособен на практике

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

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

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

в книге Пентковского про Эль-76 интересным способом вводятся модули: вводя время жизни модуля, символа, блока. почти как в Rust, только 3 времени жизни: глобальный, локальный, и «как у того блока» (локального ЕМНИП в Rust нет). через это можно поблочно/символьно задать, нужен GC или не нужен.

затем поверх динамической типизации вводится статическая. довольно любопытно.

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

«was the god of hard labor »

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

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

Хорошего бога «поносом» не назовут.

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

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

TomBOY ★★
()
8 сентября 2015 г.

Это тоже не нужно

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