LINUX.ORG.RU

Вышел пятый выпуск Haskell Platform

 , , , ,


2

5

Вчера, 3 июня, спустя примерно полгода со времени предыдущего релиза, вышел пятый (за номером 2012.2.0.0) выпуск Haskell Platform — простого в установке окружения разработки для языка Haskell.

Данный выпуск включает в себя:

>>> Подробности

★★★★

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

Ты планируешь это писать в вакансии или говорить уже после устройства? «Ребята, у нас серьезно меняется платформа завтра все пишем на хаскелле?»

Второе может прокатить, первое - не думаю, что большинство «сильных» программеров пойдет на такую вакансию, т.к. будут ощущать «ненужность» знания языка за пределами этой компании.

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

Сильный программист не может быть узко-специализированным.

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

Дай знать, когда твой плюсовый проект принесет тебе первый миллион :-D Подозреваю, что вероятность этого стремится к 0.

Ты промазал мимо тазика. И кстати, глянь на аватарку.

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

У них Haskell? Что именно? (Не из троллинга ради спрашиваю, честное слово).

Да, да. Что у них на нём? Я там хаскель не видел, хотя и искал. :-) Может кто-то что-то на хаскеле делал, а затем уволился?

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

А если просто взять сильных программистов и попросить их выучить хаскель? Насколько велики шансы на успех?

А что знают «сильные программисты»? Если у них порядок с матаном и прочим, и, внимание, если они поймут, в чем сила ФП, тогда успех будет автоматом.

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

А что знают «сильные программисты»? Если у них порядок с матаном и прочим, и, внимание, если они поймут, в чем сила ФП, тогда успех будет автоматом.

Ага, щас. :-)

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

К сожалению, хаскель хорошо демонстрирует этот изъян. Язык построен на в общем-то мощных идеях, но с точки зрения software engineering у него и его стандартного инструментария есть масса больших проблем. Поэтому он и не популярен. Каждый пишет свою статью про монады, но лишь единицы пишут настоящий и практически полезный код.

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

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

Вы не поняли, _хороший_ программист _обязан_ быть математиком, иначе он не хороший программист, а просто кодер ;)

Язык построен на в общем-то мощных идеях, но с точки зрения software engineering у него и его стандартного инструментария есть масса больших проблем.

Например? У меня есть реалистичная версия, почему на нем пишут мало, она подходит не только под программирование, а, в общем-то, под любую область.

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

> А что знают «сильные программисты»? Если у них порядок с матаном и прочим, и, внимание, если они поймут, в чем сила ФП, тогда успех будет автоматом.

100% гарантию дают только в сберкассе :)

Для сильных программистов математика важна. Не спорю. Хотя системщики могут обойтись, да и то не всегда. Просто многие не всегда подозревают, что занимаются время от времени математикой. Она ведь не только в интегралах и производных.

Что касается силы ФП. У него есть и слабости. О них тоже надо знать. Кстати, хаскель тут хороший пример. Монада State только для передачи состояния через череду маленьких крохотных функций - это нечто!

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

И все же, хотелось бы услышать обоснование этого «Язык построен на в общем-то мощных идеях, но с точки зрения software engineering у него и его стандартного инструментария есть масса больших проблем.» :)

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

+100500 Математика ведь и в структурах данных, и в асимптотике итп.

Кстати, вопрос тем кто в теме. У какого языка круче экосистема: у фа-диеза или хаскеля (возможноть дергать дотнет-библиотеки не в счет)?

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

Что касается силы ФП. У него есть и слабости. О них тоже надо знать. Кстати, хаскель тут хороший пример. Монада State только для передачи состояния через череду маленьких крохотных функций - это нечто!

А самое веселое начинается, когда приходится использовать monad transformers.

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

Например? У меня есть реалистичная версия, почему на нем пишут мало, она подходит не только под программирование, а, в общем-то, под любую область.

1. синтаксис - сложный и постоянно меняющийся. Из-за этого сложно или невозможно написать нормальный инструментарий для автоматического анализа, рефакторинга, и т.д. И да, я в курсе про HaRe. При этом я не считаю, что синтаксис сложен для людей.

2. finalizers, навешиваемые на объекты и завязанные на работу GC.

3. cabal, что умеет установить пакеты, но не может их удалить.

4. ад с зависимостями пакетов. Не ясно, как именно прописать ограничения на версии зависимостей и поэтому никто это нормально не делает. Из-за этого собрать что-то сложное иногда почти нереально.

5. а когда к этому добавляется прикол с несколькими версиями одного и того же пакета в системе тогда проще все снести и переустановить.

6. монады сложно соединить. Monad transformers это ужас.

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

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

9. в сыром виде система типов недостаточна. А расширения часто не совместимы между собой или могут привести к явно неправильному поведению.

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

P.S. что за идея?

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

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

Не знаю, где вы нашли таких экспертов. Насчёт резкого изменения скорости - так это вполне ожидаемо.

Monad transformers это ужас.

Хм, а что в них ужасного? Давеча скрещивал Random, List и Writer, всё просто и понятно.

все исключения - unchecked

Если хорошо изолировать не чистый код - такой проблемы вообще не будет.

в сыром виде система типов недостаточна.

Мир вообще несовершенен.

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

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

Чтобы это гарантировать нужно гарантировать тотальность кода. В критичном месте можно не использовать частичных функций (head, read и т.д.), использовать только функции для которых известно что они тотальны, писать тотальные функции, смотреть выхлопы GHC на предмет покрытия cases и guards (с -Wall).

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

Что-то вроде

import Data.Time
import Control.Applicative

brazil :: TimeZone
brazil = TimeZone (- 3 * 60) False "BRT"

getBrazilOfficialTime :: IO ZonedTime
getBrazilOfficialTime = utcToZonedTime brazil <$> getCurrentTime

не подходит?

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

Выше ответили.

P.S. что за идея?

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

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

Не знаю, где вы нашли таких экспертов.

Например:

It is very difficult to predict the time and space behavior of lazy functional programs.

Если хорошо изолировать не чистый код - такой проблемы вообще не будет.

Чистый код тоже может поделить на ноль или сделать head [].

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

Чистый код тоже может поделить на ноль или сделать head [].

head [] избежать можно, выше говорили как. При делении на ноль исключение по умолчанию не возникает, а возвращается NaN, также как и в других языках.

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

head [] избежать можно

head - частичная функция. В хаскеле сделали шаг - отделили чистое от нечистого. Но тотальное (строго-нормализированное, консистентное) и частичное (тьюринг-полное, неконсистентное) никак не разделены, так что строгих гарантий нет. Этот второй шаг тоже можно сделать (agda, например).

При делении на ноль исключение по умолчанию не возникает, а возвращается NaN, также как и в других языках

> 1 `div` 0
*** Exception: divide by zero
quasimoto ★★★★
() автор топика
Ответ на: комментарий от quasimoto

It is very difficult to predict the time and space behavior of lazy functional programs.

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

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

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

При делении на ноль исключение по умолчанию не возникает, а возвращается NaN, также как и в других языках

> 1 `div` 0
*** Exception: divide by zero

Речь о плавающем делении, а ты показал целое.

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

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

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

Речь о плавающем делении, а ты показал целое.

Речь о целых числах. Если кто-то говорит об исключении при делении на ноль - понятно что он имеет в виду целые числа, плавающие тут ни при чём.

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

Если я упомянул NaN, значит речь всяко шла о плавающих числах.

(/) для плавающих чисел не является примером частичной функции, поэтому просто не интересна. Речь о том, что в нынешнем хаскеле всегда существуют частичные функции отсутствие которых никак нельзя гарантировать статическими средствами, поэтому даже в чистом коде действительно нельзя дать 100% гарантию того, что не возникнет исключение.

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

всегда существуют частичные функции

Ну это... Можно же при желании понаписать функций вроде

div' :: Integral  a => a -> a -> Maybe a
dmfd
()
Ответ на: комментарий от quasimoto

Этот второй шаг тоже можно сделать (agda, например).

Забавно. Как в этом случае будет выглядеть тот же div или head?

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

Не знаю, где вы нашли таких экспертов. Насчёт резкого изменения скорости - так это вполне ожидаемо

http://www.starling-software.com/misc/icfp-2009-cjs.pdf

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

Monad transformers это ужас.

Хм, а что в них ужасного? Давеча скрещивал Random, List и Writer, всё просто и понятно.

Уродливо и неочевидно. Черт его разберет, что там во что вложено и как оно вместе работает. Плюс по-моему там часто надо для каждой пары монад писать свою связку.

Если хорошо изолировать не чистый код - такой проблемы вообще не будет.

Ага, а что делать с «нечистым»?

Мир вообще несовершенен.

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

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

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

Ну конечно, очевидно, само собой разумеется - нет.

Уродливо и неочевидно.

Почему неочевидно? Достаточно смотреть на сигнатуры, а что внутри - на совести автора.

А если система типов в хаскеле не дает решить проблему

Бро, покажи мне язык с идеальной системой типов, я на него тут же перейду.

Ага, а что делать с «нечистым»?

Зависит от ситуации.

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

P.S. Для человека с более-менее математическим складом ума система типов в хаскеле довольно подходящая.

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

Можно же при желании понаписать функций вроде

Можно делать монадические обобщения вроде

headM :: Monad m => [a] -> m a
headM [] = fail "empty list"
headM x = return $ head x

-- > runIdentity (headM [])
-- *** Exception: empty list
-- > headM [] :: Maybe a
-- Nothing

divM :: (Monad m, Integral a) => a -> a -> m a
divM _ 0 = fail "division by zero"
dviM x y = return $ div x y

-- > runIdentity (1 `divM` 0)
-- *** Exception: division by zero
-- > 1 `divM` 0 :: Maybe Int
-- Nothing

readM :: (Monad m, Read a) => String -> m a
readM s | [x] <- [x | (x, "") <- reads s] = return x
        | otherwise = fail $ "parse error: \"" ++ s ++ "\""

-- > runIdentity (readM "q1" :: Identity Int)
-- *** Exception: parse error: "q1"
-- > readM "q1" :: Maybe Int
-- Nothing

которые частичны в одних монадах и тотальны в других.

Как в этом случае будет выглядеть тот же div или head?

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

take : ∀ {a} {A : Set a} → ℕ → List A → List A
take zero    xs       = []
take (suc n) []       = []
take (suc n) (x ∷ xs) = x ∷ take n xs

head : ∀ {a} {A : Set a} → List A → List A
head = take 1

обычный (как в хаскеле) и при этом правильный head возможен для «векторов»:

head : ∀ {a n} {A : Set a} → Vec A (1 + n) → A
head (x ∷ xs) = x

тут на уровне системы типов известно, что в векторе достаточно элементов для выполнения head.

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

Чтобы это гарантировать нужно гарантировать тотальность кода.

И как ее гарантировать с практической точки зрения?

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

Да, head и read это вообще песня. Причем это - часть _стандартной_ библиотеки. Лично я их не использую, но можешь ли предложить способ на 100% гарантировать, что ни в моем коде, ни в коде библиотек они не вызываются?

смотреть выхлопы GHC на предмет покрытия cases и guards (с -Wall).

Свой-то код еще как-то можно проверить...

Что-то вроде

import Data.Time

import Control.Applicative

brazil :: TimeZone

brazil = TimeZone (- 3 * 60) False «BRT»

getBrazilOfficialTime :: IO ZonedTime

getBrazilOfficialTime = utcToZonedTime brazil <$> getCurrentTime

У меня это выводит вот что:

2012-06-06 12:03:09.919154 BRT

Тут есть минимум такие проблемы:

1. явно приходится для каждой зоны конструировать ее описание. Ты не можешь просто сказать «зона Бразилии», приходится указывать какой сдвиг по отношению к GMT и летнее ли там время. А все это меняется со временем, причем слабопредсказуемо. Фактически, в некоторых странах правительство может объявить что они прямо завтра неожиданно переходят на зимнее время. И как твой софт будет это поддерживать? :)

2. формат времени неправильный. Должно быть что-то типа «06/06/2012 12:03:09.919154». Правильный формат времени для Бразилии описан, например, тут: http://en.wikipedia.org/wiki/Date_and_time_notation_in_Brazil

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

P.S. Для человека с более-менее математическим складом ума система типов в хаскеле довольно подходящая.

О да.. :-) Сильный аргумент. Вообще-то я не о том, что она сложная, если тебе не очевидно. Я о том, что она «закрытая» и ее расширения не совместимы одно с другим.

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

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

Конечно. «Лучшее» - враг «хорошего». Даже если «хорошее» ну просто очень плохое. :)

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

не будет пропущена тайпчекером - обычный head просто не пишется

Ясно, спасибо.

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

что она «закрытая»

Пример «открытой». Не совсем понимаю, что под этим понятием кроется.

и ее расширения не совместимы одно с другим.

Вам виднее, я пока с этим не сталкивался.

Лично я их не использую, но можешь ли предложить способ на 100% гарантировать, что ни в моем коде, ни в коде библиотек они не вызываются?

Часто приходилось сталкиваться с исключениями в чужом коде?

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

И как ее гарантировать с практической точки зрения?

Никак :) В хаскеле это невыразимые в языке / тулзах чисто умозрительные построения (например, можно ожидать, что length никогда не упадёт, а read - может упасть).

Впрочем, а где не так? Где можно гарантировать exception freeness (где exception - в широком смысле, но только языковые исключения) для какого-то куска кода иначе кроме как вылизыванием этого кода и отслеживанием всех функций что он использует.

но можешь ли предложить способ на 100% гарантировать, что ни в моем коде, ни в коде библиотек они не вызываются?

Вот так, даже для сторонних библиотек, нельзя конечно. Есть пакет safe (0.3.3!), выше я привёл примеры монадических безопасных функций - можно определить тип MyLayer представляющий определённый безопасный уровень в стеке приложения, написать правильный instance Monad MyLayer и на этом уровне использовать безопасные монадические функции. Но это как раз из серии использования / сочинения монадических трансформеров (у которых, к тому же, константный оверхед).

Ты не можешь просто сказать «зона Бразилии», приходится указывать какой сдвиг по отношению к GMT и летнее ли там время. А все это меняется со временем, причем слабопредсказуемо

Да, я посмотрел - как понял, в Sao Paulo всегда стабильно UTC-03, а в остальном - надо писать сложную функцию, учитывающую топологию (там в каждом штате свои правила). Это явно не задача стандартной библиотеки / платформы хаскеля, но задача специального софта.

Должно быть что-то типа «06/06/2012 12:03:09.919154»

Форматированием занимается Data.Time.Format:

> formatTime defaultTimeLocale "%d/%m/%Y %T%Q" <$> getBrazilOfficialTime
"06/06/2012 12:43:45.624452"
quasimoto ★★★★
() автор топика
Ответ на: комментарий от quasimoto

Вообще, практически проще форкать лёгкие потоки, связывать в них STM очереди для сообщений, обрабатывать SomeException, посылать сообщение родителю и падать.

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

явно приходится для каждой зоны конструировать ее описание

Ага, пакет time имеет просто непосредственное отношение к хаскелю.

Если твоя предметная область подразумевает необходимость работы со временем, то используй соответствующие библиотеки, благо FFI устроен неплохо, а GHC'шный линковщик спокойно разбирается как с .o, так и с .so, в т.ч. и в байт-код режиме ghci. Т.е. можешь спокойно написать решение твоей проблемы на C, примитивную FFI прослойку, и спокойно работать.

А time - предельно простенький пакет, для несложных сценариев использования.

Запомни, хаскель это не фреймворк навроде .Net и Java. Хаскель спокойно интегрируется в сишную экосистему.

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

thesz, самый сильный программист на Haskell в России

В пауэрлифтинге? :)

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

В compile time нельзя проверить, что один из параметров - ноль.

Можно, например, гарантировать проверку делителя на 0 :)

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

А что возвращать-то в таком случае?

Исключение бросай, например. Хотя это уже не важно - то, что в некотором участке кода не будет division-by-zero, гарантировано.

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

Некто Лев Валкин делился в жжешке подобным опытом обучения хаскелю, окамлу и эрлангу группы кодеров, в гугле инфа должна быть. Да, наверное, ты читал. Там просто история успеха. Окамл, вроде, получше хаскела пошел.

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

Лев Валкин и группа кодеров просто неосиляторы хаскеля.

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