LINUX.ORG.RU

Функциональщина. Что выбрать?


0

0

Решил в свободное время заняться изучением модного нынче функционального программирования. Встал естественный вопрос: что выбрать? Этих всяких лиспов, хацкелей, оцамлей и т.п. вагон и маленькая тележка. Чтобы не распыляться выбрал Scheme, т.к. его используют в SICP, но настораживает его не слишком большая распространённость и «академичность». С другой стороны, лямбды и прочие «вкусности» потихоньку приходят и во всякие там питоны и даже плюсы. Не холивара окаянного ради, а сугубо для просвещения и развития спрашиваю: что изучать, чтобы не лежало оно потом мёртвым грузом? У каких языков какие плюсы, минусы и области применения?

★★★★

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

>Ты его не знаешь даже (для протокола - я не о своем мнении).

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

Но в рантайме, мля. При том, что их можно ловить на этапе компиляции.

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

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

>Попробуй «звонок другу».

ок. Как же в хаскеле функцию сделать от переменного количества аргументов? А! вот так: add2, add3, add4, lol.

вот и видно, что хаскель это такой лямбда/теоркат-брейнфак. а функциональная парадигма полностью поддерживается в удобном виде в том же комон лиспе.

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

> Можно поинтересоваться списком «разных языков»?

Можно: FORTRAN, C++, Python, JavaScript, Common Lisp - языки для которых имел достаточно большую практика (для FORTRAN наименьшую)

Потому что именно в Хаскеле я начал понимать,

что такое НАСТОЯЩАЯ статическая типизация.



Я правильно понимаю, что НАСТОЯЩАЯ она только в Haskell?

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

>>Потому что именно в Хаскеле я начал понимать, что такое НАСТОЯЩАЯ статическая типизация.

Давай угадаю, она делает все крутым и супер математичным?

facepalm.jpeg

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

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

>>Но в рантайме, мля. При том, что их можно ловить на этапе компиляции.

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

Ты наверное не поверишь, но и в статике это делать тоже можно.

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

Как же в хаскеле функцию сделать от переменного количества аргументов? А! вот так: add2, add3, add4, lol.

Как же тогда, интересно, работает Text.Printf?

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

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

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

Я правильно понимаю, что НАСТОЯЩАЯ она только в Haskell?

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

Хотя, как выясняется, можно проделывать любопытные вещи и с системой типов жабы (например), но всё равно, никакого сравнения.

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

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

И что это? Что-то уверен, сейчас будет перечисление всего что есть в хаскеле.

Как же тогда, интересно, работает Text.Printf?

И как же?

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

>То, что языки, специально предназначенные для массового программирования (Java, C#) и критических по надежности приложений (Ada), являются статически типизированными, ни на что не намекает?

И в Жабе и в COM (C++EE) любой метод при желании можно вызвать через стринг с именем метода и массив Variant-ов c параметрами. Прозреваю что и в C# так. И это неслучайно вообще-то.

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

>Ты наверное не поверишь, но и в статике это делать тоже можно.

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

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

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

Какие?

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

Что приносит сюда статическая типизация? Чем лучше динамической? Тем что она «математична» и является чудом?

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

> И в Жабе и в COM (C++EE) любой метод при желании можно вызвать через стринг с именем метода и массив Variant-ов c параметрами.

И что?

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

>> И в Жабе и в COM (C++EE) любой метод при желании можно вызвать через стринг с именем метода и массив Variant-ов c параметрами.

И что?

Ну это сделано с определенной целью, я полагаю. Интеграция, все дела.

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

И что это?

Как минимум - контроль над сайд-эффектами.

Как же тогда, интересно, работает Text.Printf?

И как же?

Очень хорошо.

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

> Ну это сделано с определенной целью, я полагаю. Интеграция, все дела.

Ну как бы понятно, что рефлексия - полезная вещь. Правда, непонятно причем тут ФП или статическая типизация vs динамическая.

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

>Как минимум - контроль над сайд-эффектами.

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

Очень хорошо

и поэтому все используют fn2,fn3,fn4? наверное реализация и возможна, но без сахара это будет полное убожество.

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

>Какие?

Что приносит сюда статическая типизация? Чем лучше динамической? Тем что она «математична» и является чудом?

Ну вот смотри:

[code] --Haskell: f x = x + 1 someProcFunction $ map f $ someList

;; Lisp: (defun f(x) (1+ x)) (some-proc-function (mapcar f some-list)) [/code]

Ды вот в чем тут дело. Функции someProcFunction и f уже сильно завязаны. Например функция f не может случайно стать функцией складывающей два числа или функцией считывающей что-то из файла. Она уже связана по аргументу со списком someList и по результату с someProcFunction. Если же подобное записано в цикле или в языке с динамической типизацией, то вместо f и соответственно инкремента может происходить вообще все что угодно. Тут с той лишь разницей, что лисп матернется в рантайме, а с циклом просто неверно программа будет работать.

Waterlaz ★★★★★
()
Ответ на: комментарий от Waterlaz
 
--Haskell: 
f x = x + 1 
someProcFunction $ map f $ someList

;; Lisp: 
(defun f(x) (1+ x)) 
(some-proc-function 
(mapcar f some-list)) 
Waterlaz ★★★★★
()
Ответ на: комментарий от anonymous

>Говорить о контроле для языка в котором даже не ясно сразу выполнится map, а потом reduce, или же будет что-то оптимизировано - смешно.

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

Если ты не об этом. То я вообще не понимаю, на кой черт тебе знать, что там компилятор соптимизировал, если результат не изменился?

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

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

Что подразумевается под reduce?

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

и поэтому все используют fn2,fn3,fn4?

Кто «все»? Если кто-то использует хотя бы fn3, это уже признак плохого дизайна; если используется fn4, плохой дизайн становится доказанным фактом.

И что подразумевается под fn? ZipWith? Посмотри на Control.Applicative.

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

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

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

> На Haskell программу надо сначала программу записать, потом выполнить, а потом выловить баги, которые не смогла выловить крутая система типов. При разработке же на Common Lisp программу сначала выполняют (через REPL, это очень просто и быстро), а потом удачный вариант записывают.

Не понял - а на CL программу не пишут?

Почувствуйте разницу...

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

Да, я подозреваю, что в Хаскеле есть REPL (в Ocaml точно есть).

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

Гм. У наиболее популярной реализации Haskell имеется REPL. Который используется именно так: попробовали, не понравилось, попробовали ещё раз, понравившийся вариант записали.

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

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

разве что контролю вида вылетание с оут оф мемори.

И что подразумевается под fn? ZipWith? Посмотри на Control.Applicative.

Зачем? Ни лямбда, ни комбинаторы себя не оправдали. И ведь тоже самое можно проще сделать. Зачем тогда смотреть?

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

Ну и насколько реально и полезно можно его применять, когда загружено, скажем, 50 000 строк кода? Ведь система типов не даст внести какое-нибудь значительное изменение: не дай бог какая-нибудь часть программы станет на пару минут некорректной...

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

> Не понял - а на CL программу не пишут?

Ну, в CL такого понятия вообще нет, если что :) И да, не пишут в традиционном понимании, процесс разработки совершенно другой.

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

>> Не понял - а на CL программу не пишут?

Ну, в CL такого понятия вообще нет, если что :)

CL настолько крут, что умеет выполнять несуществующие программы? %)

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

> CL настолько крут, что умеет выполнять несуществующие программы? %)

Не поверишь, но да.

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

>которые из программы на Хаскеле выловила система типов.

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

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

>Как минимум - контроль над сайд-эффектами.

будет определение что такое функциональная парадигма, и почему она невозможна, например в CL?

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

разве что контролю вида вылетание с оут оф мемори.

Ню-ню.

Ни лямбда, ни комбинаторы себя не оправдали.

Пруфлинк или не было.

И ведь тоже самое можно проще сделать.

Ты хоть можешь сформулировать, ЧТО ИМЕННО можно сделать проще?

Зачем тогда смотреть?

Ну, хотя бы, чтобы понять, что никто не пишет

zipWith7 f as bs cs ds es fs gs
а пишут
f <$> as <*> bs <*> cs <*> ds <*> es <*> fs <*> gs

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

Ну и насколько реально и полезно можно его применять, когда загружено, скажем, 50 000 строк кода?

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

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

Ещё одна черта хорошей системы типов: от того, что ты напишешь что-то ещё, написанное раньше стать некорректным не может.

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

> Ещё одна черта хорошей системы типов: от того, что ты напишешь

что-то ещё, написанное раньше стать некорректным не может.


Как так? Поясню, надо не написать что-то ещё, а изменить то, что написал раньше, ибо раньше была написана херня и ты это понял.

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

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

Ну, вообще-то, если не увлекаться паттерном «_», то порядок паттернов особого значения не имеет. А пропущенные ветки отлично вылавливаются - правда, только ворнингом, но таким ворнингом, в котором можно быть уверенным (то есть, если ты что-то пропустил, то ворнинг будет). Кстати, именно благодаря строгой статической типизации.

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

>> которые из программы на Хаскеле выловила система типов.

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

ЕМНИП нечто похожее есть и в CL. Так что неубедительно.

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

будет определение что такое функциональная парадигма

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

почему она невозможна, например в CL?

Потому самому. В CL, если мой коллега написал какую-то функцию, я не имею ни малейшего понятия, даёт ли она какие-либо сайд-эффекты, и какие. До тех пор, пока не просмотрю весь его код. В Haskell мне достаточно посмотреть на её тип, ну и проверить, не импортировал ли он какой-нибудь unsafe-модуль, для гарантии.

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

Как так? Поясню, надо не написать что-то ещё, а изменить то, что написал раньше, ибо раньше была написана херня и ты это понял.

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

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

>ЧТО ИМЕННО можно сделать проще

написать программу, поддерживать, изменять. использовать ФП.

Ни лямбда, ни комбинаторы себя не оправдали.

Пруфлинк или не было.

Был, был ещё в первой половине прошлого века.

f <$> as <*> bs <*> cs <*> ds <*> es <*> fs <*> gs

Это точно не брейнфак?

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

>что ты напишешь что-то ещё, написанное раньше стать некорректным не может.

То есть существующий код изменить уже практически не реально.

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

написать программу, поддерживать, изменять. использовать ФП.

Тогда от лямбды ты никуда не денешься.

Был, был ещё в первой половине прошлого века.

Пруфлинк или не было.

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

> Если херня в маленьком кусочке, то от того,

что ты его перепишешь, тип измениться не должен.


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

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

То есть существующий код изменить уже практически не реально.

То есть, читать ты не умеешь реально.

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

>ЕМНИП нечто похожее есть и в CL. Так что неубедительно.

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

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

>> ЕМНИП нечто похожее есть и в CL. Так что неубедительно.

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

Не понял. Паттерн матчинг - это динамическая конструкция? Или пришел из динамического языка?

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

>Потому самому. В CL, если мой коллега написал какую-то функцию, я не имею ни малейшего понятия, даёт ли она какие-либо сайд-эффекты, и какие. До тех пор, пока не просмотрю весь его код. В Haskell мне достаточно посмотреть на её тип, ну и проверить, не импортировал ли он какой-нибудь unsafe-модуль, для гарантии.

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

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

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

Какие-то это неправильные пчёлы.

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

Итак можно часами (ну, от размера зависит, можно и сутками) править код без возможности скомпилировать и запустить.

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

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

>Пруфлинк или не было.

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

Тогда от лямбды ты никуда не денешься.

речь про статическую типизацию.

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