Pull to refresh

Comments 54

UFO landed and left these words here
Интересует. Рискните. Желательно, конечно, начать с азов ;)
Haskell — похоже мёртворождённое дитя академиков. Если мы говорим о языках общего назначения (а пропоненты Haskell'я говорят именно об этом), то один из главных показателей — как там с dogfood'ом. И тут Haskell оказывается провалом чуть более, чем полностью: разработчики GHC отказываются от darcs. Если разработчики самого популярного Haskell-компилятора не могут доработать до вменяемого состояния свой собственный проект (самый популярный Haskell-проект при этом!), то ясно что все разговоры о том, что Haskell может быть не медленнее, чем C — фикция. В теории — может, на практике… увы.

Haskell — нишевой язык (как bash или PHP) и вопрос состоит в определении подходящей ниши, а не в использонии его «не по назначению»…
UFO landed and left these words here
Много вы знаете популярных вещей, использующих Haskell? А ведь этому языку скоро 20 лет стукнет. Примерно как python'у или erlang'у.

Я не против того, чтобы использовать Haskell там, где он хорошо ложится на задачу (скажем интеллектуальная обработка массива данных — хотя я думаю тот же erlang будет более подходящим выбором). Но зачем на нём писать вещи, для которых он не предназаначен? Нафига использовать Haskell для GUI?
UFO landed and left these words here
GUI на Haskell писать как раз достаточно удобно — равно как и, скажем, на Prolog (см. XPCE для SWI-Prolog); во всяком случае куда удобней чем на C++ (хотя и не так удобно как на Tcl/Tk)

достаточно понять, что UI — это реактивная событийная модель, которая замечательно выражается в терминах именно ФП (см. Reactive Элиотта); ну а графическая часть по определению должна описываться декларативно (см. тот же WPF в сравнении с WinForms)

другое дело, что нет доведённых до ума законченных GUI-библиотек для Haskell — ну так это потому, что никто этим специально не занимался
Кстати по поводу GUI. Это частый вопрос, потому что GUI традиционно ООП и мне в том числе самому было непонятно, как вообще это выглядит на Хаскеле. Однако всё не так страшно.
Ну и соглашусь с Lazin. Haskell позволяет проще писать корректные программы (ещё большую проверку может позволить разве что использование dependent types, но это относительно новая область, и вот там действительно академические языки), а ленивость и функицональные возможности в целом сильно сокращают код. За всё это, конечно, приходится платить, но плюсы позволяют быстро написать прототип программы. Некоторе, кстати, именно для этого его и используют.
интересней было бы сравнить GUI на FRP/AFRP (тот же FranTk) с чисто событийным Tcl/Tk. особенно учитывая тот факт, что возможности построения eDSL для Haskell весьма неплохи (от комбинаторов до квазиквотации): С++/Tk-подобных извращений писать не придётся

а по поводу корректных программ стоит добавить, что подстановочная модель позволяет использовать формальные методы матлогики для статической верификации приложения: в императивных языках о таком можно только мечтать
> Нафига использовать Haskell для GUI?

Ибо корректнее, быстрее и проще. (Пока что только в теории, но мы ситуацию изменим. :))

Все наезды не имеют никакой основы. SPJ недавно сознался, что «we tried to avoid success at all costs».
lolwut? то, что это академический язык — как-то отменяет то, что его надо изучать, для общего развития?

вы в своём комментарии боретесь с выдуманной проблемой
я думаю, Haskell это самый лучший академический язык из существующих, т.к. даёт огромный insight и при этом позволяет писать реальные программы (с GUI, сетью, БД и т.п.)
Знаете — и на bash'е можно написать нечто, что будет работать с GUI, с БД и прочим. Но почему-то никто так не делает (а если и делает, то это попадает не в серию, а в копилку курьёзов). То же самое и с Haskell — если вам нужно изобразить что-нибудь невероятно красивое и «правильное» — вы можете взять Haskell, если вам нужен практический результат — вы возьмёте Python, Ruby или там C++…
bash не представляет академической ценности

аналогия некорректна
Академичская ценность не представляет практитческой ценности.
I LOLd.

Если бы не «практическая ценность академической ценности», вы бы до сих пейсали на ассемблере.
не надо ля-ля, языки высокого уровня возникли как раз из практических соображений, а не как академическое упражнение…
ага, а теперь в современных языках высокого уровня начинают появляться ФВП, замыкания, иммутабельные структуры данных (System.String) и даже монады (System.LINQ)

и полвека не прошло!
надо полагать, ни в школу, ни ВУЗ вы не посещали

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

клмментом выше — был сарказм
А мне не интересен тупой сарказм(т.к. основан на ложных фактах).
каких ещё фактах?

вам неизвестен смысл слова «сарказм»?
Я не могу согласиться.
Да, он достаточно академичен, но интерес к нему постепенно растёт, а его возможности всё более и более переходят в mainstream.
Сам он mainstream'ом скорее всего не станет, но мертворождённым его назвать трудно, хотя смотря что иметь в виду. Популярности C# ему вряд ли сыскать.
Это, конечно, здорово: взять один test-case, и по нему сказать «язык — фейл».

Если интересно, то у Хаскеля медленное IO в стандартной библиотеке. Библиотеки ByteString/Binary ситуацию изменяют, но не во всех случаях.

Будущее за комонадическим IO или за iteratee-based IO. ;)
Честно говоря, не понял я, почему за ними будущее.
У меня есть некоторые претензии/вопросы:
1. Что ни говори, а в чистом языке тип a -> b -> () не может (не должен) иметь побочных эффектов, что бы он там ни принимал
2. Скрытое возвращение результата изменения внешнего мира предлагается делать при помощи mapOI, которая примет функцию f :: OI a -> b, а вернёт f :: OI (OI a) -> OI b. Т.е. f теперь как бы принимает копию окружения и возвращает новую. Но ведь f сам ничего не возвращает, а mapIO ничего не знает об f, следовательно реализация mapOI может разве что скопировать окружение.
3. Теперь все функции с побочными эффектами должны иметь тип OI a -> b, не эстетично
4. IO a имеет вполне понятный смысл — вычисление значения типа a, чего не сказать об OI a -> b

Я даже для State с трудом представляю, как менять этот самый State из функции, а не снаружи при помощи специально написанной local, потому что duplicate всего лишь копирует (о чём я в пункте 2 написал).
У меня тоже куча вопросов на самом деле. :) Иногда хочется, чтобы в Хаскеле появился effect typing (или зависимые типы, или и то, и другое) или хотя бы уникальные типы (чисто из практических соображений).

> 1. Что ни говори, а в чистом языке тип a -> b -> () не может (не должен) иметь побочных эффектов, что бы он там ни принимал

В случае с OI будет то же самое.

> 2. Скрытое возвращение результата изменения внешнего мира предлагается делать при помощи mapOI, которая примет функцию f :: OI a -> b, а вернёт f :: OI (OI a) -> OI b. Т.е. f теперь как бы принимает копию окружения и возвращает новую. Но ведь f сам ничего не возвращает, а mapIO ничего не знает об f, следовательно реализация mapOI может разве что скопировать окружение.

Пользователю не нужно ничего знать о mapOI, как и о enableOI. Кстати, в IO-монаде двойственные этим функциям fmap и join тоже спрятаны подальше. Вообще, почему-то в Хаскеле монады определяются через return и bind, а не через return, fmap и join.

> Теперь все функции с побочными эффектами должны иметь тип OI a -> b, не эстетично

А помоему, довольно понятно: OI Handle -> Char это функция, которая возвращает Char из файла. Это скорее «по-другому» (а так — вполне эстетично).

Вообще же под «комонадическим IO» я имел в виду dataflow-программирование (и в частности FRP). :)
В случае с OI будет то же самое
А как же тогда осуществлять побочные эффекты?
Вообще, почему-то в Хаскеле монады определяются через return и bind, а не через return, fmap и join
Думаю, в немалой степени из-за do-notation. Там напрямую используются >>= и >>, а так будут лишние действия. Хотя не знаю, будет ли через fmap/join медленнее.
А помоему, довольно понятно: OI Handle -> Char это функция, которая возвращает Char из файла. Это скорее «по-другому» (а так — вполне эстетично).
Я тоже об этом подумал :)
Но тогда можно подумать, что
getChars :: OI Handle -> OI Handle -> (Char, Char)
Возвращает (Char, Char) из двух файлов, а это не так.
Да и OI a обязан быть последним аргументом.
Или я что-то путаю?
Ну т.е. понятно, что getChars f1 f2 = (getChar f1, getChar f2), но как этот getChars в cobind передать?
> А как же тогда осуществлять побочные эффекты?

Не понял вопроса. :( Во время вычисления coeval разве не будут производиться side-effecting операции?

> Думаю, в немалой степени из-за do-notation. Там напрямую используются >>= и >>, а так будут лишние действия.

Да, наверное.

> getChars :: OI Handle -> OI Handle -> (Char, Char)
> getChars x y = coeval (getChar x =>> \a -> getChar y =>> \b -> (a,b))

По-моему, оно. Правила те же, что и у монад, только все «наоборот». Чтобы передать getChars в cobind, нужна немного другая функция:

getCharsOI :: OI Handle -> OI Handle -> OI (Char, Char)

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

> getChars :: OI Handle -> OI Handle -> (Char, Char)
> getChars x y = coeval (x =>> getChar =>> \a ->
> y =>> getChar =>> \b -> (coeval a, coeval b))

И сразу становится видно, как передать getChars в cobind (убрать применение coeval).
Не понял вопроса. :( Во время вычисления coeval разве не будут производиться side-effecting операции?

Я скорее про «философическую» сторону вопроса.
Обычный IO воспринимается, как World -> (a, World). Т.о. хотя мы в сам World залезть не можем, реализация — может, и putChar можно написать так:
putChar c w@(World (Heap h) ... (Descriptors d)) = case lookup d stdout of
    Just f -> Success ((), World (replaceInHeap h f c) ... (Descriptors d))
    Nothing -> Exception "hmm..." ((), w)

В комонадах же сначала вызывается enableOI, который дублирует окружение, а затем mapOI, который из функции OI Handle -> Char делает OI (OI Handle) -> OI Char.
Цитата: «The operational effect of co-ext f allows a function f, which accepts arguments that may depend upon the current IO environment, to propagate the IO environment as an implicit parameter along with its result»
где co-ext f = (mapOI f).enableOI
Т.е. некий базовый putChar должен бы иметь тип OI (OI Char) -> OI () и использоваться без mapOI, но тогда неясно, как его использовать внутри своих функций.

Пока писал, подумалось, что Handle может внутри себя содержать все нужные данные (т.е. это не дескриптор, а сами данные), тогда coeval stdin возвращает некоторые данные, а также может выполнить некоторые изменения в окружении (что за изменения — скрыто в реализации OI), а getChar, зная внутреннее устройство Handle достаёт оттуда символ.
Вариант.
Соответственно main будет иметь тип coMain :: OI () -> ()
coMain env = env =>> coGetChar stdin =>> coPutChar stdout

не так давно (лет 8-10 назад) говорили о том что функциональноe программировние — мертворожденное дитя академиков…

Пока не появился гугл с mapreduce и bigtable…

И что — mapreduce и bigtable возродили Prolog, Lisp или тот же Haskell? Да нифига подобного: они написаны с использованием старого доброго C/C++, насколько не известно. Я не говорю о том, что Haskell не содержит интересных идей и что его не нужно изучать: для самообразования — полезно. Примерно как и изучение латыни. Но ни Haskell, ни латынь вы не сможете применить в практической дейтельности — если только вы не попадёте в определённую небольшую нишу. А идеи и отттуда и оттуда переходят в другие языки и будут использоваться.

Я не против того, чтобы изучать Haskell или латынь — я против того, чтобы пытаться приспособить их к задачам, для которых они не годятся.
mapreduce и bigtable возродили интерес к функциональному программированию. Это важнее. А где конкретно — в прологе, хаскеле или эрланге — дело десятое.

mapreduce и bigtable показали что хорошее образование дает возможность посмотреть на вещи с другой стороны и решит проблему таким образом, каким невозможно обычным путем…

А насчет задач для которых ФП годится — функциональное программирование всего лишь другая парадигма. С помошью него можно решать точно те же задачи. Вас же не удивляет что обьектно ориентированное программирование уживается с структурным…

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

4.2

Я сейчас использую Хаскель на практике.
У троллей, мало перспектив, в отличии, скажем, от VoidEx=)
VoidEx — умный тролль, у него перспектив много ;-)
Желаю успехов и с нетерпением ожидаю заметок про haskell!
Статьи по Хаскелю лишними не будут. На практике конечно я лично врядли буду использовать, но как пищу для ума и из любопытства с удовольствием.
Жду с нетерпением. Хочу нормально научиться настраивать xmonad.
Спасибо! Я только начал читать про haskell и пытаться на нём что-нибудь сваять. :) Ждём новенького, горяченького материальчика. :)
Милый, но подробный туториал по Хаскеллу есть тут: learnyouahaskell.com/ (с картинками и примерами)
Но статья в любом случае нужна, будем ждать!
и вот мне тоже кажется, что всякие основы можно найти в учебниках.

а вот что былобы интересно — так это иллюстрация уже живого, рабочего кода для чата, с объяснениями смысла каждой конструкции (ну и при необходимости лирическими отступлениями на тему что это означает вообще).
Only those users with full accounts are able to leave comments. Log in, please.