LINUX.ORG.RU

Зависимые типы, жидкие типы. Что лучше?

 , liquid haskell,


1

4

Пытаюсь понять тенденции в современных статических языках. Обычного Haskell явно не хватает. Что ожидать на замену?

★★★★★

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

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

Я вот читаю твой комментарий и мне кажется, что ты просто тупой. Не знаю, почему так.

И нахрен мне это надо, чтобы уловить класс ошибок размером в 0,2%?

Доступность привелигированных API только для аутентифицированных юзеров отлично кодируется в типах хачкелля. Не уверен, что это прямо 0.2%. Но тебе лучше знать, чувак.

hateyoufeel ★★★★★
()

Жидко типизированный код. А что, звучит.

«Опять этот джун жидко обтипизировался прямо в мастер» .

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

Жидко типизированный код.

Еврейко типизированный код. Хватит антисемитствовать!

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

Например, что функция parseJSON для любой строки возвращает валидный json либо ошибку, а не взрывается.

Без зависимых типов нормально там реализуется «валидный json»? А если что-то посложнее? (ну ответ мы и так знаем). Динамика на контрактах тоже могет.

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

Я вот и хотел услышать, возможно, какой-то *действительно* подходящих пример что вот у нас есть такая задача. И из-за _таких_ вот свойств хаскеля потому и поэтому - это реально лучший вариант из существующих. Или один из нескольких. А начинается опять сказ про сложение килограмм с апельсинами.

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

Я вот читаю твой комментарий и мне кажется, что ты просто тупой. Не знаю, почему так.

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

Доступность привелигированных API только для аутентифицированных юзеров отлично кодируется в типах хачкелля.

Чем сложно реализовать это в динамике? И чем такое решение будет хуже?

Не уверен, что это прямо 0.2%. Но тебе лучше знать, чувак.

100%.

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

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

Ты приводишь кейсы с какими-то данными которые приходят непонятно откуда и содержат непонятно что и спрашиваешь как себя поведет haskell код. Он поведет себя одинаково, как и любой другой код, но в отличии от любого другого в нем практически невозможен вариант, когда «неправильные» входящие данные, проскользнут в систему из-за неявных преобразований, благодаря строгой статической типизации, более того, тебе вывалится не какое-то невнятное в виде стектрейса, а вполне приличное сообщение о том что произошло. Здесь можно начать приводить примеры того, что это все же можно сделать если захотеть, но это будет просто попытка на зло мамке уши отморозить чтобы доказать что у haskell нет из коробки никаких преимуществ.

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

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

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

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

Это не история, это факт.

Это чушь. Но про статическую vs динамическую типизацию не интересно, это обсуждалось много раз. И по итогу - статическая почти никогда не нужна.

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

Это более верно чем то что написано перед тобой.

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

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

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

А так не в вебе да есть и какие-то более менее известные названия например https://www.tesla.com/careers/search/job/haskell-engineerdatatools-82891?sour...

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

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

Без зависимых типов нормально там реализуется «валидный json»?

Если понимать слово «нормально» буквально, то да, нормальная реализация будет без зависимых типов. Гарантии корректности при этом будут на человеческом языке (слово пацана), на языке реализации (юнит-, проперти-тесты) либо на отдельном языке. С зависимыми типами спецификация, реализация и верификация пишутся на одном языке.

А если что-то посложнее? (ну ответ мы и так знаем).

Что-то посложнее будет посложнее.

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

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

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

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

Система, которую пользователь может расширять в процессе работы (как Emacs или почти любая программа на Common Lisp). Или которую можно обновлять без останова работы (как Erlang OTP).

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

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

И ещё программа, которая должна иметь графический интерфейс в том числе на Windows.

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

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

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

Это чушь. Но про статическую vs динамическую типизацию не интересно, это обсуждалось много раз. И по итогу - статическая почти никогда не нужна.

Ты же сам жалуешься, что тебе никто ничего не может внятно объяснить, а сам кроме как «чушь, глупость, ерунда» ничего ответить на вполне обоснованные аргументы не можешь.

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

как много новых языков имеют динамическую типизацию

Julia, Hack, Scala. Приобрёл динамическую типизацию C#, добавлен std::any в С++ и Dynamic в Haskell.

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

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

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

void* хватило бы всем и для всего

Там у значения типа нет. То не динамическая, то слабая.

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

Там не было обоснованных аргументов, или «на хаскеле можно нанять макак за борщ и все будет надежно» это и есть самый сильный и адекватный аргумент?

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

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

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

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

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

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

То не динамическая, то слабая

ескобар.jpg

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

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

Ничего, менее квалифицированный персонал придумает новые, охапками. Да такие, которые тебе во страшном сне не привиделись бы.

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

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

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

если прокладка между клавиатурой и креслом никудышная совсем, не спасет никакой язык

Точно так. Конечно, хотелось бы, чтобы кухарка могла успешно делать операции на мозге (за зарплату кухарки, разумеется), но вряд ли это хорошо кончится — какой бы крутой наноскальпель мы ей ни вручили.

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

остальные проблемы будет решать язык настолько, насколько сможет

Он не помешает перепутать «+» и «-», «<» и «>», ленивое выполнение заставит падать с ошибкой деления на ноль не в операции деления, а в команде putStrLn a, а принципиальное отсутствие пошагового отладчика значительно затруднит поиски ошибки.

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

Видимо мне придется теперь до момента протухания этого треда цитировать себя Зависимые типы, жидкие типы. Что лучше? (комментарий)

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

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

Я как раз на Haskell писал. И когда получил на строчке writeFile outFile . unlines . reverse . result ошибку разбора регулярного выражения был озадачен, а как теперь искать, откуда она взялась.

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

Но право, в жс или питоне это сделать куда проще имхо.

Там проще уронить, но и проще поднять. Есть отладчики, есть стектрейс.

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

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

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

A тут что сложного? разбей на части посмотри что происходит, что уж проще может быть.

Как посмотреть? Он же не пишет из какой функции прилетел error.

Как поделить на части? Точек останова в языке не предусмотрено.

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

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

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

Как посмотреть? Он же не пишет из какой функции прилетел error.

вообще-то пишет

Как поделить на части? Точек останова в языке не предусмотрено.

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

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

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

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

вообще-то пишет

Prelude> let f x y  = (x+y) `div` (x-y)
Prelude> let g x  = x - 5
Prelude> let k x = f (g x) 10
Prelude> let s = map k [1..20]
Prelude> sum s
*** Exception: divide by zero

И как увидеть, в какой функции ошибка? В sum точно никакого деления нет, там только суммирование.

декомпозировать код разбив выражение на части

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

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

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

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

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

И как увидеть, в какой функции ошибка? В sum точно никакого деления нет, там только суммирование.

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

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

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

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

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

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

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

И как увидеть, в какой функции ошибка? В sum точно никакого деления нет, там только суммирование.

Собрать код с инструментированием и запускать с нужными флажками RTS:

> cat callstack.hs                       
f x y  = (x+y) `div` (x-y)
g x  = x - 5
k x = f (g x) 10
s = map k [1..20]
main = print $ sum s

> ghc -prof -fprof-auto ./callstack.hs -o ./callstack
[1 of 1] Compiling Main             ( callstack.hs, callstack.o )
Linking ./callstack ...

> ./callstack +RTS -xc
*** Exception (reporting due to +RTS -xc): (THUNK_STATIC), stack trace: 
  GHC.Real.CAF
  --> evaluated by: Main.f,
  called from Main.k,
  called from Main.s,
  called from Main.CAF
  --> evaluated by: Main.main,
  called from Main.CAF
callstack: divide by zero

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

> cat hascallstack.hs
import GHC.Stack (HasCallStack)

f :: HasCallStack => Int -> Int -> Int
f x y  =
  if x == y
  then error "divide by zero"
  else (x+y) `div` (x-y)

g :: HasCallStack => Int -> Int
g x  = x - 5

k :: HasCallStack => Int -> Int
k x = f (g x) 10

s :: HasCallStack => [Int]
s = map k [1..20]

main = print $ sum s

> ghc ./hascallstack.hs -o ./hascallstack
[1 of 1] Compiling Main             ( hascallstack.hs, hascallstack.o )
Linking ./hascallstack ...

> ./hascallstack 
hascallstack: divide by zero
CallStack (from HasCallStack):
  error, called at hascallstack.hs:6:8 in main:Main
  f, called at hascallstack.hs:13:7 in main:Main
  k, called at hascallstack.hs:16:9 in main:Main
  s, called at hascallstack.hs:18:20 in main:Main
Laz ★★★★★
()
Ответ на: комментарий от anonymous

на действительно слабые места haskell, а именно на его систему модульности и как следствие этой системы на его проблемы с неповоротливой долгой сборкой, на инструменты сборки как таковые

Для моих целей хватало. Но фоне C++ он ещё быстрый.

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

Как будто это что-то плохое. И в XMonad и в Movie-Monad 95% кода в монаде IO. И так почти в любой прикладной программе.

если вы писали на хаскеле вы знаете, что там никто простынями не пишет

https://github.com/xmonad/xmonad/blob/master/src/XMonad/Core.hs#L565 – это не простыня?

Или https://github.com/hedgewars/hw/blob/master/gameServer/HWProtoLobbyState.hs#L73 ?

Если не простыня, то простынями на всех языках почти никто не пишет.

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

called from Main.k,

Строчку и имя файла угадывайте сами…

Ну да «никто простынями не пишет».

s :: HasCallStack => [Int]

Здесь лучше. Осталось прикрутить макросы, чтобы это по -debug автоматически на все функции прикручивалось. Правда он и так не слишком быстро пересобирвается.

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

95% кода в монаде IO

да ты упорот. там даже main это IO() и что не писать на хаскеле теперь? зачем кстати ты на нём пишешь? ты же скобочкофил, вот и пиши на лишпах, не?

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

да ты упорот. там даже main это IO() и что не писать на хаскеле теперь?

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

По мне IO не хуже любой другой монады.

А для обсуждаемого «менее квалифицированного персонала» это вообще основной режим записи программы.

зачем кстати ты на нём пишешь?

Чтобы получить красивый текст прграммы.

ты же скобочкофил, вот и пиши на лишпах, не?

Это что за сцена ревности?

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

Ну а на чем писать транслятор, не на С++ же

Ха. Как раз недавно для прикола написал один и тот же транслятор дважды, на C++17/Boost и F#. Так вот нифига не очевидно, какой вышел проще.

У F# мусора поменьше, и строчек меньше, зато они перегружены горизонтально и больше давят на моск. Да, паттерн-матчинг - почти киллер-фича (ждем C++23), но в целом код плюс-минус одинаково замороченный, не сказать чтоб прям явно один лучше другого.

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

Для моих целей хватало. Но фоне C++ он ещё быстрый.

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

Как будто это что-то плохое.

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

Если не простыня, то простынями на всех языках почти никто не пишет.

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

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