Здравствуйте, alex_public, Вы писали:
_>Речь не о том. Я имел в виду, что когда я заглянул в реальные примеры кода (не своего), то увидел что там кода "внутри монад" больше по объёму чем вне их. Соответственно возникает вопрос: "а нафига тогда так отделять было?". Ведь цена такого отдельния тоже есть — не слишком удобный синтаксис внутри монад.
Не нравится специальный синтаксис монад -- никто не заставляет им пользоваться
Здравствуйте, alex_public, Вы писали:
_>Да, и кстати дело не в GUI. Как я понимаю вообще вся внешняя работа (включая запись в файл) вынесена в монады. Соответственно инструмент получается неудобный почти для всех практических задач.
Вся внешняя работа вынесена в монаду IO ("монада Йо" (c) lurkmore)
Здравствуйте, alex_public, Вы писали:
_>Нуу грубо говоря мы можем записать в генератор (или в map) чтение/запись в файл и никаких проблем не будет. Естественно это будет не "чистая" операция. Но мы же стремимся не к идеалу какому-то абстрактному, а к решению реальных задач. А "чистота" нам полезна только для удобства разработки, для уменьшения ошибок.
А кто мешает так писать на хаскеле? mapM спасёт отца русской демократии.
_>Эээ, это тут оффтопик конечно. Но Tcl/Tk — это недоинструмент по сравнению с современными мощными библиотеками с визуальными редакторами, нативными контролами и т.д. Да ну и главное: GUI — это как бы не главная цель, а просто один из обязательных параметров.
Оно конечно, недоинструмент, но некоторые вообще на delphi'ях/C-builder'ах гуи валяют.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, vshabanov, Вы писали:
V>>Судя по всему, ты написал на хаскеле дубовый императивный GUI-код, совершенно такой же, как на питоне. Вот по-этому разницы особой нет. Попробуй пописать что-нить более существенное, чем дергание сишных библиотечных ф-ий.
_>Нуу GUI в виде "мегамонады" — это я в основном не сам писал, а посмотрел примеры к библиотечке. А сам я писал естественно вообще без этого. Так, всякия математические фокусы попроверял ради интереса. Единственно что действительно "цепляет" — это ленивость встроенная в язык, а не путём "eval". Кажется в Maple такое было ещё помнится... Но неабстрактные практические применения что-то так и не пришли в голову.
Ленивость позволяет меньше думать над кодом. Пишешь как пишешь, в каком хочешь порядке, а вычисляться будет как надо.
Из практики -- позволяет очень много чего обрабатывать как списки, а не в цикле, при этом не выжирая всю память. Какой-нить (putStr . map toUpper =<< getContents) может хоть на гигабайтном вводе работать.
Также можно не задумываясь писать и использовать всякие (forM_ [1..n] ...), никакого списка в памяти не будет (а последние версии ghc вроде вообще такой код могут до обычного цикла соптимизировать).
В общем, у ленивых вычислений выше выразительная сила. И в хаскеле они применяются везде, только это не очень заметно (он же ленивый по-умолчанию)
V>>А что у вас за задачи, что требуется быстродействие и при этом используется питон?
_>Питон используем во всех внутренних утилитах/процессах и для серверных скриптов на сайтах.
Для утилит хаскелл в принципе самое то (если, конечно, недостаточно sed/awk/grep/10 строк perl). Хотя и для остального хорошо подходит, просто с утилитами проще всего попробовать.
V>>"генераторы, условия, шаблоны" -- это что?
_>Хы, уже 3-ий кто спрашивает. ))) Я там чуть выше ответил кому-то.
V>>Сопоставление с образцом конечно слабее унификации (но мощнее серии if/then/else). Только вот в хаскеле можно проверить полноту сопоставления (и вообще правильность типов), а в прологе нет. Также со всякими ViewPatterns/PatternGuards/RecordWildcards сопоставление с образцом уже не кажется таким слабым.
_>Согласен) Я так и сказал что слабее прологовского и немного сильнее if/else. Просто я как бы ждал от языка слишком многого. Т.е. если сопоставление с образцом, то тогда уж уровня Пролога. Это же "великий хаскель". )))
Он не то, чтобы великий. Практически все, что в нем есть, где-то реализовано лучше (ну кроме ленивости/type class-ов), просто в хаскеле это все в одном месте.
V>>Сечения используются довольно часто. Ты попробуй попиши код с ф-иями высшего порядка и поймешь.
_>Нуу функторы делают тоже самое в любом языке (где можно оперировать функциями). Тут просто это красивее и естественнее. Но как бы я не особо часто пользуюсь функторами в таком стиле.
Тут дело в удобстве. Если где-то надо писать отдельный класс с оператором, а где-то просто скобочки с галочками поставить, то там где проще, там и начинаешь пользоваться. В том же С++ не часто делается new, т.к. сразу надо за памятью следить, а в java/c# над этим никто и не задумывается особо.
V>>Монады -- не встроенный язык. Это type class с небольшим сахаром для одной ф-ии. И служат они не только для IO. Хотя в дубовом IO (последовательный вызов библиотечных ф-ий) без использования ФВП и прочих хаскельныйх фишек могут выглядеть даже похуже питона. Только такой код на хаскеле почти не пишется (если только в примерах работы с GUI библиотеками .
_>Как бы не только GUI же получается но и любые "внешние операции"... Т.е. их получается "слишком много" в реальные приложениях. Я посмотрел там всякие примеры не образцового математического кода, а чего-то реального...
Не сказал бы, что монады вообще напрягают и чего-то там слишком много. Кроме ввода/вывода/вызова внешних ф-ий, есть еще и логика, ради которой все эти вызовы делаются. И вот эта логика обычно чистая.
Т.е. код внешне может выглядеть каким-то большим do, но реальной императивности там почти нет.
V>>А пример записи императивного и функционального кода в питоне в едином стиле можно? В питоне вообще expression и statement -- разные вещи.
_>Нуу грубо говоря мы можем записать в генератор (или в map) чтение/запись в файл и никаких проблем не будет. Естественно это будет не "чистая" операция. Но мы же стремимся не к идеалу какому-то абстрактному, а к решению реальных задач. А "чистота" нам полезна только для удобства разработки, для уменьшения ошибок.
В хаскеле тоже можно, только потом придется sequence добавить, чтобы все-таки выполнить список действий:
sequence_ [do print x; print y | x <- [1..5], y <- [1..5]]
V>>Ага, а еще ленивые вычисление позволяют тебе писать код в любом порядке, как удобно, а не как будет вычисляться. Т.е. если ты написал x = y where y = x, ты уже используешь ленивые вычисления.
_>Ага, удобно для символической математике. В Maple помнится тоже были всякие удобные вещи из этой области. Но я как бы математическим софтом не занимаюсь, поэтому на практике пока не особо вижу пользу.
Математическим софтом вообще мало кто занимается. Это удобно и при обычном программировании. По другому начинаешь на код смотреть -- не "так, тут а=foo, теперь b=bar, ага, возвращаем baz a b", а "ага baz a b", а что такое 'a'/'b' можно зачастую и не смотреть, если название более менее осмысленное
V>>Для GUI посмотри на Tcl/Tk. Удобнее вроде пока ничего не придумали (правда выглядит плохо, но все равно стоит ознакомиться). Ну и попробуй напиши какую-нить логику к твоему GUI, может мнение о хаскелле поменяется )
_>Эээ, это тут оффтопик конечно. Но Tcl/Tk — это недоинструмент по сравнению с современными мощными библиотеками с визуальными редакторами, нативными контролами и т.д. Да ну и главное: GUI — это как бы не главная цель, а просто один из обязательных параметров.
_>Что касается Хаскеля, то как бы я на самом деле не говорю что это плохой язык. Просто не такой хороший, как я о нём когда-то думал. Ну и как бы неполезный на практике в большинстве случаев.
Ну неполезность, она от задач зависит. Возможно, если есть куча наработок/нужных библиотек на питоне, от хаскелла особого толка и не будет. Хотя, у кого как http://habrahabr.ru/company/selectel/blog/135858/
Здравствуйте, jazzer, Вы писали:
J>А что такое ПП? И, чтоб 2 раза не вставать уже — что такое "(a ~ b) => ..."?
ПП — Параметрический полиморфизм. Грубо говоря, одна реализация для разных типов данных.
Второе объяснять долго, это фишка в последних версиях GHC, чисто хаскельная, в общем-то.
J>Интересно потестить возможности плюсовых шаблонов.
ПП в плюсах нет.
Есть неполноценная имитация — шаблоны. Когда функция для каждого типа пишется отдельно, но макросистема (т.е., шаблоны) позволяет один раз показать, как оно должно выглядеть, а дальше компилятор пишет их сам.
Re[3]: Мифический Haskell
От:
Аноним
Дата:
16.02.12 17:58
Оценка:
Здравствуйте, alex_public, Вы писали:
А>> Спрашивается — а на кой хрен вообще программировать GUI на Хаскелле? Да еще используя биндинги к чужеродным библиотекам, а не родную для Хаскелля идеологию functional reactive programming? Для GUI есть всякие там Tcl/Tk, идеально под эту задачу заточенные.
_>Я оценивал как язык справляется с этой задачей — он же позиционируется как универсальный...
Вот именно, что универсальный. А задача-то узкоспециализированная.
_>Да, и кстати дело не в GUI. Как я понимаю вообще вся внешняя работа (включая запись в файл) вынесена в монады.
Что значит "вынесена"? Кажется, вы не понимаете, что такое монады.
_> Соответственно инструмент получается неудобный почти для всех практических задач.
Странные у вас практические задачи.
А>> Функциональный код на Питоне?!? Не смешите мои панталоны! Какой такой "функциональный" код на языке, где expression и statement это разные вещи?
_>Там естествено нет "доказанной чистоты". ))) Но зато отлично сочетаются чисто функциональные практики с прямыми вызовами API.
Какие такие "функциональные практики"? Там полноценной лямбды нет. Закопать!
А>> Человеку, программирующему гуйню, ничего сложнее Tcl и не нужно по определению. Меня, честно говоря, сильно удивляет, как это жирный и сложный C++ (он на порядок сложнее того же Хаскелля) оказался в списке ваших инструментов. Не гуйнячий же язык, совсем не гуйнячий.
_>А мы как бы и не только GUI создаём — это только небольшая, но необходимая часть любого проекта. )))
А я вот за всю свою жизнь вообще ни одного гуя не нарисовал. И потребности такой никогда не возникало. Может, не такая уж это и "необходимая" часть любого проекта, а?
Тем более что на кой хрен надо делать гуй на том же языке, что и логику? Все нормальные люди гуй и логику всегда разделяют.
Здравствуйте, m e, Вы писали:
MM>>Я как-то приводил пример: http://migmit.livejournal.com/32688.html
ME>поставь туда null вместо одного из Cons-ов -- и компилятор жизнерадостно сховает неверную программу
Ты убеждаешь меня, что хаскель лучше шарпа и жабы? Спасибо, я знаю.
Здравствуйте, Don Reba, Вы писали:
DR>Здравствуйте, MigMit, Вы писали:
MM>>Как минимум, конструкция if...then...else является ленивой вообще везде.
DR>Не знаю как сейчас с OpenCL, но Brook на картах ATI параллельно вычислял обе ветки.
Здравствуйте, alex_public, Вы писали:
_>Я ответил в сообщение выше. Речь была про работу со списками.
Ясно, спасибо. Да, в питоне компрехеншены спижжены именно из Хаскеля.
_>А как на счёт техники отката и отсечения из Пролога в сопоставление с образцом в Haskell?
Не понял. Как техника отката относится к паттерн-матчингу?
_>Эээ, я могу вызывать какие-то системные функции не из монад? Возможно я в чём-то не разобрался конечно...
Во-первых, не из монад, а из IO. Только. Монад гораздо больше.
Во-вторых, можешь. Хаскельный FFI позволяет объявить внешнюю функцию как чистую. Другой вопрос, что если она таки нечистая, то ты поимеешь проблем (от непредсказуемости порядка вычислений, например).
_>Да, но у нас же не только GUI идёт в монадах, но и любые "внешние операции". Т.е. там в файл записать и по сети передать и так далее. Если мы вычтем и gui и всю эту непосредственную работу, то что остаётся то? Несколько алгоритмических кусков и всё? Я к тому что получается что код внутри монад будет очень сильно преобладать по объёму в любом реальном приложение...
По-моему, ты не писал реальных приложений вообще.
Мне приходилось работать в геймдеве. Сейчас я занимаюсь антивирусами.
И там, и там, объём того, что можно назвать "внешними операциями" безумно мал по сравнению с манипуляциями внутренними структурами данных.
_>Само собой что ленивость можно реализовать в любом языке. Тут основное преимущество что она полноценно встроена в синтаксис языка. Но опять же на таком уровне она и нужна не так что бы часто. Т.е. я вспоминая свои проекты не вижу особо где она могла бы добавить реальных преимуществ.
Естественно. В проекте на C++ ленивость никому нафиг не нужна.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, Klapaucius, Вы писали:
K>>Для справки, в вашем списке языков примерно 0 наименований, которые подготовили бы вас к реальному функциональному стилю в котором пишут на хаскеле и примерно 12 наименований, которые бы затруднили понимание и написание кода на хаскеле. Именно это и имеют в виду, когда говорят, что хаскель "сложный": привычные по другим языкам "очевидные" умолчания и практики на пользу не пойдут.
_>Эээ, Lisp — это тоже анти Хаскель? )))
Лисп — это такой суровый императивный язык с некоторыми функциональными возможностями. Написанию кода в функциональном стиле он совершенно не способствует. Теоретически, это возможно, но вот Женя Кирпичёв, например, даже на Java умудрялся писать в функциональном стиле.
MM>>>Я как-то приводил пример: http://migmit.livejournal.com/32688.html ME>>поставь туда null вместо одного из Cons-ов -- и компилятор жизнерадостно сховает неверную программу MM>Ты убеждаешь меня, что хаскель лучше шарпа и жабы? Спасибо, я знаю.
нет, я убеждаю тебя, что написанный тобой код на жабе и шарпе не работает -- не проверяет статически равную длинну векторов
кстати, его похоже можно обламать и иным способом, кроме null
а еще он может быть дыряв даже на хаскеле с расширениями
Здравствуйте, MigMit, Вы писали:
MM>Здравствуйте, jazzer, Вы писали:
J>>А что такое ПП? И, чтоб 2 раза не вставать уже — что такое "(a ~ b) => ..."?
MM>ПП — Параметрический полиморфизм. Грубо говоря, одна реализация для разных типов данных.
реализация в каком смысле?
Если в текстовом — то это шаблоны.
А если в бинарном — то это type erasure уже (void* в экстремальном случае)...
MM>Второе объяснять долго, это фишка в последних версиях GHC, чисто хаскельная, в общем-то.
J>>Интересно потестить возможности плюсовых шаблонов.
MM>ПП в плюсах нет.
MM>Есть неполноценная имитация — шаблоны. Когда функция для каждого типа пишется отдельно, но макросистема (т.е., шаблоны) позволяет один раз показать, как оно должно выглядеть, а дальше компилятор пишет их сам.
Это да, но он еще может кой-чего на типах посчитать в процессе.
Я посмотрел твой пост про скалярное произведение, мало что понял, если честно — если длина известна во время компиляции, то есть более простые способы ее проверить безо всяких консов...
Есть какая-нть задача, которая решается только ПП и другого более прямого решения на С++ нету?
Здравствуйте, jazzer, Вы писали:
MM>>ПП — Параметрический полиморфизм. Грубо говоря, одна реализация для разных типов данных. J>реализация в каком смысле? J>Если в текстовом — то это шаблоны. J>А если в бинарном — то это type erasure уже (void* в экстремальном случае)...
В бинарном.
Аргумент про type erasure не понятен для языков, компилирующихся в натив. В ассемблерном коде типов всё равно нет.
Вот в Java, где типы сохраняются в байткоде, там да, там type erasure приводит к безумным спецэффектам — скажем, если есть interface I<T>, то нельзя одновременно в одном классе реализовать I<A> и I<B>. В шарпе можно, там не на стирании типов это дело завязано.
J>Я посмотрел твой пост про скалярное произведение, мало что понял, если честно — если длина известна во время компиляции, то есть более простые способы ее проверить безо всяких консов...
А она неизвестна. Известно, что она ОДИНАКОВАЯ.
J>Есть какая-нть задача, которая решается только ПП и другого более прямого решения на С++ нету?
Здравствуйте, vshabanov, Вы писали:
V>Ленивость позволяет меньше думать над кодом. Пишешь как пишешь, в каком хочешь порядке, а вычисляться будет как надо.
Возможно стоит ещё посмотреть это. Есть какие-нибудь интересные примеры "правильного" кода, но при этом не из абстрактной области, а из реальных приложений?
V>Из практики -- позволяет очень много чего обрабатывать как списки, а не в цикле, при этом не выжирая всю память. Какой-нить (putStr . map toUpper =<< getContents) может хоть на гигабайтном вводе работать. V>Также можно не задумываясь писать и использовать всякие (forM_ [1..n] ...), никакого списка в памяти не будет (а последние версии ghc вроде вообще такой код могут до обычного цикла соптимизировать).
Кстати, что касается ленивости в списках, то в том же Питоне есть некая забавная попытка ленивости — две отдельных функции range и xrange.
V>Для утилит хаскелл в принципе самое то (если, конечно, недостаточно sed/awk/grep/10 строк perl). Хотя и для остального хорошо подходит, просто с утилитами проще всего попробовать.
У нас много сложных процессов. Правда у Питона в данном случае ещё преимущество в быстрой правке (не компилируемые программки).
V>Не сказал бы, что монады вообще напрягают и чего-то там слишком много. Кроме ввода/вывода/вызова внешних ф-ий, есть еще и логика, ради которой все эти вызовы делаются. И вот эта логика обычно чистая.
Во многих приложения сама логика часто реализуется в виде набора вызовов системных функций. Т.е. даже дело не в императивности (возможно это и можно было под функциональных стиль подвести), а именно в том что вызовы системы, а это в Хаскеле "не чистое". )))
V>В хаскеле тоже можно, только потом придется sequence добавить, чтобы все-таки выполнить список действий: V>sequence_ [do print x; print y | x <- [1..5], y <- [1..5]]
Воо, это уже интереснее. ) Но в том же Питоне оно у нас без лишних слов работает. Но в любом случае посмотрею на эту sequence_...
V>Ну неполезность, она от задач зависит. Возможно, если есть куча наработок/нужных библиотек на питоне, от хаскелла особого толка и не будет. Хотя, у кого как http://habrahabr.ru/company/selectel/blog/135858/
Интересно. ) Хотя если у них затык в быстродействие был, то я бы на их месте перешёл на C++11... Ещё про OCaml или D можно было бы подумать, но только в рамках "поиска и фана". А вот C++11 (если конечно найти реальных специалистов) дал бы гарантированный результат.
Что касается нас, то кучи своих библиотек на Питоне у нас может и нет. Но допустим для сборки проектов (а они бывают сложные, многоступенчатые, с тестами, сборками хелпов, языков, инсталляторов и т.п.) у нас используется scons — скрипт сборки представляет собой просто нормальную Питон программу, работающую в особом окружение. Потом у Питона есть биндинги ко множеству полезных нам библиотек: криптография, гуи, сеть, базы данных.
О, кстати, интересно... А кто-нибудь использует haskell в качестве серверных скриптов? По идее там многие недостатки будут скрыты за допустим fastcgi интерфейсом или чем-то подобным...
Здравствуйте, Аноним, Вы писали:
_>>Я оценивал как язык справляется с этой задачей — он же позиционируется как универсальный...
А> Вот именно, что универсальный. А задача-то узкоспециализированная.
GUI — это явно не ускоспециализорованная задача. ))) Ну разве что если вы программируете микроконтролёры и т.п... )))
А> Какие такие "функциональные практики"? Там полноценной лямбды нет. Закопать!
Хыхы, а какие тогда на ваш взгляд есть языки с нормальной поддержкой функционального программирования? )
А> А я вот за всю свою жизнь вообще ни одного гуя не нарисовал. И потребности такой никогда не возникало. Может, не такая уж это и "необходимая" часть любого проекта, а?
Для наших проектов это необходимая часть. )
А> Тем более что на кой хрен надо делать гуй на том же языке, что и логику? Все нормальные люди гуй и логику всегда разделяют.
Разделять (логически) — это одно. А использовать для них разные инструменты (и плюс неизбежные переходники делать) — это только от бедности используемых инструментов. К счастью у моих команд в руках инструменты позволяющие и просто создавать быстрый системный код с логикой и быстро создавать красивые интерфейсы.
Здравствуйте, alex_public, Вы писали:
_>О, кстати, интересно... А кто-нибудь использует haskell в качестве серверных скриптов? По идее там многие недостатки будут скрыты за допустим fastcgi интерфейсом или чем-то подобным...
А зачем это надо, если есть тот же warp, например?
(ссылка немного старовата уже правда)
Здравствуйте, MigMit, Вы писали:
MM>Ясно, спасибо. Да, в питоне компрехеншены спижжены именно из Хаскеля.
Хы, а Питон не раньше его появился на свет случаем? )))
Да, кстати, там ещё guard'ы Хаскеля выглядят буквательно так же. Только вместо запятой в Питоне "if".
MM>Не понял. Как техника отката относится к паттерн-матчингу?
Как это какое? Это как раз основное преимущество Пролога в этой области. Без этого сопоставление с образцом является только синтаксическим сахаром к if/else лестнице. А с ним получается мощнейший инструмент. Ну на самом деле это просто у меня были завышенные ожидания к Хаскелю, что типа там собрали всё лучшее и если уж есть сопоставления с образцом, то "максимальное, прологовское". )
MM>Во-вторых, можешь. Хаскельный FFI позволяет объявить внешнюю функцию как чистую. Другой вопрос, что если она таки нечистая, то ты поимеешь проблем (от непредсказуемости порядка вычислений, например).
Хм. Интересно. Я так понимаю что по умолчанию все системные функции объявлены как нечистые и подобные действия — это типа нарушения практик?
Здравствуйте, MigMit, Вы писали:
MM>Лисп — это такой суровый императивный язык с некоторыми функциональными возможностями. Написанию кода в функциональном стиле он совершенно не способствует. Теоретически, это возможно, но вот Женя Кирпичёв, например, даже на Java умудрялся писать в функциональном стиле.
Нууу у нас и STL с частью Boost'а можно обозвоать функциональным стилем. ))) Только от этого C++ не становится функциональным языком. )
Но вот то что Lisp императивный — это довольно неожиданная новость. )))