Pull to refresh

Comments 47

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

В добавление к перечисленному вами софту можно добавить Stalin - https://github.com/barak/stalin - компилятор Scheme R5, производящий агрессивную оптимизацию всей программы.

Тем не менее, возникает вопрос - вот есть полигоны для отработки "ИТ апокалипсиса": демосцена и микроконтроллеры, почему там LISP не используется? Ну кроме как В. Луговским.

Помимо тяжёлого Хаскеля есть лёгкая версия того же - Clean (clean.cs.ru.nl), к сожалению, там нет поддержки многопоточности. И альтернативная ветка статически типизированных фунциональных языков - ML значительно легче, чем Haskell.

На Хабре была статья об использовании LISP в микроконтроллерах для программирования умного дома: https://habr.com/ru/post/513128 С Clean и ML я сам, к сожалению, дела не имел, поэтому ничего о них не могу достоверно сказать.

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

Naughty Dog такая стратегия в разработке Crash Bandicoot и Jak and Daxter помогла выжать из спецпроцессоров Play Station удивительный по тем временам результат. Язык назывался GOAL, это был, если можно так сказать, структурированный ассемблер.

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

Для Форт (Forth) ещё проще сделать реализацию языка и он достаточно активно представлен в нише программирования контpоллеров и не только.

Да, но на Forth систему компьютерной алгебры написать будет сложновато. Интересно, были ли попытки?

Не знаю, но вроде, на DSSP (ДССП — диалоговая система структурного программирования) были и такие разработки хотя это и не Форт язык.

А, почему сложно, если с Форт можно сделать любой уровень DSL языка?
тот же RPL язык программиования использован в HP калькуляторах.

P.S. А, рассматривался ли в Лисп сообществе конкатенативный язык Factor включающий и парадигму функционального программирования?
Здесь на форуме dxdy.ru есть некоторый топик по нему объясняющий некоторые моменты Язык Factor
Интересны, к примеру, механики реализации алгоритма быстрой сортировки сделанного в рамках Factor языка.

Rosetta Code: Popular Programming Languages
Factor на 23-ем месте в таком рейтинге решённых задач с ресурса.

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

Как прикладного математика меня интересует возможность работы со сложными математическими объектами. Как в Forth могут выглядеть примеры кода, например, из книги Functional Differential Geometry?

Как системного программиста, которому приходится работать с размазанными по ЦОДам распределёнными системами, меня интересует, во-первых, реализация в Forth аналога конструкции cond - это выбор варианта по условиям, которые могут быть весьма нетривальными. И, во-вторых, реализация вызовов с текущим продолжением (call-with-current-continuation), которые для меня являются прямо таки спасением в программировании сложных реакций программы на внешние события. Как это всё выглядит в Forth?

Мне сложно ответить полноценно на заданный Вами вопрос т.к. несколько далёк от темы математических вычислений.
На Хабр была такая статья Численный FORTH
к тому же и тот же PostScript тоже стековый язык и по нему есть изданные книги по его использованию в вычислительных задачах.

Под Форт много чего есть, как The Forth Scientific Library Project
Forth Foundation Library

страница профессора J. V. Noble использовал Форт в разных прикладных вычислениях.

P.S. В Форт возможно моделирование на уровне языка любых хотелок, но, конечно же, это требует некоторого самостоятельного труда, если штатных возможностей языка или той или иной своей или стоонней Форт системы недостаточно.

ЛЕО БРОУДИ СПОСОБ МЫШЛЕНИЯ — ФОРТ ЯЗЫК И ФИЛОСОФИЯ ДЛЯ РЕШЕНИЯ ЗАДАЧ

Л. Броуди: НАЧАЛЬНЫЙ КУРС ПРОГРАММИРОВАНИЯ НА ЯЗЫКЕ
ФОРТ
(книга, конечно, немного устаревшая за неимением выпущенных книг по Форт современных реалий, но основы языка проясняет.) сейчас, конечно, боле-менее в основе разных Форт систем присутствует линия идей стандарта 94года.

Универсальный DSL. Возможно ли это?

P.S. И, конечно же книга советских времён по основам Форт
С.Н.БАРАНОВ Н.Р. НОЗДРУНОВ ЯЗЫК ФОРТ И ЕГО РЕАЛИЗАЦИИ
(если бы не лихолетье 90-х годов, то возможно Форт не был бы забыт и более широко использовался и в России в разных цепочках и продуктах IT)

Некоторая ретроспективная подборка книг FORTH (Computer program language)

Картинка с рускоязычного форума пользователей Форт языка
image

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

Интересно, а почему был выбран Factor и какого плана была обнаружена ошибка в языке?

У меня есть программа на C++ для геометрических построений. Хотел написать к ней маленький пруфчекер (проверяльщик доказательств). Если мы строим, допустим, фигуру с какими-то свойствами, на каждом шаге ссылаясь на аксиому или ранее доказанную теорему, он проверяет, нет ли ошибок в построении. Нужен функциональный язык (писать пруфчекеры на C++ плохая затея), на котором можно хорошо рисовать. Выбирал между Скалой, Окамлом и Фактором. Ошибку нашёл в команде map-reduce. Если дан список, допустим, чисел и мы хотим найти сумму квадратов всех чисел (или не квадратов, а синусов, или не сумму, а произведение), мы применяем map-reduce, указывая в качестве аргументов список и две функции (возведение в квадрат и сложение, синус и умножение и т.д.) Эта команда работала неверно, я сообщил об ошибке, потом сам нашёл, почему (разобрался в её определении а Факторе), исправили

https://www.blogger.com/comment.g?blogID=8513438391157777465&postID=8680112867593321902&bpli=1&pli=1

А что скобки? Даже Visual Studio поддерживает paredit mode

Ну просто в комментах к любой статье про Lisp есть какой-то из мемов про скобки. Я просто исправил недопущение тут))))

P.S. SBCL это классно, но почему не рассмотрена тема создания Lisp-интерпретаторов под распространенные VM? А именно тема Clojure? На нем, к слову, написана Metabase и не только. Просто низкоуровневое эффективное программирование и лимит в 3.5 Мб это одна область. Но JVM это просто другая область, там не нужны производительность и размер, там нужна хорошо знакомая всем виртуальная машина.

Я не стал писать о Clojure, потому что он опирается не только на JVM, но и на всю экосистему Java, используя довольно много библиотек. Я попытался найти компактные реализации JVM, на которых запустился бы Clojure. Но ничего у меня не получилось. Был бы полезно узнать о таких возможностях, если они существуют.

Так в том и суть, что Clojure позволяет использовать всю мощь экосисиемы Java - десятки тысяч человеко-часов работы программистов, сотни библиотек на все случаи жизни и т.д. Взять тот же JDBC - любая современная хранилка данных имеет свой JDBC-драйвер. А в SBCL все уже не так радужно... И JDBC это лишь малый кусочек.

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

Ну SBCL тоже не в РФ развивают. Все самим с нуля не написать, тут уж без вариантов. Вся эта экосистема - это Open Source и SBCL его часть.

Да. Но open source тоже могут отрезать. Даже если создать полную копию всего, эта копия будет мёртвым грузом. SBCL же относительно компактный проект, который можно поддерживать малыми силами. Я не сторонник того, чтобы всё бросить и писать только на Lisp-ах, но в стратегию выживания it-отрасли имеет смысл включить Lisp-системы.

С OSS проблема не в отрезании, а в том, что это же заготовка. Если железо сильно деградирует в производительности, то сложные программы придётся очень серьёзно оптимизировать без возможности влить в upstream.

Спасибо за статью

Что скажете насчет Clojure для прикладного программирования?

Clojure подобен Лисп на JVM, что позволяет использовать на Лиспе все библиотеки для Джавы.

Clojure - отличный инструмент. Мне нравится. И не только мне. Насколько я знаю, его использует AMD для автоматизации дизайна процессоров. Но нужно помнить о том, что Clojure зависит от большой экосистемы JVM. Если по каким-то причинам она окажется недоступной, поддерживать и развивать Clojure будет трудно.

К сожалению, снова повторяется ситуация типа "каждый кулик своё болото хвалит".

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

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

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

Я не говорил здесь о том, какой язык лучше, а какой хуже, потому что для этого сначала надо ввести порядок на свойствах языков. Порядок будет субъективным и частичным, и ничего из этой затеи не выйдет. Поэтому я говорю о трудоёмкости достижения определённой функциональности при программировании на том или ином языке. Относительно объективное представление об этом может дать история it. Эта трудоёмкость важна в случае потери доступа к готовым решениям, чтобы эти готовые решения можно было достаточно быстро запрограммировать.

Означает ли это, что Lisp - это лучший язык программирования из возможных? Нет, конечно.

Трудоёмкость = К / У, где У - уровень повторного использования. Уровень же в основном определяется имеющимися в наличии компонентами. Если язык имеет развитое сообщество с открытым кодом, то с компонентами, даже при наличии санкций, проблем не будет. Поэтому предложенную вами трудоёмкость вполне можно сравнить в одинаковых терминах, например по статистике имеющихся компонентов с открытым кодом. Подозреваю, что у лиспа такая статистика сильно хуже, чем у си-подобных языков.

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

Давайте попробуем честно признать - вам нравится лисп и его инфраструктура, а потому вы и предлагаете его. Всё остальное - попытка оправдать то, что нравится. И я даже за такие попытки, но только если честно признаётся, что ниша на рынке уже занята и реалистичных путей её заполучить, в общем-то, не видно. Соответственно, я за статьи, где указывается на какие-то плюсы языка и инфраструктуры в сравнении со всем остальным. Предлагать же решания для запущенных политических проблем на основе того, что нравится - чистая субъективщина.

Прямо во вводном абзаце сказано, что я - любитель Lisp, и состою в соответствующем сообществе. Признаю, что мне нравится Scheme и его инфраструктура. Но язык мне нравится не просто так, а за то, что я могу быстро и эффективно решать сложные сетевые задачи, которые требовали гораздо больше времени при решении их на Go, Bash, C, NodeJS. Динамические контексты и вызовы с продолжением - отличные инструменты для работы со сложными потоками управления. Я бы, наверное, сравнил работу на Scheme по продуктивности с работой на Python, только код в результате получается существенно более компактным и эффективным.

У того, что мне нравится Scheme, есть причины. Согласен, это субъективный взгляд. Но, ведь, есть и объективные факты. Lisp-машины действительно существовали, и действительно на них был достигнут высокий уровень развития ПО. Компиляторы Lisp действительно проще, чем компиляторы многих других промышленных языков программирования, но достаточно эффективны при этом. На Lisp действительно писали и пишут сложные системы...

И, мне кажется, Вы ошибаетесь в оценке уровня развитости Lisp-экосистем. Например, Guile Scheme в своей стандартной сборке (без внешних зависимостей) содержит уйму библиотечных функций почти на все случаи жизни. Мне в работе пока не пришлось прибегать ко внешним зависимостям. Код действительно более компактный (за счёт особенностей языка и его системы времени исполнения), в небольшую по размерам сборку умещается уйма функциональности.

Впрочем, Вы правы, нужно показывать на конкретных примерах. Займусь по возможности.

Лучше отделять идеологические соображения от практических. Идеологически лисп хорош, я не спорю. Было бы время им долго позаниматься, наверняка он и мне бы понравился (это мысль на основе краткого знакомства).

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

По библиотекам. Простой пример - пробегитесь по всему циклу создания сайта в интернете. Сколь полна поддержка генерации клиентского html? На сколько генерация поддерживается в IDE? Да даже на сколько удобна IDE для самого лиспа? Просто поддержка со стороны IDE - это очень большая тема, в неё вложено очень много труда, может ли экосистема лиспа похвастаться теми же удобствами? А если ещё начнём разговаривать о доступе к БД? Что там с ORM? Банально драйвера под большинство БД есть? Дальше посмотрите на веб сервисы и разного рода очереди - как у лиспа взаимодействие с подобными системами?

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

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

int n;

try { n=Integer.parseInt(intAsString); }

catch (NumberFormatException e) { return false; }

int a=n*b;

...

Здесь задача кратко выразить мысль о том, что невалидный текст вызывает выход с негативным результатом, а если текст валидный - продолжаем выполнение метода. Как видите, вместо одной строки получилось 4. А сколько будет на лиспе? Но имеются в виду стандартные библиотеки, а не целенаправленное усилие специально для сокращения количества строк.

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

Аналог call-with-current-continuation можно соорудить на Си или Си++. Мне приходилось этим заниматься, но ничего приятного и простого в этом нет: необходимо переключать стеки на низком уровне. Не уверен, что такое можно провернуть в managed языках. Аналоги dynamic-wind мне не знакомы. Больше всего это похоже на окружения процессов UNIX только с перехватом выхода и выхода из них. Что позволяет писать, например, так:

(define hi
  (with-mutex (make-mutex)
    (lambda ()
      (display "acquired!\n"))))

Всякий раз при вызове hi будет происходить автоматический захват мьютекса. Можно ли на Си такое вручную сделать? Можно. Но на Lisp быстрее и удобнее.

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

(and-let* ((n (string->number intAsString))
           (a (* n b)))
  ...
  )

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

Близкий аналог есть в JavaScript в виде конструкции async await. В Java в процессе доводки (то есть уже доступен, но пока не считается частью спецификации) находится Project Loom, где используются так называемые "виртуальные" потоки, которые по сути есть как раз надстройка над переключателем стеков.

Передать же куда-то продолжение операции в виде лямбды (которая есть упрощение передачи объекта) можно в большинстве си-подобных языков.

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

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

Я же думал, что можно получить что-то вроде такого:

int n=Integer.parseIntOrExit(intAsString,false);

Здесь предполагается использование некой не реализованной конструкции языка, которая позволяет выполнить return argument; в случае невыполнения какого-то заданного критерия. А значение для argument здесь передаётся как второй параметр. В некотором смысле это потенциально возможный альтернативный вариант обработки исключений.

(and-let* ((var exp)...) body...)

вычисляет последовательно значения выражений exp, и присваивает результаты переменным var. Если на каком-то шаге exp возвращает false, то and-let* возвращает false. Если false не встретилось, то выполнение доходит до body, и результатом будет результат вычисления body.

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

(call-with-current-continuation
  (lambda (k)
    (let ((n (string->number intAsString)))
      (unless n (k false))
      ...
      )))

(call-with-current-continuation fn), в некотором смысле, создаёт точку возврата (некий аналог setjmp из POSIX), и передаёт её аргументом в fn, в нашем случае это параметр k. При вызове (k value), value становится результатом в этой точки возврата.

Можно так объяснить, наверное, да простят меня спецы по Lisp.

Контекст, который передаётся через объекты, - это аналог замыканий в Lisp, то есть, контекстов, в которых живут процедуры (функции). Динамические контексты обладают большей функциональностью, они отслеживают входы в них и выходы из них. Это позволяет гибко управлять захватом и освобождением ресурсов.

Наверное, в других языках нечто такое когда-нибудь да сделают. Но в Lisp-ах это уже есть лет 30 как. А Lisp-ы ещё и развиваются. Появляются новые интересные выразительные техники программирования. Ждать ещё 30 лет, когда они попадут в другие языки?

Promises, кстати, тоже давно появились (под именем futures) в Lisp-ах. Годах, кажется, в 90-ых. И это просто библиотека, не требующая менять ядро языка.

Спасибо за пояснения. Как я понял, and-let, это аналог следующего:

if (!expression1 || !expression2 || !expression3 ...) return result;

Здесь expression может выполнять присваивание примерно так: (null!=(var=getValue(...)))

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

Отсюда следует, что предлагать альтернативное поведение по аналогии с лиспом для сильнее типизированного языка - неправильно. Так нарушается принцип типизации. А без нарушения типизации, видимо, как вы и указали выше, получится более громоздкое решение.

Ошибки типизации возникают на практике редко и вылавливаются быстро. Было даже статистическое исследование исходников на GitHub, которое показало, что от типизированности языка количество багов почти не зависит. Оно зависит только от количества строк кода. Чем меньше пишем, тем меньше ошибаемя. Самым "безошибочным" языком в этом исследовании оказался Clojure, в котором динамическая типизация.

Ну, и динамическая типизация даёт больше возможностей. Например, сложно написать систему символьной алгебры на статически типизированнои языке: у вас должна в арифметике быть смесь из чисел, векторов, функций, символов, операторов и т.д. Придётся сначала написать интерпретатор бестипового исчисления. В языках с динамической типизацией: Julia, Python, Lisp - такой проблемы нет. У статической типизации есть свои плюсы, но и у динамической типизации они есть.

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

and-let* работает не совсем так, потому что определяет новые переменные с локальной для and-let* областью видимости.

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

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

В Lisp довольно легко. Можно поставить трассировку на обращение к полю структуры, и наблюдать процесс доступов вживую. Это не то же самое, конечно.

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

Вынужден с вами не согласиться.


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

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

А Вы читали исходники Savage? В них всё так, как я и говорил: написан интерпретатор бестипового языка. Интерпретатор простенький, не позволяет определять функции (я не нашёл соответствующего правила в parse.rs, и не нашёл в примерах, как это сделать). Можно ли этот интерпретатор довести до ума? Можно. Но это будет весьма трудоёмкое приключение. Поэтому я и говорю, что сложно написать систему компьютерной алгебры уровня Maxima или SCMUtils.

В книге SICP система уровня Savage разрабатывается за одну главу и умещается в меньший объём кода. При чём она сразу даёт возможность определять рекурсивные символьные функции и автоматически их дифференцировать. Ну, потому что обычные функции автоматически получают символьную интерпретацию. И это учебник из 80-ых годов.


Проблема с несоответствием типов чрезмерно преувеличена. Я вот на Scheme пишу production-код уже лет 5. До этого писал на C++, C, Java, Go, Haskell. Не вижу при переходе на язык с динамической типизацией особых проблем с ошибками в типах. Да, они бывают, но обнаруживаются простейшими тестами и быстро исправляются.

Это не только мой личный опыт. Есть соответствующее научное исследование On the Impact of Programming Languages on Code Quality, в котором показано, что наличие строгой типизации в языке не влияет существенно на количество багов.

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

На количество багов, прежде всего, влияет количество строк кода в проекте.

В первую очередь, на количество ошибок влияет ваш внутренний QA. А потом, разумеется, и размер кода.

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

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

Это, в общем характерно для программ на Python, что в спящих областях, таких как обработчики ошибок, как раз и таится некорректный код.

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

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

И именно на Haskell бизнес-логику писать - такое себе удовольствие. if-ы и pattern matching не выразительные в Haskell по сравнению с тем же Clojure.

Предлагаю начать с малого и написать интерпретаторы Common Lisp для Menuet и Kolibri. Ими никто не пользуется, а у них, насколько я понимаю, большой потенциал.

Отличная идея! Можете по быстрому сориентировать с чего начать? Как написать Hello World?

http://menuetos.net/docs.htm
Там есть и примеры аппликаций.
Сайт для Kolibri недавно поменяли, и теперь там ничего толком невозможно найти.
Menuet и Kolibri это почти одно и то же, только Menuet это 64 бит, а Kolibri это 32 бит и open source.
Написаны они на ассемблере, и предполагается, что аппликации к ним будут писаться тоже на ассемблере. Если Вы сами писали ядрышки, Вас это не должно остановить, правда? Но таких мазохистов героев не так много, а компилятора ни одного нормального языка еще не сделано, в результате с ними никто не хочет иметь дело, а жаль.

Хорошо что Вы это поняли и что под KolibriOS есть достаточное количество инструментльных средств написания кода под неё и не обязательно в приоритете использования ассемблера. 😋

P.S. К примеру, есть и такая экзотика как Форт для KolibriOS (на базисе SPF4).
Only those users with full accounts are able to leave comments. Log in, please.