Обсуждение:Haskell
Материал из Lurkmore
Добавьте эталонную попаболь "Роман рассказал, что в свое время интервьюировал не меньше двух десятков хаскеллистов в Киеве, и практически никто не смог во время интервью решить такую задачку: есть длинный список чисел, надо найти их среднее арифметическое за один проход по списку и О(1) памяти. Cходу я тоже не смог, при требовании сделать на бумажке в интервью отказался бы. " http://nponeccop.livejournal.com/449682.html
Программировать на Хаскеле - это всеравно, что чинить автомобиль через выхлопную трубу!
Примеры, с помощью которых любители хаскеля доказывают преимущество хаскеля, зело бесполезны. Витринный случай -- кусок кода сишного и кода хаскельного, который якобы реализует qsort. Проблема в том, что там сравниваются реализации разных алгоритмов. Хаскельный код сортирует списки, а не массивы, и использует голову списка для разбиения его на два -- плохое (O(N^2)) поведение на упорядоченных данных, часто встречающееся в реальной жизни, гарантировано. Во-вторых, правильно написанная qsort использует лишь O(log N)[1] дополнительной памяти, сколько использует хаскельный код -- одному Б-гу известно, а алгоритмы с разными O() -- это разные алгоритмы и есть. Поэтому приведенный хаскельный код гарантированно не попадет в продакшн и является лишь игрушкой. На самом деле на хаскеле можно написать настоящую in-place quicksort, но с использованием монад и выглядит это уродливее, чем код сишный. Все это хаскеллофаги отлично знают, но троллинга ради и чтобы не отпугивать новичков, приводят короткий и бесполезный код. Я считаю, нужно добавить.
- Во-первых, то, что хаскельный код сортирует списки, есть одно из его важнейших преимуществ - он будет работать на всем, имеющим класс Ord(а это из коробки люые числа, символы, строки плюс можно определить операции сравнения для любого своего типа данных и пользоваться квикосртом)- как бы полиморфизм, аналогичный код на сишечке вообще непонятно как делать без километров бойлерплейта, на крестах - шаблоны(OH YEAH BABY). Насчет использования головы списка для его разделения - так вообще бред, что там в сишкомирке сейчас принятно брать для медианы? Православен только вариант с псевдослучайным разбиением, но он сожрет столько ресурсов, что не обрадуешься. Все остальные способы разбиения стабильно просасывают на каком-либо типе данных(в случае реализации квиксорта на хаскелле - отортированный в обратную сторону список), ничего не поделаешь. В третьих, средняя сложность квиксорта - (N * log N), авторитетное мнение специалиста, не знающего даже этого, несомненно имеет большое значение.
- Для сортировки списков оптимателен и надежен мердж-сорт. Списки квиксортом сортировать могут только тролли или умственно отсталые. Школота, иди нахуй.
- Ебать дебил. И у мерджсорта и у квиксорта средняя сложность O(n log n). Да мердж устойчивый, но он и памяти значительно больше жрёт. Дядя Хоар создал один из самых быстродействующих и чаще всего ИСПОЛЬЗУЕМЫХ НА ПРАКТИКЕ ПО СЕЙ ДЕНЬ алгоритмов внутренней сортировки, но деревянное фоннеймовское быдло всё не уймётся со своим говном эпохи второй мировой. И это программисты. Кнута прочитали, говно жрут. Пидоры блять.
- Для сортировки списков оптимателен и надежен мердж-сорт. Списки квиксортом сортировать могут только тролли или умственно отсталые. Школота, иди нахуй.
- Хаскельный код писал мудозвон, сишный - долбоёб.
Эта статья нефапабельна :-(((
Последний пример кода вопиюще несмешон. \x -> Suave Space Kitten Javascript 14:30, 20 ноября 2007 (MSK)
- Зато для быдлокодеров на похапе он очень даже wtf-абельн. --22:30, 20 ноября 2007 (MSK)
А случаем не 5150-ли у камрада на фотограмме? ;) --Хатхи 10:10, 9 февраля 2008 (MSK)
Меж тем, хочу сказать, что статья бредова чуть менее, чем полностью. Лучше бы в статье о Лиспе стоило упомянуть, что интерпретатор лиспа на лиспе занимает не больше 15 строк. ---
- Это примерно то же, что говорить в пользу бейсика, что там можно листинг программы распечатать одним оператором LIST. Интерпретатор Лиспа на Лиспе никому не нужен. Компилятор Лиспа на Лиспе (со всеми фичами, включая сборщик мусора) занимает строк чуть более, чем дохуя.
И первый пример кода нерабочий
- Да ладно, в нём только и нужно импорты подправить на
-
import System.Random;import Data.List;import Data.Char;
- но лучше бы поправить, конечно — школьник-кун
я ничего не знаю о хаскеле, но мне кажется, кому-то хотелось продемонстрировать нечитаемость кода, и не удалось. Что угодно можно сделать нечитаемым, запихнув в одну строку с минимально возможным числом пробелов, а потом разорвав её в случайных местах.
Та до жопы читаемость и количество скобок, сам код даже с идеальным форматированием нифига не понятен, как регулярки - ничего разобрать невозможно, пока не задрочишь всё по буквам. Ну и как на этом можно быстро пейсать приложения? Хэллоуворды, библиотеки и уних-вей утилиты, копирующие один файл из А в Б? А как насчёт серьёзных разработок, требующих постоянного обновления и отладки, более чем 1 человеком? Как этот хуёво структурированный высер больного воображения одного академического долбоёба будет разбирать другой?
instance XmlContent Album where fromElem (CElem (Elem "album" [] c0):rest) = (\(a,ca)-> (\(b,cb)-> (\(c,cc)-> (\(d,cd)-> (\(e,ce)-> (\(f,cf)-> (\(g,cg)-> (\(h,ch)-> (Just (Album a b c d e f g h), rest)) (definite fromElem "<notes>" "album" cg)) (many fromElem cf)) (definite fromElem "<personnel>" "album" ce)) (many fromElem cd)) (definite fromElem "<coverart>" "album" cc)) (fromElem cb)) (definite fromElem "<artist>" "album" ca)) (definite fromElem "<title>" "album" c0) fromElem (CMisc _:rest) = fromElem rest fromElem rest = (Nothing, rest) toElem (Album a b c d e f g h) = [CElem (Elem "album" [] (toElem a ++ toElem b ++ maybe [] toElem c ++ toElem d ++ concatMap toElem e ++ toElem f ++ concatMap toElem g ++ toElem h))] instance XmlContent Title where fromElem (CElem (Elem "title" [] c0):rest) = (\(a,ca)-> (Just (Title a), rest)) (definite fromText "text" "title" c0) fromElem (CMisc _:rest) = fromElem rest fromElem rest = (Nothing, rest) toElem (Title a) = [CElem (Elem "title" [] (toText a))] instance XmlContent Artist where fromElem (CElem (Elem "artist" [] c0):rest) = (\(a,ca)-> (Just (Artist a), rest)) (definite fromText "text" "artist" c0) fromElem (CMisc _:rest) = fromElem rest fromElem rest = (Nothing, rest) toElem (Artist a) = [CElem (Elem "artist" [] (toText a))] instance XmlContent Recording where fromElem (CElem (Elem "recording" as []):rest) = (Just (fromAttrs as), rest) fromElem (CMisc _:rest) = fromElem rest fromElem rest = (Nothing, rest) toElem as = [CElem (Elem "recording" (toAttrs as) [])] instance XmlAttributes Recording where fromAttrs as = Recording { recordingDate = possibleA fromAttrToStr "date" as , recordingPlace = possibleA fromAttrToStr "place" as } toAttrs v = catMaybes [ maybeToAttr toAttrFrStr "date" (recordingDate v) , maybeToAttr toAttrFrStr "place" (recordingPlace v) ] instance XmlContent Coverart where fromElem (CElem (Elem "coverart" as c0):rest) = (\(a,ca)-> (Just (Coverart (fromAttrs as) a), rest)) (fromElem c0) fromElem (CMisc _:rest) = fromElem rest fromElem rest = (Nothing, rest) toElem (Coverart as a) = [CElem (Elem "coverart" (toAttrs as) (maybe [] toElem a))] instance XmlAttributes Coverart_Attrs where fromAttrs as = Coverart_Attrs { coverartStyle = definiteA fromAttrToStr "coverart" "style" as } toAttrs v = catMaybes [ toAttrFrStr "style" (coverartStyle v) ] instance XmlContent Location where fromElem (CElem (Elem "location" as []):rest) = (Just (fromAttrs as), rest) fromElem (CMisc _:rest) = fromElem rest fromElem rest = (Nothing, rest) toElem as = [CElem (Elem "location" (toAttrs as) [])] instance XmlAttributes Location where fromAttrs as = Location { locationThumbnail = possibleA fromAttrToStr "thumbnail" as , locationFullsize = possibleA fromAttrToStr "fullsize" as } toAttrs v = catMaybes [ maybeToAttr toAttrFrStr "thumbnail" (locationThumbnail v) , maybeToAttr toAttrFrStr "fullsize" (locationFullsize v) ] instance XmlContent Catalogno where fromElem (CElem (Elem "catalogno" as []):rest) = (Just (fromAttrs as), rest) fromElem (CMisc _:rest) = fromElem rest fromElem rest = (Nothing, rest) toElem as = [CElem (Elem "catalogno" (toAttrs as) [])] instance XmlAttributes Catalogno where fromAttrs as = Catalogno { catalognoLabel = definiteA fromAttrToStr "catalogno" "label" as , catalognoNumber = definiteA fromAttrToStr "catalogno" "number" as , catalognoFormat = possibleA fromAttrToTyp "format" as , catalognoReleasedate = possibleA fromAttrToStr "releasedate" as , catalognoCountry = possibleA fromAttrToStr "country" as } toAttrs v = catMaybes [ toAttrFrStr "label" (catalognoLabel v) , toAttrFrStr "number" (catalognoNumber v) , maybeToAttr toAttrFrTyp "format" (catalognoFormat v) , maybeToAttr toAttrFrStr "releasedate" (catalognoReleasedate v) , maybeToAttr toAttrFrStr "country" (catalognoCountry v) ] instance XmlAttrType Catalogno_Format where fromAttrToTyp n (n',v) | n==n' = translate (attr2str v) | otherwise = Nothing where translate "CD" = Just Catalogno_Format_CD translate "LP" = Just Catalogno_Format_LP translate "MiniDisc" = Just Catalogno_Format_MiniDisc translate _ = Nothing toAttrFrTyp n Catalogno_Format_CD = Just (n, str2attr "CD") toAttrFrTyp n Catalogno_Format_LP = Just (n, str2attr "LP") toAttrFrTyp n Catalogno_Format_MiniDisc = Just (n, str2attr "MiniDisc") instance XmlContent Personnel where fromElem (CElem (Elem "personnel" [] c0):rest) = (\(a,ca)-> (Just (Personnel a), rest)) (many fromElem c0) fromElem (CMisc _:rest) = fromElem rest fromElem rest = (Nothing, rest) toElem (Personnel a) = [CElem (Elem "personnel" [] (concatMap toElem a))] instance XmlContent Player where fromElem (CElem (Elem "player" as []):rest) = (Just (fromAttrs as), rest) fromElem (CMisc _:rest) = fromElem rest fromElem rest = (Nothing, rest) toElem as = [CElem (Elem "player" (toAttrs as) [])] instance XmlAttributes Player where fromAttrs as = Player { playerName = definiteA fromAttrToStr "player" "name" as , playerInstrument = definiteA fromAttrToStr "player" "instrument" as } toAttrs v = catMaybes [ toAttrFrStr "name" (playerName v) , toAttrFrStr "instrument" (playerInstrument v) ] instance XmlContent Track where fromElem (CElem (Elem "track" as []):rest) = (Just (fromAttrs as), rest) fromElem (CMisc _:rest) = fromElem rest fromElem rest = (Nothing, rest) toElem as = [CElem (Elem "track" (toAttrs as) [])] instance XmlAttributes Track where fromAttrs as = Track { trackTitle = definiteA fromAttrToStr "track" "title" as , trackCredit = possibleA fromAttrToStr "credit" as , trackTiming = possibleA fromAttrToStr "timing" as } toAttrs v = catMaybes [ toAttrFrStr "title" (trackTitle v) , maybeToAttr toAttrFrStr "credit" (trackCredit v) , maybeToAttr toAttrFrStr "timing" (trackTiming v) ] instance XmlContent Notes where fromElem (CElem (Elem "notes" as c0):rest) = (\(a,ca)-> (Just (Notes (fromAttrs as) a), rest)) (many fromElem c0) fromElem (CMisc _:rest) = fromElem rest fromElem rest = (Nothing, rest) toElem (Notes as a) = [CElem (Elem "notes" (toAttrs as) (concatMap toElem a))] instance XmlAttributes Notes_Attrs where fromAttrs as = Notes_Attrs { notesAuthor = possibleA fromAttrToStr "author" as } toAttrs v = catMaybes [ maybeToAttr toAttrFrStr "author" (notesAuthor v) ] instance XmlContent Notes_ where fromElem c0 = case (fromText c0) of (Just a,rest) -> (Just (Notes_Str a), rest) (Nothing,_) -> case (fromElem c0) of (Just a,rest) -> (Just (Notes_Albumref a), rest) (Nothing,_) -> case (fromElem c0) of (Just a,rest) -> (Just (Notes_Trackref a), rest) (Nothing,_) -> (Nothing, c0) fromElem (CMisc _:rest) = fromElem rest fromElem rest = (Nothing, rest) toElem (Notes_Str a) = toText a toElem (Notes_Albumref a) = toElem a toElem (Notes_Trackref a) = toElem a instance XmlContent Albumref where fromElem (CElem (Elem "albumref" as c0):rest) = (\(a,ca)-> (Just (Albumref (fromAttrs as) a), rest)) (definite fromText "text" "albumref" c0) fromElem (CMisc _:rest) = fromElem rest fromElem rest = (Nothing, rest) toElem (Albumref as a) = [CElem (Elem "albumref" (toAttrs as) (toText a))] instance XmlAttributes Albumref_Attrs where fromAttrs as = Albumref_Attrs { albumrefLink = definiteA fromAttrToStr "albumref" "link" as } toAttrs v = catMaybes [ toAttrFrStr "link" (albumrefLink v) ] instance XmlContent Trackref where fromElem (CElem (Elem "trackref" as c0):rest) = (\(a,ca)-> (Just (Trackref (fromAttrs as) a), rest)) (definite fromText "text" "trackref" c0) fromElem (CMisc _:rest) = fromElem rest fromElem rest = (Nothing, rest) toElem (Trackref as a) = [CElem (Elem "trackref" (toAttrs as) (toText a))] instance XmlAttributes Trackref_Attrs where fromAttrs as = Trackref_Attrs { trackrefLink = possibleA fromAttrToStr "link" as } toAttrs v = catMaybes [ maybeToAttr toAttrFrStr "link" (trackrefLink v) ]
Это сгенерированный код, долбоебы слепые.
Каково, бля? Это вам не сортировка, и не факториал. Не лезьте с этим говном к прикладникам и системщикам! Вы, хаскелеёбы, плаваете в своём говне вдали от цивилизации - enjoy, но не обмазывайте им мой SDL! Не смейте писать на хаскеле файловые менеджеры - всё равно получаются только фэйловые. Сидите, дрочите монады, и не высовывайтесь с криком "я илита", ибо вы не илита, вы академическое, бесконечно далёкое от жизни говно, догоняющее ушедший поезд.
- Что именно Вам непонятно в приведенном фрагменте кода?
- Батхёрт детектед. Смирись уже с тем что ты ничтожество и иди пиши говнокод на пхп или с++.
- Приведённый код писало жуткое уёбище. Стиль написания - просто пиздец. Что-то более подробное по этому коду понять нельзя, потому что это тупо реализация классов типов (на языке ООП - наследование интерфейсов), и никакой реальной программы здесь нет. В нормальных программах так писать никто не будет. А если и будет, то всё будет хорошо откомментировано. Иначе ваше условие о том, что программу поддерживает >1 человека неуместно. к тому же код на хаскелле за счёт ссылочной прозрачности очень легко и удобно рефакторить. Насчёт файловых менеджеров - про xmonad не слышал? это помощнее файлового менеджера.
- Да не трогай ты этого питуха. Чудак живёт в восьмидесятых, хаскель ещё не изобрели, и разницы между программистом и специально выведенным компьютерным опущенцем байтодрочером пока нет.
Содержание |
Реквестирую Гопника Хаскеля
Реквестирую Гопника Хаскеля
Думаю, что в статью не помешает добавить главу.
Не хаскельное Комьюнити
Своим существованием хаскель доставляет настолько лютый батхёрт всем программистам остальных языков, что объемы троллинга в сторону хаскеля превышают все допустимые нормы. // Батхёрт и троллинг могут быть взаимосвязаны только в одном случае: батхёрт произошёл у объекта троллинга. КО как бэ сообщает, что троллить в состоянии батхёрта невозможно. Из всего сказанного можно сделать вывод, что остальным программистам батхёрт доставляет глобальный троллинг, проводимый сообществом haskell. Это предположение, кстати, было недавно озвучено на хабре.
Былинные трэды на лоре, хабре, а теперь и обсуждение на луркморе!
А что им ещё остаётся делать? Не пытаться же читать и просвещаться в сторону функционального программирования, зачем терять своё время? Проще поубеждать их (а главное себя) что хаскель на самом деле не стоит внимания и вообще не годный язык.
- Функциональное программирование <> функциональное программирование с корявой универсальностью.
Эпиграф
Запилите ссылку, где Ксеноцефал такое говорил: «Хаскель — это как ламборджини в деревне. Немного подрочил — и пошел работать на тракторе.»
Неплохой каламбур, если учесть , что ламборгини делал трактора. А уж разжившись на них стал делать и спорткары.
- Запилите ссылку на аффтара в эпиграфе на этого самого((спойлер: просто скопируйте готовую ссылку отсюда!)) Ксеноцефала, ибо мимокрокодящим это имя ничего не скажет... И какого
хуястатья в RO режиме? —22:21, 26 октября 2012 (MSK)
Название
Разве Хаскель не был назван так в честь математика Хаскеля Карри?
Да, так и есть. Вот пруф: http://research.microsoft.com/en-us/um/people/simonpj/papers/history-of-haskell/history.pdf
В самом деле
А какой профит от лямбда калкулус? first-class functions, еба. запарил. кажется я перебрал, сорри
Как бы записать
В общем, мне кажется, что пример, как любители матана вычисляют факториал, содержит баги.
А программа, которая выводит питоновский код, пострадала от форматирования:
q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')'] main=q "q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')']" "def q(a,b,c):print b+chr(10)+'q('+repr(b)+','+repr(c)+','+repr(a)+')'" "def e(x) return 34.chr+x+34.chr end;def q(a,b,c) print b+10.chr+'main=q '+e(b)+' '+e(c)+' '+e(a)+' '+10.chr end"
Хаскель зло
Надо бы ещё добавить такую информацию. Рассмотрим реальную вакансию разработчика http://company.yandex.ru/job/vacancies/dev_search_architect.xml.
Видим требование «умение разбираться в коде и архитектуре больших сложных систем (с объемом исходников от 200 МБ);».
Но самые большие и сложные проекты на хаскеле, например, компилятор хаскеля ghc, имеют размер исходников в распакованном виде не более 50 Мб (http://www.haskell.org/ghc/download_ghc_6_12_3.html).
Следовательно, программируя на хаскеле, Вы никогда не достигнете уровня мастерства, необходимого для работы в яндексе!
- программируя на хаскеле, Вы никогда не достигнете уровня мастерства, необходимого для работы в яндекс программистом с++. Спасибо, кэп.
Кроме того, программируя на хаскеле, человек постепенно забывает о бесчисленных граблях при работе со ссылками, указателями, объектами, конструкторами, деструкторами, о и их наследовании и поведении по-умолчанию, об операциях копирования и присваивания объектов, о выделении и освобождении памяти и т. д., поэтому он также не ответит и на Вопрос 4.
Хаскель зло, никогда его не учите!
- Ну как тут не упомянуть замечательнейшую статью Why learning Haskell/Python makes you a worse programmer ☺
- Я считаю вы долбоёбы со своими компиляторами, высокоуровневыми языками и виртуальными машинами совсем забыли, что такое регистроёбство и не-проеби-указатель- стека-вство.
- Моя рецензия на "Why learning Haskell/Python makes you a worse programmer": плохому танцору и яйца мешают!
Про популярность сабжа на ЛОРе
Материал к статье
http://johnmacfarlane.net/images/JohnMacFarlaneTransparent.png
Влом было заливать картинку и не знаю могу ли (регаться влом), но это программист на Haskell.
Думаю что уместно было бы добавить слоган\мем хаскелитов "avoid success at all costs".
Зопилите цитату чтоб не пропала
Делаешь пандорический захват, лифтишь в монаду, потом строишь рекурсивную схему (здесь подойдёт зигохистоморфный препроморфизм) как монадический трансформер из категории эндофункторов, и метациклически вычисляешь результат. Любой второкурсник справится. А если делать на анафорических лямбдах — так задачка вообще на пять минут.
Отседова http://www.linux.org.ru/forum/development/7153213?cid=7153773
Сцылки
lambdabot@jabber.ru - онлайн-интерпретатор для Jabber-а
http://www.haskell.org/haskellwiki/Lambdabot - справка по боту.
Таки да!
Поиск в гугле по словам "haskell hebrew meaning" выдаёт много интересного.
"wisdom" по-ихнему.
Hello world
Правильнее всё же с putStrLn:
main :: IO () main = putStrLn "Hello, world!"
Нахуя??
Нахуя писать "функциональный декларативный язык программирования", как будто чистый функциональный язык может быть не декларативным??
F# к Haskell не имеет никакого отношения. F# в основе имеет Ocaml Light, а тот в свою очередь ML.
Пара гвоздей в гроб
Раз:
(+1) 1 -- OK (/1) 1 -- OK (*1) 1 -- OK (-1) 1 -- Error!
Все операторы как операторы, а минус на особом положении. Причины понятны, но тем не менее такие вот исключения из правил не красят язык.
- Используй ((-)1).
- Звучит как "держи костыль".
- (subtract 1) aka flip (-) 1
- Звучит как "держи костыль".
Два:
data Person = Person { name :: String } data Country = Country { name :: String } -- конфликт имён!
Вот за такое создателям Хаскеля надо отрубать руки по самые уши.
- себе руки отруби, даун
- https://ghc.haskell.org/trac/ghc/wiki/Records так-то посоны сами считают это провалом
С заменой всего на "задрот" статья стала хуже, статья стала глупее.
Поясните, Почему haskell программистов называют штангистами?