Pull to refresh

Comments 161

SICP может быть несколько сложным для начала. Можно начать с "How to Design Programs, second edition: An Introduction to Programming and Computing", в русском переводе: "Как проектировать программы. Введение в программирование и компьютерные вычисления".

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

UFO landed and left these words here

С точки зрения CI/CD интерпретируемый язык вроде Lisp или Scheme очень удобен, потому что можно менять код программы прямо по ходу её выполнения, не перезапуская её. А функциональный стиль подразумевает, что каждая отдельная функция – сама себе юнит, который можно тестировать, причём в нормальном случае она не имеет побочных эффектов. Поэтому сама постановка вопроса об отдельных юнит-тестах скорее является артефактом императивных языков.

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

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

UFO landed and left these words here

Что да или нет?

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

Если программировать на Scheme символьный ИИ, что на каком-нибудь C++ вообще малореально, то тестирование затруднено, потому что сама фишка любого ИИ в том, что его невозможно покрыть тестами.

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

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

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

UFO landed and left these words here

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

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

UFO landed and left these words here

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

Если говорить про зрение робота, то вкорячивать в его код интерфейс к конкретной СУБД – в любом случае плохое решение.

UFO landed and left these words here

Во-первых, нет никаких стейтфул или стейтлесс задач. Есть конкретные алгоритмы.

Во-вторых, желательно выбирать соответствующий задаче уровень абстракции. Где-то там внизу данные может хранить та или иная СУБД, но для алгоритма машинного зрения это точно неважно.

UFO landed and left these words here

Вопрос сохранения данных вообще, конечно, рядовой. Scheme в этом отношении, между прочим – удобный язык, так как не имеет проблем с сериализацией объектов. Но сохранение вообще не означает, что нужно тащить в высокоуровневый код API СУБД.

UFO landed and left these words here
  1. Коннектор – не означает само API СУБД.

  2. В большинстве случаев, когда в реальной жизни используются простые СУБД вроде mysql, аналогичных результатов можно достичь в Scheme более простым путём – через ассоциативные списки и функции высшего порядка. Ещё и быстрее будет из-за отсутствия потерь на коннект. Конечно, это не относится к высоконагруженным и огромным по размеру базам данных, но там вообще совершенно своя специфика работы.

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

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

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

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

Однако, на то же самое можно взглянуть с другой стороны: когда мы занимаемся какими-то формальными преобразованиями кода, например, оптимизацией, распараллеливанием, доказательством правильности – то состояния нам мешают.

UFO landed and left these words here
UFO landed and left these words here

К сожалению, мне нет дела до того, какие слова или выражения вы выучили. Будь то "монада", "эндофунктор", "аорист" или "закозельская кукарямба".

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

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

Это применяется для написания компиляторов? Каких компиляторов? Как выясняется, это компиляторы из одного диалекта LISP в другой диалект LISP, описанные в мощнейшем университетском курсе 40-летней давности.

Это позволяет писать программы без ошибок? Как выясняется, под программой понимается не приложение, а кусок кода, который ничего не делает или считает ряд Фибонночи.

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

UFO landed and left these words here

Да хоть тот же ghc, например. 

То есть в компиляторе всё того же Haskell.

Market cap у какого-нибудь cardano, где это используется — 14 миллиардов, входит в топ-10

А почему не Hamster Combat? У него тоже была большая капитализация.

Или в гитхабе для анализа исходников.

Где я могу увидеть этот анализатор? На каком языке он написан?

Или в фейсбуке антиспам. 

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

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

Мощная система. И что, тоже на Scheme написана?

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

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

Этому обучают на профильных факультетах. Примерно на первом курсе.

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

Если не шарите - попробуйте восполнить оскорблениями. Расскажите им про помойных червей и обезьянок в зоопарке. Они будут вас внимательно слушать.

UFO landed and left these words here

Да, который, в свою очередь, используется в куче упомянутых ниже приложений. Чем плохо?

Тем, что gcc используется несколько шире.

А, то есть, теперь какие-то измеримые критерии вам не нужны? Ну понятно.

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

По вашему нет компаний с большей капитализацией, которые используют Visual Basic?

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

Ну то есть вы предполагаете, что она там есть.

А я предполагаю, что там С++. Или Go. Или Rust. Или Visual Basic. Попробуйте опровергнуть.

У вас аргументы всё мощнее. А я помню, как LLM рекомендовала пользователю пиццу с клеем, или что-то такое. И что теперь это говорит об ООП, с использованием которых по-вашему сделаны LLM?

Это говорит о том, что никакой "защиты от ошибок" в Хаскелле нет. Раз один городской сумасшедший смог её обойти самым примитивным способом.

Как вы сделали этот вывод из моих слов? Или это открытая вами теорема, доказательство которой — ненужная мелочь?

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

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

UFO landed and left these words here

Если бы вы разбирались в теме, то аргументация звучала бы так:

Scheme и чисто функциональные языки активно применяются в области X. Да, они не подходят для программирования контроллеров, но пример современного использования можно найти в книге Y.

Для примера: вот код, который описывает математическую матрицу средствами Haskell. После того, как вы определили матрицу таким образом, вы можете легко производить над ней операции вот так:

Я допускаю, что вам интересно рассказывать про лемму Йонеды. Но вот что важно: вас про лемму Йонеды и капитализацию криптовалют никто не спрашивал.

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

UFO landed and left these words here

Вы написали много про меня, и ничего по теме

UFO landed and left these words here
UFO landed and left these words here
UFO landed and left these words here
UFO landed and left these words here
UFO landed and left these words here
UFO landed and left these words here

Люди, которые придумали FILE*, fopen и fclose, такого слова-то, как ООП, не знали. Его не придумали ещё тогда.

FILE* – это адрес в памяти дескриптора файла.

UFO landed and left these words here

Ну я, например, не вижу эту жопу повсюду :)

UFO landed and left these words here
UFO landed and left these words here
UFO landed and left these words here
UFO landed and left these words here

Нас окружают объекты совсем не в смысле ООП.

UFO landed and left these words here
UFO landed and left these words here
UFO landed and left these words here

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

Вот что делает код:

команда пуэп 64 ошибка o8 o16 o8 o8 o16 o16 o16 o8 ostr)

???

Он создаёт ошибку? Вызывает ошибку? Почему нельзя записать его как

{

"to": "пуэп",

"cmd": "error",

"list": [o8, o16, o8, o8, o16, o16, o16, o8],

"ostr": true

}

и интерпретировать????

Его можно "передать в систему и не беспокоиться о внутренней реализации?" Кажется, кто-то только что изобрёл Observer, Command и Strategy. А может даже и event-based system и хэш-таблицы.

Макросы? Кто-то изобрёл Interpreter и DSL.

Функции как переменные? Указатели на функции были ещё в C.

Лямбды и создание функций на лету, map и т.п.? Давно есть даже в C++.

Рекурсия никуда не пропадала.

Требования писать функции чисто и по возможности использовать иммутабельность - были ещё в учебниках 1980-х.

Этот код ничего не ДЕЛАЕТ. Он говорит о том, что в протоколе работы с устройством "пуэп" есть собственная команда этого устройства с кодом 64, которую мы называем "ошибка", имеющая девять выходных параметров определённых типов.

Просто декларативное описание протокола работы.

Можно написать, например,

(команда http "GET" get istr ostr)

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

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

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

А поддержка JavaScript в этом браузере будет?

Я вот специально зашёл на https://try.scheme.org/ и вбил в строку выполнения (команда http "GET" get istr ostr)

Получил ответ:

ERROR IN console@1:2 -- Unbound variable: |\xd0;\xba;\xd0;\xbe;\xd0;\xbc;\xd0;\xb0;\xd0;\xbd;\xd0;\xb4;\xd0;\xb0;|

Какой-то плохой браузер получился. Мне не подходит.

А поддержка JavaScript в этом браузере будет?

Ну извините, бесплатно – берите что дают. Без джаваскрипта.

Я вот специально зашёл на https://try.scheme.org/и вбил в строку выполнения (команда http "GET" get istr ostr)

Так вам ещё нужен весь остальной код программы, чтобы такая команда работала.

Здесь от базового синтаксиса Scheme только строковый литерал "GET".

UFO landed and left these words here

Что значат все эти слова?

Начальное представление о значении этих слов можно получить в Википедии

UFO landed and left these words here

Судя по издевательскому тону, в котором вы их уже упоминали, вы что-то слышали о паттернах проектирования. Можете посмотреть подробности о них в оригинальной книге (она так и называется - "Паттерны проектирования")

Для Haskell есть даже сервис поиска функций по сигнатуре (!) в библиотеках по всей репозитории. А библиотек там, поверьте, не мало. Для подключения к Postgres - не менее дюжины, с примесями ОРМ и без. Там и свой crates и cargo и вся инфраструктура есть давным давно (кроме отдельного IDE). Но вроде ситуация от этого не меняется.

UFO landed and left these words here

Это называется "не прочитал, но своё мнение я скажу". Так и я об этом же - инфраструктура есть, но популяризации она не способствует.

UFO landed and left these words here

Что конкретно исследуют эти инженеры при помощи scheme и где познакомиться с результатами?

UFO landed and left these words here

Удручающе напоминает "великую теория Смысл-Текст" Мельчука и Жолковского. В ABBYY на её основе лет 10 делали систему автоматического перевода - и так и не сделали.

UFO landed and left these words here

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

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

UFO landed and left these words here

Предлагаю вспомнить ещё один успешный проект на Racket - Perl 6.

Им тоже никто не пользуется.

UFO landed and left these words here

Тем не менее Perl 5 продолжает обновляться и у него на порядок больше пользователей.

Очевидно, он позволяет решить больше задач и более удобен.

UFO landed and left these words here

Вам стоило бы немного поизучать логику. Аргументация оскорблениями (то у вас обезьянки в зоопарке, то копошение червей у мусорного пакета) - признак небольшого ума.

UFO landed and left these words here

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

UFO landed and left these words here

Скажем так - этот язык появился раньше Perl и с тех пор особо не развился. Никаких преимуществ перед JavaScript не обнаружено.

Невероятные технологии из 1985 года.

Возможно, в следующей статье нам расскажут про язык макросов в C.

А так, конечно, после волны скриптовых языков начала 90х всё это уже не актуально. В JavaScript уже в 2000 году были и деревья, и функции как значения и даже eval.

Что характерно, это пишет человек, написавший статью про программу из 200 строк для корректного сравнения объектов в JavaScript :)

Причём программа-то хорошая и нужная, но вот 200 строк на примитив equal? - нужен ли нам такой 2000 год?

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

Последний стандарт Scheme принят в 2013 году, SRFI – в 2023. Подозреваю, что за это время универсальное средство сравнения объектов в джаваскрипте так и не появилось, потому что джаваскрипт вообще – антипаттерн проектирования ЯП.

И как новый стандарт SRFI повлиял на популярность языка? Fortran тоже в 2018 году обновился.

Сравнивать в JavaScript сложнее, чем в Scheme, потому что в JavaScript не все типы сводимы к деревьям. А так-то готовые методы есть в underscore и lodash.

Вообще, JavaScript наглядно доказывает, что языки программированяи бывают двух видов: на одни все жалуются, а другими никто не пользуется. Lisp-оподобные языки были популярны как скриптовые языки в больших системах (с тех времён уцелели Emacs, Mathematica, Gimp) в те времена, когда документации было мало и разработчику приходилось работать лексером и парсером. Но почему-то как только появились Perl, а потом Python, Ruby, JavaScript и Lua, именно их, при всех недостатках, стали понимать интерпретаторы.

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

  1. Фортран обновился в 2023 году и активно используется в своей области, входя в десятку наиболее используемых ЯП.

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

  1. Ну вот видите. Язык прошёл проверку временем. В отличии от Scheme.

  2. Судя по той же таблице популярности, Scheme - это эзотерический язык где-то между Closure и Brainfuck

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

Clojure (кстати, тоже Лисп) не более "эзотерический" в 2024, чем, скажем, Ruby, если исключить большее количество легаси из-за старости второго. Можете ознакомиться со списком компаний использующих Clojure, от Apple до Netflix. Популярная графовая БД Datomic тоже полностью написана на Clojure.

Closure в 2024 достаточно эзотеричен, чтобы на него почти полностью отсутствовали вакансии. C 2007 года его много где могли попробовать, но в отличии от PHP и JavaScript, не нашлось ни одной области, где он бы обеспечил хоть какое-то преимущество над более простыми решениями.

nim и Nemerle тоже где-то пробовали. А на Lotus до сих пор что-то в каких-то компаниях работает.

Почти полностью отсутствуют вакансии где, в России?

C 2007 года его много где могли попробовать

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

PHP незаменим из-за охренительного количества легаси. Javascript, как рантайм - из-за браузера, а как язык оказался хуже, чем десятки надстроек над ним. И ClojureScript, как бы иронично не звучало, один из них.

У меня https://clojurejobboard.com/ открылся как пустая страница.

Замечательная демонстрация продвинутости технологии и профессионализма тех, кто её использует.

Так страница написана на джаваскрипте.

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

Так и Лисп не эзотерический язык. Clojure нормальный диалект Лиспа, только поверх JVM. Могу понять людей, которым не хотелось писать на Джаве, когда они знают Лисп.

Могу понять даже людей, которые пишут на кроссплатформенном и Тьюринг-полном языке Brainfuck.

Вы говорили про отличия от лисп а есть ли в ским библиотека по типу cffi для интеграции сишного кода? Если есть то вопрос о недостатке библиотек не слишком актуален :)

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

В этом плане интересная работа проводится в Gambit Scheme (я привёл ссылку на лекцию в статье), где прямо посреди скимовского кода можно писать императивные операторы с питоновскими вызовами чего угодно. И автор прямо в видео показывает, как он pip'ом какую-то там полезную примочку подтянул и тут же из скима вызвал. Тем более, к питону концептуально проще цепляться, чем к си – он тоже динамический язык.

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

Я лично в целом сторонник микросервисной архитектуры, и считаю, что, по большому счёту, если сокеты есть (а они в скиме есть на уровне конкретных реализаций) – то уже жить можно.

UFO landed and left these words here

Мысль Ваша движется в правильном направлении.

Более того, на сегодня подавляющее большинство компиляторов использует в качестве промежуточного представления кода программы AST деревья, которые по сути являются специализированным диалектом Лиспа. Так что можно сказать, что программа на Rust фактически сначала транслируется в Лисп (AST дерево) фронтендом компилятора, а потом уже бекенд компилятора транслирует AST дерево в машинный код.

И одно из применений языков Lisp и Scheme – это как раз скрипты для прикладных программ. Например AutoCAD скриптуется на AutoLisp, GIMP – на TinyScheme. Это также к вопросу об обработке изображений.

UFO landed and left these words here
UFO landed and left these words here

В уже указанной книге написанию такого интерпретатора на Go посвящены главы Evalution и Evaluting the Interpreter. Сам автор указывает, что его реализация обхода аналогична интерпретатору из 5-ой части SICP.

Набор s-выражений здесь выстроен в AST (Abstract Syntax Tree). В принципе, никаких принципиальных отличий от Scheme нет - просто yacc позволяет сгенерировать лексер и парсер, а в лиспоподобных языках лексер и парсер - белковые (то есть это дерево строит сам программист).

Можно попросить интерпретатор, чтобы он дёргал предустановленные функции из C-библиотеки. Подключить их можно, например, так: https://dev.to/metal3d/understand-how-to-use-c-libraries-in-go-with-cgo-3dbn

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

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

Нет, потому что Лисп – это как данные, так и имеющий определённую семантику код, а JSON – только данные.

UFO landed and left these words here

Ну смотрите, в языке же всё завязано одно на другое.

sort-list в Scheme – это функция высшего порядка, у которой первым аргументом идёт лямбда-выражение, задающее упорядочивающее отношение, а вторым аргументом список, который в Лиспе/Scheme тоже реализуется вполне определённым образом. В стандартном Лиспе заодно ложь и пустой список – одно и то же значение. То есть вам надо построить лисповские структуры данных, чтобы обрабатывать их лисповскими функциями.

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

UFO landed and left these words here

Лисп язык очень высокого уровня, и именно поэтому в нём нет эксплуатационных/тулзовых вещей. Он выше их уровнем.

Сам я использую Scheme для реализации некоторого метаязыка – надстройки над сервисами, написанными на других языках. А всякие базы данных, GUI интернет и прочее – они ниже уровнем, в условном “ассемблере”. Фактически я имею возможность давать описание задачи компьютеру на языке, приближенном к естественному, а программа на Scheme сама преобразует их семантику к операциям, исполняемым при помощи других прикладных программ, и сама генерирует для этого код.

А VM ко всему этому вообще не имеет никакого отношения. Лисп – компилируемый (при необходимости) в машинный код язык.

UFO landed and left these words here

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

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

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

UFO landed and left these words here

Так я как раз не хочу ничем оперировать. Или хочу оперировать как можно меньше.

ASM не позволяет делать утверждения, а Лисп позволяет. ASM просто задаёт команды.

Это, кстати, значительная проблема при обучении ФП людей, ранее знакомых с императивными языками – отучить их мыслить поведением.

UFO landed and left these words here

Тут надо внимательно следить за руками. Хотя математика исторически и появилась как способ подсчёта отнимаемого у крестьян зерна, но в современном понимании не является манипуляцией с числами. И операторы над матрицей или функции в математике просто фиксируют отношения между правой и левой частями. Например, в математическом утверждении sin(x) = cos(x+pi/2) нет никакого вычисления или манипуляции, это просто денотация свойства синуса и косинуса.

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

Если бы мы не умели вычислять значения синуса и косинуса, то фиг бы мы вообще что получили императивным способом определения функции из равенства sin(x) = cos(x+pi/2). Хотя как база для символьных преобразований – оно вполне рабочее.

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

UFO landed and left these words here

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

UFO landed and left these words here

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

Важное уточнение - учебное пособие приблизительно 40 летней давности. С тех пор индустрия шагнула немного вперёд. И сам курс давно читают с примерами на Python 3.

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

Новый курс вообще совсем поверхностный, а не то что просто переведён на Python.

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

Ну я бы сказал, что всё намного проще - с появлением более лаконичных и читаемых языков Scheme отправился вслед за Smalltalk и Simula67

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

Эта книга - 1985 года. Тогда ещё даже Mathematica не было.

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

Если вычислительная математика - то компьютер просто используется как очень мощный калькулятор, там LISP-ов нет, а используется C-подобная CUDA или даже Fortran (на суперкомпьютерах до сих пор). А логическая математика - это крайне узкая область и описание её объектов очень утомительно: приходится разворачивать каждое "после тривиальных преобразований получим". Гротендик и вовсе считал такие инструменты концом математики как науки.

UFO landed and left these words here

Зависит от использованной модели.

UFO landed and left these words here

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

А когда вы введёте обратную связь, то вам не нужно будет хранить в программе состояние объекта.

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

UFO landed and left these words here

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

Поэтому у вас будет поле в объекте "состояние лампочки", с одной стороны, и фактическое состояние лампочки, с другой стороны. И они могут разойтись между собой.

Всё на самом деле ещё сложнее. Реальная история из жизни. В одном приборе было установлено механическое реле, состояние которого контролировалось программой через замыкание контрольного контакта, а всего в контактной группе замыкалось много контактов. И вот получилось так, что в процессе транспортировки реле сотряслось, и разные контакты в контактной группе оказались в разном положении. Контрольный контакт оказался замкнут, а исполнительный отошёл от замкнутого положения (или наоборот). И неудачно написанная программа заблокировалась, так как она считала реле замкнутым и не видела оснований подавать ещё одну команду на его замыкание. Так что даже с обратной связью всё не так просто, и никаких программных состояний и прочих неконтролируемых теоретических допущений о состоянии управляемых объектов быть не должно. А в этом устройстве с тех пор горячие клавиши для команд управления отрабатываются программой даже тогда, когда команды исчезают из меню на экране. Пользователю виднее. Ну, программисты зато прокатились в командировку 4 часа на самолёте.

Если вам интересно, то вот почти реальный код на Scheme из системы управления объектом, касающийся подсистемы управления электропитанием:

(служба 111 сервер1 пуэп)
(команда пуэп 61 вкл-выкл i16 i8)
(команда пуэп 62 описание i16 o8 o16 o8 o8 o8 ostr)
(команда пуэп 63 статус i8 o8 o8 o16 o16 o8 o8)
(команда пуэп 64 ошибка o8 o16 o8 o8 o16 o16 o16 o8 ostr)
(команда пуэп 65 включить i16 таймаут 20)
(команда пуэп 66 выключить i16 таймаут 20)
(команда пуэп 67 блокировать i16)
(команда пуэп 68 разблокировать i16)
(команда пуэп 69 состояния o8 o8 o16 o8 o8 o8 o8 o16 o8 o8)
(команда пуэп 70 вкл-выкл-дизель i8)
(команда пуэп 71 вкл-дизель)
(команда пуэп 72 выкл-дизель)

Это макросы, которые генерируют фактический исполняемый код для команд управления.

Они находятся ближе к нижнему уровню абстракции в программе. На самом верхнем уровне находятся команды вроде (условно):

(время 9:00) (заварить кофе)

а система уже сама разбирается, что и как для этого нужно сделать.

Если бы я использовал тут объектную модель, то я бы столкнулся, как минимум, со следующими проблемами.

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

  2. Пришлось бы каждый раз думать, какой именно класс реализует нужный мне метод, например, заварить(). Это представляет собой совершенно излишний мыслительный труд. Либо надо было бы собирать вообще все методы верхнего уровня в одном суперклассе УмныйДом, что по понятным причинам криво.

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

UFO landed and left these words here

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

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

UFO landed and left these words here

Вы вправе всё, что угодно, называть объектами, но реквизиты магазина и банковской карты - это структурированный текст. В Лиспе он будет, несомненно, синтаксически представлен S-выражением, которое по своей семантике, скорее всего, будет иметь тип список.

UFO landed and left these words here

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

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

UFO landed and left these words here

В смоллтоке разве что. И то я не уверен относительно экземпляров чисел.

UFO landed and left these words here
UFO landed and left these words here
UFO landed and left these words here
UFO landed and left these words here
UFO landed and left these words here
UFO landed and left these words here

emacs на C написан. LISP там - аналогично Python в Sublime или JavaScript в Atom, язык скриптов и дополнений.

Вроде на C написан интерпретатор Emacs Lisp, а на этом Лиспе - сам Emacs.

UFO landed and left these words here

Если б его писали сейчас, был бы целиком на лиспе, к гадалке не ходи. Но в те времена Лисп очень тормозил.

ZED (из недавно вышедших) написан на Rust.

Что в нём нового по сравнению с Sublime - не очень ясно.

За Scheme можно было ещё словечко замолвить. Racket есть в Termux пакетом, а вот пакета Julia в Termux нет. И на Андроид есть диалект Lisp как относительно рабочее приложение, а на iPad есть прямо таки Scheme, хотя и называется LispPad. И Scheme развивается достаточно медленно и поэтому везде более-менее одинаковый, чем выгодно отличается от того же Python который почти везде не актуальный.

Книжка SICP в 2022-м году вышла перепетая на JavaScript.

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

Вот промисы в том же JS: есть две ветки выполнения - resolve и reject - и состояние, упакованное в контейнер. Пусть @illinav поправит, но очень похоже на монаду.

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

@RikkiMongoose.Кстати, вот насчёт типизации и гарантий в "compile time" (в широком смысле), никто же не будет спорить что "use strict" штука полезная.
ESLint, TypeScript - тоже классные инструменты. Насколько понимаю, Haskell и, тем более, Idris, например, - это как TypeScript на максималках.

@ednersky Спор выше по сути не про ООП, а про слабые и сильные системы типов. И вот как то так получилось, что у большинства ООП-языков система типов слабая (по сравнению с). И приходится выкручиваться паттернами и линтерами и тестами там, где могли бы эффективнее работать типы.

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

Что популярно и где используется - вообще странный аргумент, вот Blackbird - чудо своего времени, но использовался крайне ограниченно, так и тут.
Возможно, что то из функциональных (в том числе "экзотических") языков ещё перейдёт в тот же JS / TS (и другие мейнстримные языки). Такое уже не раз было...

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

Что касается промисов (которые вроде как раз из Scheme изначально и пошли), то они, скорее, представляют собой организацию ленивого вычисления руками. Но пользы от этого, честно сказать, гораздо меньше, чем от настоящего ленивого порядка вычислений, как в Хаскеле. Хотя иногда бывает полезно.

UFO landed and left these words here

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

А что касается мема, то, конечно, это пример просто необдуманной перегрузки плюса.

UFO landed and left these words here

Она даёт автоматизацию части вещей, для которых иначе надо сначала содержательно думать головой, а потом писать руками код. То есть увеличивает производительность труда программиста и надёжность программы, если предметная область вообще поддаётся содержательной типизации (категорированию). Это как с объектами: можно, конечно, декларировать, что объекты – это вообще всё, но практическую пользу от этого можно получить только в некоторых случаях.

А так пусть лучше вам хаскелисты объясняют. Я лично за бестиповое ФП.

UFO landed and left these words here

Не являюсь экспертом по перлу, но в моём понимании он – классический императивный язык, весьма запутанный к тому же. Наличие лямбды не особо приближает его к функциональному программированию, он императивен по семантике своих основных конструкций (как и питон). Хотя саму по себе идею заимствования lambda и map в императивных языках следует приветствовать.

UFO landed and left these words here
UFO landed and left these words here

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

Sign up to leave a comment.

Articles