LINUX.ORG.RU

Анализ пользователей Common Lisp и Racket

 , ,


11

7

Common Lisp разрабатывался и используется в предположении, что пользователь программы — программист. Поэтому из языка намеренно исключены сложные для понимания конструкции (пользователь не обязательно квалифицированный программист), поэтому в языке мощнейший отладчик, позволяющий без остановки программы переопределять функции и вообще делать что угодно. Но из-за этого документация по большей части библиотек Common Lisp существует только в виде docstring и комментариев в коде (некоторые вообще считают, что код сам себе документация). Из-за этого обработка ошибок почти всегда оставляется на отладчик (главное сделать рестарт «перезапустить с последней итерации», а там пользователь сам разберётся). Из-за этого в программе проверяется только happy path (пользователь ведь «тоже программист»).

Racket разрабатывался и используется в предположении, что пользователь программы не программист, а задача разработчика написать программу так, чтобы она корректно работала при любых входных данных (если данные некорректны, то сообщала об этом в том месте, где данные были введены). Поэтому в языке эффективная библиотека для написания тестов, система контрактов на уровне модулей, макимально широкий спектр инструментов программирования (разработчик должен быть профессионалом!). Также реализована идея инкапсуляции: считается, что пользователь модуля не должен знать особенности реализации и, более того, не может в своём коде изменить функцию чужого модуля если это явно не разрешено разработчиком того модуля. Исходный код разумеется доступен, но его не требуется смотреть, чтобы использовать модуль. Достаточно документации. Поэтому реализована мощнейшая система документировния Scribble, а при реализации макроса есть возможность обеспечить указание на ошибки в коде, предоставленном макросу пользователем, не показывая потроха макроса.

И поэтому в Racket нет CLOS (есть как минимум две реализации, но не используются) - провоцирует заплаточное программирование (monkey patching), поэтому отладчик намеренно ограничен (если ты отлаживаешь программу, значит ты не знаешь как она должна работать!), поэтому нет разработки в образе (image based) - она провоцирует разработку через отладку (а значит непонимание программы и проверку только happy path).

Таким образом, Racket и Common Lisp несмотря на внешнее сходство являются очень разными языками. И я рекомендую писать на Racket, если только конечными пользователями программы не являются исключительно программисты на Common Lisp.

Взято с http://racket-lang.blog.ru/#post214726099

Хотелось бы знать, что по этому поводу думают пользователи ЛОРа. А также, мне кажется, что для Java и C++ будет где-то такая же разница.

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

But if you do this for several different formats, you soon begin to see lots of duplication between the functions.

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

Another problem with this approach is that it is very easy to miss a shape in one or more savers

отловится при первом тестовом запкуске, нет?

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

Делать в 21-м веке язык с динамической типизацией - это роспись в профессиональной непригодности (и да, я знаю о Typed Racket).

С или C++ в руках идиота гораздо страшнее, чем Common Lisp в руках идиота.

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

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

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

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

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

miss a shape — в варианте define/match увидишь ошибку только при тесте именно по пропущенной комбинации. Или не увидишь. Match ведь просто вернет void

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

С или C++ в руках идиота гораздо страшнее, чем Common Lisp в руках идиота.

Си - древний убогий язычок, Си++ - напластование костылей поверх этого язычка; да, наверняка они опаснее в руках идиота.

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

Блин, каждый раз из оо помойки

Казалось бы, причем тут ОО...

доносится чей-то тупой визг про нужность типов.

Ritmik ★ (02.10.2014 8:11:11) [малограмотное кложурное хамло]

Некоторые вещи не меняются %)

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

Си - древний убогий язычок, Си++ - напластование костылей поверх этого язычка

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

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

Я бы внял, если бы думал, что за неубогий язык ты считаешь хаскель

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

Но ты же питонист

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

tailgunner ★★★★★
()

У меня после прочтения AMOP появилось осознание того, что протоколы — это более гибкая и правильная альтернатива интерфейсам.

http://norvig.com/design-patterns/design-patterns.pdf

Я просто оставлю это здесь.

ilammy ★★★
()
Ответ на: комментарий от x4DA
> (match 4 [1 "ok"])
. . match: no matching clause for 4
anonymous
()
Ответ на: комментарий от tailgunner

неубогому языку Ocaml.

лел. Башню чисел не осилили. Две точки с запятой дно ебаное. Если найду пасту с полным анализом от Лавира, кину сюда.

anonymous
()

Хотелось бы знать, что по этому поводу думают пользователи ЛОРа.

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

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

division by zero.

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

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

Правильно я понял, что ты мне запрещаешь печь дома пироги? Сначала надо на кондитера пойти поучиться?

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

Match ведь просто вернет void

Нет, match плюнет эксцепшен.

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

жалко, что не можешь, это вроде как элементарно :/

myaction :: IO String -> X (Maybe String)
myaction читатьИзIO = do
  s <- liftIO читатьИзIO
  if s == "ok"
  then refresh >> return (Just "ok")
  else return Nothing

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

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

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

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

SCB расскажи, им интересно будет.

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

Ты пойми, что система типов - это лишь инструмент

Какпитан никогда не бывл так очевиден.

динамике есть аналогичные статике инструменты для решения аналогичных проблем (получение гарантий корректности программы и т.п.)

Назови их.

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

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

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

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

Назови их.

Динамическая типизация. Если назовешь конкретную задачу, покажу как она решается в динамике.

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

Standard Chartered Bank из тех что haskell используют активно в повседневной жизни.

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

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

Назови их.

Динамическая типизация.

Я выше сказал, что Капитан никогда не был так очевиден... но через минуту ты побил рекорд.

Если назовешь конкретную задачу, покажу как она решается в динамике.

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

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

http://eax.me/types-benifit/

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

Да? А вот что автор действительно имеет сказать:

«благодаря типам вы никогда не сложите возраст с долларами, не сошлетесь на несуществующий URL и не напишите невалидный SQL запрос. Я многие годы работал с динамически типизированными языками программирования и пришел к выводу, что писать на них что-то серьезнее скрипта на 100 строк кода — это боль и унижение. Не повторяйте моих ошибок, пишите на нормальных языках».

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

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

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

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

не сошлетесь на несуществующий URL и не напишите невалидный SQL запрос

Еще как

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

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

Говорить можно что угодно, а во тфакты не врут:

1. Наличие статической типизации НЕ ИЗБАВИЛО его от ошибки само по себе

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

вывод: решение подобных задач ортогонально типизации

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

Наличие статической типизации НЕ ИЗБАВИЛО его от ошибки само по себе

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

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

Покажи решение с динамической типизацией, которое обнаружит ошибку без запуска программы.

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

вывод: одно кривое решение подобных одной частной задачи ортогонально типизации

fixed во имя Бобра

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

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

Именно так. Смысл в том что в динамике есть свои инструменты для решения задач, которые решает статика.

Покажи решение с динамической типизацией, которое обнаружит ошибку без запуска программы.

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

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

Покажи решение с динамической типизацией, которое обнаружит ошибку без запуска программы.

А зачем именно без запуска?

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

Главное найти ошибку и желательно пораньше, запуск/отсутсиве запуска - совершенно несущественно.

Ты гарантируешь, что запуск тестов быстрее прохода чекера? На каком основании? Как насчет времени, потраченного на написание тестов?

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

У тебя программа выполняется без компиляции, волшебными понями?

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

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

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

А зачем именно без запуска? Главное найти ошибку и желательно пораньше, запуск/отсутсиве запуска - совершенно несущественно.

А ты уверен, что не зевнешь опечатку какую-нибудь тупейшую? И она вылезет в рантайме в самый неожиданный момент. Или щас начнешь заливать про супер-дупер TTD и 100% покрытие?

anonymous
()

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

2. Будет ли в программе только проверка «happy path» - это зависит только от программиста.

3. Инкапсуляция в CL возможна, на уровне пакетов. И далее грепать :: по всем сорсам, чтобы найти нарушения. Вообще, сама догма о том, что нельзя опираться на реализацию, потому что она может измениться, выглядит сомнительной. Может измениться - это ещё не значит обязательно изменится. Закладка на реализацию позволяет достичь цели быстрее и обогнать конкурентов сегодня, а если она вдруг изменится - то тогда и будет время разобраться.

4. Если у меня не будет разработки в образе, то и лисп тогда не нужен. Есть Java и C#.

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

Господа, давно доказано языком T-SQL (а может, и другими подобными), что динамизм (возможность менять программу в рантайме) и строгая типизация не противоречат друг другу.

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

Покажи решение с динамической типизацией, которое обнаружит ошибку без запуска программы.

Запуск тестов является запуском программы? Статически типизированная программа не требует тестов?

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

динамизм (возможность менять программу в рантайме)

Речь о динамической и статической типизации, а не «динамизме» в твоем понимании.

и строгая типизация не противоречат друг другу.

По-моему, кто-то путает статическую и строгую типизации.

Запуск тестов является запуском программы?

Да.

Статически типизированная программа не требует тестов?

Требует.

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

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

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

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

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

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

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

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

Ребят, заканчивайте, пожалуйста, этот малоинтересный срач динамические типы vs статические. А то ей богу, такой упор на ТОЛЬКО ПРИ КОНПЕЛЯЦИИ БЕЗ ЗАПУСКА... что идеальным языком для вас будет Typed Awesome, где единственным допустимым выражением является полиморфное «Вам заебись», а всю программу надо выразить типом этого выражения, чтобы она ВЫПОЛНИЛАСЬ ПРИ КОМПИЛЯЦИИ.

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

т.е. соответствие типов уже во многом достигнуто. Хотя, могу все же привести и такой пример.

А типы там при чем? Там про говенность общелиспа, который не умеет в корректное выполнение макросов.

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

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

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

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

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

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

А этот метод одинаково можно исопльзовать как в статике, так и в динамике (в динамике даже удобнее немного)

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

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

Ребят, заканчивайте, пожалуйста, этот малоинтересный срач динамические типы vs статические.

Ты не обязан в нем участвовать.

такой упор на ТОЛЬКО ПРИ КОНПЕЛЯЦИИ БЕЗ ЗАПУСКА...

Не знаю, где ты нашел этот упор, но отдай его владельцу.

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