Обсуждение:Haskell
Материал из Lurkmore
Примеры, с помощью которых любители хаскеля доказывают преимущество хаскеля, зело бесполезны. Витринный случай -- кусок кода сишного и кода хаскельного, который якобы реализует qsort. Проблема в том, что там сравниваются реализации разных алгоритмов. Хаскельный код сортирует списки, а не массивы, и использует голову списка для разбиения его на два -- плохое (O(N^2)) поведение на упорядоченных данных, часто встречающееся в реальной жизни, гарантировано. Во-вторых, правильно написанная qsort использует лишь O(log N)[1] дополнительной памяти, сколько использует хаскельный код -- одному Б-гу известно, а алгоритмы с разными O() -- это разные алгоритмы и есть. Поэтому приведенный хаскельный код гарантированно не попадет в продакшн и является лишь игрушкой. На самом деле на хаскеле можно написать настоящую in-place quicksort, но с использованием монад и выглядит это уродливее, чем код сишный. Все это хаскеллофаги отлично знают, но троллинга ради и чтобы не отпугивать новичков, приводят короткий и бесполезный код. Я считаю, нужно добавить.
- Во-первых, то, что хаскельный код сортирует списки, есть одно из его важнейших преимуществ - он будет работать на всем, имеющим класс Ord(а это из коробки люые числа, символы, строки плюс можно определить операции сравнения для любого своего типа данных и пользоваться квикосртом)- как бы полиморфизм, аналогичный код на сишечке вообще непонятно как делать без километров бойлерплейта, на крестах - шаблоны(OH YEAH BABY). Насчет использования головы списка для его разделения - так вообще бред, что там в сишкомирке сейчас принятно брать для медианы? Православен только вариант с псевдослучайным разбиением, но он сожрет столько ресурсов, что не обрадуешься. Все остальные способы разбиения стабильно просасывают на каком-либо типе данных(в случае реализации квиксорта на хаскелле - отортированный в обратную сторону список), ничего не поделаешь. В третьих, средняя сложность квиксорта - (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. Интерпретатор Лиспа на Лиспе никому не нужен. Компилятор Лиспа на Лиспе (со всеми фичами, включая сборщик мусора) занимает строк чуть более, чем дохуя.
И первый пример кода нерабочий
я ничего не знаю о хаскеле, но мне кажется, кому-то хотелось продемонстрировать нечитаемость кода, и не удалось. Что угодно можно сделать нечитаемым, запихнув в одну строку с минимально возможным числом пробелов, а потом разорвав её в случайных местах.
Та до жопы читаемость и количество скобок, сам код даже с идеальным форматированием нифига не понятен, как регулярки - ничего разобрать невозможно, пока не задрочишь всё по буквам. Ну и как на этом можно быстро пейсать приложения? Хэллоуворды, библиотеки и уних-вей утилиты, копирующие один файл из А в Б? А как насчёт серьёзных разработок, требующих постоянного обновления и отладки, более чем 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. Это предположение, кстати, было недавно озвучено на хабре.
Былинные трэды на лоре, хабре, а теперь и обсуждение на луркморе!
А что им ещё остаётся делать? Не пытаться же читать и просвещаться в сторону функционального программирования, зачем терять своё время? Проще поубеждать их (а главное себя) что хаскель на самом деле не стоит внимания и вообще не годный язык.
- Функциональное программирование <> функциональное программирование с корявой универсальностью.
[править] Эпиграф
Запилите ссылку, где Ксеноцефал такое говорил: «Хаскель — это как ламборджини в деревне. Немного подрочил — и пошел работать на тракторе.»
Неплохой каламбур, если учесть , что ламборгини делал трактора. А уж разжившись на них стал делать и спорткары.
[править] Название
Разве Хаскель не был назван так в честь математика Хаскеля Карри?
Да, так и есть. Вот пруф: 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 ☺
- Я считаю вы долбоёбы со своими компиляторами, высокоуровневыми языками и виртуальными машинами совсем забыли, что такое регистроёбство и не-проеби-указатель- стека-вство.
[править] Про популярность сабжа на ЛОРе
[править] Материал к статье
http://johnmacfarlane.net/images/JohnMacFarlaneTransparent.png
Влом было заливать картинку и не знаю могу ли (регаться влом), но это программист на Haskell.
Думаю что уместно было бы добавить слоган\мем хаскелитов "avoid success at all costs".