LINUX.ORG.RU
ФорумTalks

Более лучший Лисп

 


3

9

Что бы вы изменили и каким образом в своем любимом/нелюбимом диалекте Лиспа, чтобы он стал ещё лучше? Расскажите обо всех своих грязных фантазиях.

Лиспосрач (и те два унылых анонимуса) не приветствуется.

Перемещено tazhate из development

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

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

Я тоже про это слышал, но практически нигде не видел, что бы этим в самом деле руководствовались. Во всяком случае, в open-source, так практически не пишут.

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

макромагию

наркомагия. Звучит, да.

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

да, и хотелки: компиляция в LLVM, нормальная система модулей, подсистемы.

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

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

[typed] racket больше всего похожа на то, что ты описываешь.

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

А что такое коммандеры? Можно в двух словах?

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

в SLIME можно вывалиться в рестарт, переписать одну функцию, продолжить с того же места.

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

да, REPL гибче и гранулярнее.

отладчика нет by design

ещё там нет исключений.

в общем-то, если довести вот это до «Edit & continue», уже может быть годно.

с русским синтаксисом выглядит чумово, да

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

Да, аноним, я тоже. Вот обдумываю как это лучше сделать.

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

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

Как бы DSL должен упрощать разработку, а получается наоборот?

В любом случае неубедительно. Предположение что-то где-то в глубинах NASA или ещё где сидят настоящие лисперы и решают все задачи через DSL, а в open-source мы видим только подобие «настоящего лиспа» сомнительно (помимо прочего, из NASA, как известно, лисп прогнали с большим скандалом).

Кроме того, активное применение макросов вообще, ну и DSL в частности, входит в противоречие с интерактивной разработкой - после каждого изменения макроса необходимо перекомпилировать весь код, его использующий, часто проще всего грохнуть fasl-файлы и перегрузить систему, но это долго.

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

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

Есть изоморфизм (<f, t, and, or> это коммутативное полукольцо). То есть вопрос в том как ты понимаешь type equality

test :: Either Int String -> IO ()
x :: Either String Int

test x --- выдаст ошибку

Кстати про статическую типизацию и type inference:

Prelude> let test = either (+ 5) length
Prelude> test (Left 3)
8
Prelude> let y = Left 3
Prelude> test y

<interactive>:45:6:
    Couldn't match expected type `Int' with actual type `Integer'
    Expected type: Either Int [a0]
      Actual type: Either Integer b0
    In the first argument of `test', namely `y'
    In the expression: test y

Это разве нормально? Уж лучше как в SBCL. Иногда предупреждает, но не требует аннотировать каждую строчку

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

Как бы DSL должен упрощать разработку, а получается наоборот?

DSL надо тщательней продумывать. Хотя бывают и хорошие примеры: cl-annot, clack, caveman, lisp-interface-library. Сплошные DSL и, что характерно, OpenSource. Кстати hu.dwim.* ведь тоже сплошной DSL. Разработку им упростил. А тебе чтение усложнил.

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

use xcvb, Luke

идиома «для каждой задачи свой язык» это либо миф, либо так часто писали в древности

Посмотри Practical Common Lisp. Там в конце как раз несколько DSL демонстрируется и их эффективное использование.

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

не люблю с тобой пререкаться, но иногда это напоминает зубную боль: к врачу идти таки надо ;)

Как бы DSL должен упрощать разработку, а получается наоборот?

ВСЕГДА получается наоборот? И у кого получается? У ВСЕХ?

из NASA, как известно, лисп прогнали с большим скандалом

Не известно. Где почитать?

Кроме того, активное применение макросов вообще, ну и DSL в частности, входит в противоречие с интерактивной разработкой - после каждого изменения макроса необходимо перекомпилировать весь код, его использующий, часто проще всего грохнуть fasl-файлы и перегрузить систему, но это долго.

Это напоминает «содомию» с недописанными/неотлаженными библиотеками (для CL других разве нет?) и/или чьё-то неуёмное желание «здесь и сейчас» подстроить библиотеку под себя, причём не через «враппер», а именно расхерачить «форк» в пух и прах - имхо не самая лучшая практика. Хотел спросить - «loop на каждый чих не переписываешь?», но вспомнил про iter... Ладно, твоя практика (имеющая полное право на существование) плохо уживается с «нестабильными» макросами - согласен.

идиома «для каждой задачи свой язык» это миф

Для КАЖДОЙ задачи - миф, бесспорно. Но там где «свой язык» действительно упрощает разработку (да, можете меня пристрелить, но loop меня вполне устраивает, пока не возникает вопрос о его «расширении») - eDSL имеет полное право на жизнь. Что значит «упрощает разработку»? По мне - обеспечивает более лаконичную и более понятную запись для специалиста в domain-области.

Спорно? Конечно! Но не более, чем собственные if-ы с then/else и схемерские ритуальные пляски с бубном по имени «анафорики».

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

Хотя бывают и хорошие примеры: cl-annot, clack, caveman

Ну да, «с помощью read-макросов превратим лисп в python», отличные примеры. Только в таком случае проще уж сразу на python писать.

Кстати hu.dwim.* ведь тоже сплошной DSL. Разработку
им упростил. А тебе чтение усложнил.

Что же они свой сайт не могут в адекватном состоянии поддерживать?

use xcvb

Ага, окончательное убийство интерактивной разработки.

Посмотри Practical Common Lisp. Там в конце как раз несколько
DSL демонстрируется и их эффективное использование.

Каких? Если говорить про разрбор бинарных форматов, то когда писал mongo-cl-driver пытался использовать такой подход, но довольно быстро от него отказался и переделал на основе MOP - как раз из-за упрощения разработки и отсутствия необходимости перекомпиляции кода посла изменения макросов. Генерация html это вообще смех. В CL имеется не меньше сотни разнообразных eDSL-библиотек для генерации html. Я никогда не мог понять, зачем они их пишут. Если использовать такой подход для генерации реальных веб-страниц, то это полный мрак, огромные полотна кода смешанные с логикой, так я тоже пробовал делать.

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

помимо прочего, из NASA, как известно, лисп прогнали с большим скандалом

Можно поподробнее?

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

Не очень понятно как это могло стать причиной смерти лиспа, ведь лисп не заставляет писать именно в этом стиле. И по вашим же словам на нем так практически никто и не пишет.

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

Это напоминает «содомию» с недописанными/неотлаженными библиотеками
(для CL других разве нет?) и/или чьё-то неуёмное желание «здесь и
сейчас» подстроить библиотеку под себя, причём не через «враппер», а
именно расхерачить «форк» в пух и прах - имхо не самая лучшая
практика. Хотел спросить - «loop на каждый чих не переписываешь?», но
вспомнил про iter... Ладно, твоя практика (имеющая полное право на
существование) плохо уживается с «нестабильными» макросами - согласен.

Я так понял, вы на что-то намекаете, только не понял на что.

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

Не очень понятно как это могло стать причиной смерти лиспа,
ведь лисп не заставляет писать именно в этом стиле.

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

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

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

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

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

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

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

Ну возьмём даже твой код:

DSL cl-routes:define-route вместо канонического (push *dispatch-table* ...) или процедурного (defclass ....) (set-route .... )

restas:define-module вместо defpackage.

И при этом любой код, который не твой, но активно переопределеяет синтаксис подвергается с твоей стороны крайне жёсткой критике.

Каких? Если говорить про разрбор бинарных форматов, то когда писал mongo-cl-driver пытался использовать такой подход, но довольно быстро от него отказался и переделал на основе MOP - как раз из-за упрощения разработки и отсутствия необходимости перекомпиляции кода посла изменения макросов.

Каких макросов? cl-dbf целиком написан на com.gigamonkeys.binary-data и единственный макрос там with-db, являющийся уточнённым with-open-file.

Если использовать такой подход для генерации реальных веб-страниц, то это полный мрак, огромные полотна кода смешанные с логикой

Ты смотрел weblocks? Там на html-edsl реализованы виджеты, а на виджетах страница. Никаких «полотен кода» не видно. Или для тебя единственно верным решением является писать шаблоны на урезаном ущёрбном языке шаблонов, а в бэкенде только заполнять переменный?

Ну да, «с помощью read-макросов превратим лисп в python»

Если данную задачу легче писать на питоне, то почему нет? Вся мощь CL ведь остаётся. А ты предпочитаешь писать на CL как на Java: вот best practices, шаг влево, шаг вправо — расстрел?

use xcvb

Ага, окончательное убийство интерактивной разработки.

?! man xcvbd:bnl Или что ты имеешь виду?

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

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

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

Покажи такой код. Описываешь, словно тебя в детстве поймали маньяки и заставили сопровождать код на CL с активным использованием DSL....

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

просто данные индуктивно так устроены, что в Tree[A] всегда будут только A, это известно до запуска программы

Есть вот такое : https://github.com/sellout/quid-pro-quo

Позволяет использовать контракты, в частности форсить требования на типы слотов.

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

Как в терминах системы типов описать plist? Если использовать только гомогенные контейнеры, то половины типовых конструкций CL становится невозможной начиная с defmacro. Какой тип у body? Дикий матан на http://docs.scala-lang.org/overviews/macros/overview.html как бы намекает...

Он проверяет, но это именно стилистические предупреждения.

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

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

Ты, ламерочек, Лисп так и не освоил.

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

cl-routes:define-route
вместо канонического (push *dispatch-table* ...)

Во-первых, restas:define-route, во-вторых работает оно не так. В-третьих, это можно было бы оформить функцией (кстати, время от времени порываюсь такую написать), но при использовании её в коде из-за синтаксических особенностей лиспа это выглядело бы ужасно. Т.е. основной лейтмотив - эстетический, поэтому это не DSL, а просто синтаксический сахар.

cl-dbf целиком написан на com.gigamonkeys.binary-data


Речь о стоимости разработки и отладки самой com.gigamonkeys.binary-data.

Ты смотрел weblocks? Там на html-edsl реализованы виджеты,
а на виджетах страница.

Да. А ты смотрел вёрстку, которую делают верстальщики? Теперь попробуй запихнуть её в виджеты с помощью html-edsl. Что будет с кодом и кто это будет делать?

Так что,

Или для тебя единственно верным решением является писать
шаблоны на урезаном ущёрбном языке шаблонов, а в бэкенде
только заполнять переменный?

Это не то, что бы единственно верный, но чуть ли не единственный работающий на практике подход.

А ты предпочитаешь писать на CL как на Java: вот best
practices, шаг влево, шаг вправо — расстрел?

Так не только в Java. Это просто хороший принцип, позволяющий поддерживать код в контролируемом состоянии когда над проектом работает несколько разработчиков.

man xcvbd:bnl Или что ты имеешь виду?

Судя по описанию, это будет ещё дольше, чем перезагрузить систему. Но я пользуюсь xcvb, не могу проверить. Да и никто не пользуется, насколько видно в интернете. Только в ITA (теперь в Google).

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

Зачем нужен лисп, если не использовать макросы?

Макросы всего лишь один из инструментов. В CL много чего полезного. Но основные преимущество связанны с интерактивной разработке.

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

Речь о стоимости разработки и отладки самой com.gigamonkeys.binary-data.

Хм. А есть аналог не DSL? В cl-mongo-db ты, фактически, сделал парсинг вручную через defmethod.

Если брать другие языки, то хочешь сказать, что binary-data существенно сложнее в разработке/отладке, чем, например, http://preon.codehaus.org/ (аналогичная штука для Java). Хотя preon тоже dsl, там ведь аннотации на полях класса? Тогда как должна выглядеть библиотека для доступа к бинарным данным (в смысле, API)? Или каждый должен велосипедить собственный парсер на обобщённых фукциях?

Да. А ты смотрел вёрстку, которую делают верстальщики? Теперь попробуй запихнуть её в виджеты с помощью html-edsl.

Код виджета небольшой. На 90% состоит из параметров, получаемых из программы. Если есть пример (mock up), то программисту нет разницы, что размещать 30 параметров на 100 строк, что те же 100 строк внести в генератор на CL. Даже генератор проще, потому как язык полный и все функции стандартны, а не приходится вспоминать, как двумерный массив plist'ов в html table разложить, если цвет ячейки зависит от отношения значений в соседних ячейках.

Собственно, вопрос аналогичен тому, что вот в фотошопе окно красивое нарисовали, давайте код виджетов Gtk/Qt из картинок генерить, а то ведь на C/C++ команды рисования надо: «Что будет с кодом и кто это будет делать?».

не то, что бы единственно верный, но чуть ли не единственный работающий на практике подход

PHP-программисты с тобой не согласны. А практика web-программирования, в основном, у них.

Да и никто не пользуется, насколько видно в интернете.

~/quicklisp/dists/quicklisp/software$ find | grep xcvb | grep -v xcvb-0.596
./asdf-utils-20121125-git/build.xcvb
./fare-memoization-20120811-git/build.xcvb
./asdf-utils-20121223-git/build.xcvb
./fare-utils-20121125-git/build.xcvb
./fare-utils-20121125-git/test/build.xcvb
./rfc2388-20121013-git/build.xcvb
./cl+ssl-20121223-git/build.xcvb
./lisp-interface-library-20121125-git/build.xcvb
./fare-quasiquote-20121125-git/build.xcvb

Это при том, что у меня всего 79 пакетов, а всего их в quicklisp 1988.

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

В CL много чего полезного. Но основные преимущество связанны с интерактивной разработке.

То есть, smalltalk в котором есть REPL (http://www.squeak.org/Features/Development/), подсветка ошибочного кода и проверка кода на читабельность (http://wiki.squeak.org/squeak/3114) тебе бы подошёл ещё больше?

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

это я уже слышал. чем repl питона хуже, чем sbcl?

Проблема в том, что для Python нет SLIME. И не может быть (хотя тут какой-то anonymous на днях утверждал обратное), ибо в Python пакетная система завязана на структуру файловой системы, а классы «закрытые» (в отличие от Ruby, для которого говорят реализовали swank). Вот и получается, что возможности REPL в Python очень ограниченны (но и такие возможности часто очень полезны). Перечислять все возможности SLIME я не буду.

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

Или для тебя единственно верным решением является писать шаблоны на урезаном ущёрбном языке шаблонов, а в бэкенде только заполнять переменный?

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

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

То есть, smalltalk в котором есть REPL
тебе бы подошёл ещё больше?

Там объектная система основана на модели отправки сообщений. Мне больше нравится CLOS. Что у него со скоростью? Там помню была какая-то дикая система работы в образе, без возможности использования нормальных систем контроля версий. В общем, я мало что знаю о smalltalk, но то, что слышал, не очень впечатлило.

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

Ты когда-нибудь пробовал рассказать про скобки верстальщику?

Зачем верстальшику скобки? Ты ведь не рассказываешь дизайнеру про GObject. Каждый занимается своей работрй: верстальщик делает макет (mockup) — программист из него делает шаблон.

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

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

Ну не более дикая, чем на Java. Текстовой представление получить можно. Значит можно и в обычный CVS запихнуть. А так, там встроенная пообъектная система контроля версий.

Что у него со скоростью?

Медленней, чем Perl, но быстрей чем Ruby.

Есть вот такой: http://strongtalk.org/index.html . Быстрей чем Perl, медленней, чем Java.

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

И что оно может? Насколько я понял из кода, в лучшем случае там есть интепретатор, работающий через SLIME. Но это в лучшем случае. Т.е. возможностей не больше, чем даёт M-x run-python. Ну, можно инспектор прикрутить, если постараться.

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

Медленней, чем Perl, но быстрей чем Ruby.

Спасибо, не интересно.

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

The variable K is unbound.

Знать место ошибки с точностью до конструкции цикла - очень мило. А точнее? Где конкретное место внутри iterate?

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

что переопределять и почему дорого?

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

Основной вопрос для перехода с Дельфи на BBCP - это библиотеки. Например,не думаю, что существует FastReport для него или FIBPlus. И не уверен, что он так же красиво позволяет вызывать сервера OLE автоматизации. Все три вещи мне строго необходимы, т.к. речь идёт о существующем большом проекте.Видимо,всё останется как есть,хотя в будущем надо будет посмотреть более внимательно на этот BBCP.

обычного отладчика там нет by design

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

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

тут же, модуль перегружается целиком

Ну вообще, вопрос в том, что содержится в этом модуле.

ещё там нет исключений

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

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

Про то что or в структуры нужно оборачивать

Прагматичное решение для лиспа - представить тип (or number string) типом t, и оставить проверку соответствия типов при передаче параметров в compile-time и/или runtime. Т.е. это боксинг, но не частный, а сразу общий. Потерь от этого будет в каких-то случаях больше, чем от частного, в каких-то - нет. Меня бы устроило.

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

Зарегистрируйся, пожалуйста, тот анонимус, который про 1С.

дебаггер там настолько идиотский

Но в CL такого нет. В CL есть другое, но пошаговой отладки нет.

Плюс возможность определять синтаксис поверх s-expr.

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

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

дебаггер там настолько идиотский, что проще написать свой

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

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

выдаст ошибку

Нужно начать с того, что в интенсиональной Теории Типов про эти два типа нельзя ничего сказать - ни того что они «равны», ни того что они «не равны». Интенсионально можно сказать только A == A. Но экстенсионально они равны, так как аксиома экстенсиональности заключается, в том числе, в том, что _если_ между типами A и B существует биекция A <=> B = f : A -> B and g : B -> A, такая, что forall (x : A). g (f x) == x and forall (y : B). f (g y) == y, _то_ между A и B существует path/населённый identity type, то есть A == B.

Это значит, что

  1. test (runtimeSwap x), где runtimeSwap это та биекция:
    runtimeSwap :: Either a b -> Either b a
    runtimeSwap (Left x) = Right x
    runtimeSwap (Right x) = Left x
    

    Это случай Haskell/GHC.

  2. test (safeCompileCast x) при условии, что forall (x :: Either a b). unsafeCoerce (unsafeCoerce x :: Either b a) :: Either a b == x (у GHC не так).
  3. test x если (2) и язык умеет подтипы (как Scala, но там не (2)), так что A == B => A <: B and B <: A.

«<f, t, and, or> это коммутативное полукольцо» как раз означает существование биекций для коммутантов структур и объединений, так что всегда существует такой способ компиляции (с упорядочиванием по нумералам типов (типа Gödel numbering)), что структуры (a and b) и (b and a) и объединения (a or b) и (b or a) и т.п. будут неразличимы как память и твой пример будет ожидаемо работать (неявно как test x или явно как test (safeCompileCast x)). То что в си (по стандарту) или в Haskell/GHC не так не означает что это вообще не так и типы не равны.

Это разве нормально?

http://hackage.haskell.org/trac/ghc/ticket/7061

Prelude> default (Int)
Prelude> let test = either (+ 5) length
Prelude> test (Left 3)
8
Prelude> let y = Left 3
Prelude> test y
8
quasimoto ★★★★
()
Ответ на: комментарий от quasimoto
  • Явное или нет подтипирование с рантайм апкастами тоже подойдёт:
    {-# LANGUAGE TypeOperators, MultiParamTypeClasses  #-}
    
    class a <: b where
      up :: a -> b
    
    ($>) :: (a <: c) => (c -> b) -> a -> b
    ($>) f = f . up
    
    -- instance a <: b where
    --   up = id
    -- 
    -- ($) :: (a -> b) -> a -> b
    -- ($) = ($>)
    
    instance Either a b <: Either b a where
      up (Left x)  = Right x
      up (Right x) = Left x
    
    test :: Either Int String -> IO ()
    test = either (print . (+ 1)) (putStrLn . (++ "..."))
    
    testTest :: IO ()
    testTest = do
      let x :: Either String Int
          x = Left "!!!"
      -- test $ x
      test $> x
    
quasimoto ★★★★
()
Последнее исправление: quasimoto (всего исправлений: 1)
Ответ на: комментарий от monk

Позволяет использовать контракты, в частности форсить требования на типы слотов.

В рантайме (там пример с «all args < 10» на это намекает)? Тогда это просто интеллектуальная форма делать assert (типа QuickCheck).

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

Оно возможно, просто

Дикий матан на ... как бы намекает...

...

Как в терминах системы типов описать plist?

Мы же это уже обсудили. Как trait расширяющий базовый конкретный класс, то есть как конкретный тип + сторонний интерфейс (то что ты называл «протокол»).

Гораздо хуже, когда приходится бороться с системой типов для решения чего-нибудь типового

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

те же гетерогенные списки или массивы в Haskell

В Haskell - да, а вот в Scala уже ни чо - через Any.

quasimoto ★★★★
()
Последнее исправление: quasimoto (всего исправлений: 2)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.