LINUX.ORG.RU

[FP] Помогите с выбором языка для ФП


0

4

Здравствуйте, пожалуйста порекомендуйте какой язык выбрать из списка и по возможности книгу/туториал по нему, скажите какие у него перед остальными плюсы: - Erlang - Scala - Clojure - Scheme - OCaml Или что-то другое. Python не предлагать, как впрочем и Haskell. Если язык не из списка - то интересует именно инопланетный синтаксис и возможность писать на чистом ФП. Желательно, чтобы язык был не чисто академическим, имелась возможность работы с тулкитами (Qt, GTK, Tk).

Изучать собрался пока ради удовольствия, потом буду использовать в работе и реализации пары OpenSource проектов «для себя». Заранее спасибо.

p.s.: А Refal еще жив? Может он шевелится и имеет связки с тулкитами и прочим?


Ответ на: комментарий от Miguel

>Нет, не создают. А содержимое файликов святой дух меняет?

Или изменение файликов уже не побочные эффекты?

Нет, не для этого.

А для чего?

Побочным эффектом нужен строгий порядок. Иначе каша получается.

А в ленивом языке порядок редукций весьма причудлив и может меняться плохо предсказуемым способом. Более того функции вообще могут не вызываться.

Монада IO борется именно с этими эффектами. Больше она ни для чего не нужна.

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

> А что же это такое? Как так чистая функция, а вернула два разных значения. Значит не такая уж она и чистая.

какая функция тут вернула два разных значения?

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

Как так? Или то что ввел пользователь считается аргументом? Нихрена себе костыли, и все ради того, чтобы сказать «У нас чистый язык!». Кажется я начинаю понимать Love5an'а

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

Тебе кстати сейчас еще объяснят, что на самом деле функция getLine всегда возвращает одно и то же.

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

getLine же

ORLY?

*Main System> let x = getLine
*Main System> let y = getLine
*Main System> do { s <- y ; print s }
abc
"abc"
*Main System> do { s <- x ; print s }
abc
"abc"
korvin_ ★★★★★
()
Ответ на: комментарий от zombiegrinder_6000

В этом случае scanf и printf также придется признать чистыми.

Да и весь С тоже чистый. Там просто все вычисления завернуты в монаду IO совершенно прозрачным для программистов образом. :-/

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

>нет, не борется А что же она делает?

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

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

И да, clojure за возможность обращаться к жабным либам, которых over9000. Т.е. язык готовый для использования хоть сейчас, а не «когда победит светлое будущее».

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

Монады в хаскеле понадобились для того что бы зафиксировать порядок вызова функций. Больше они ни для чего не нужны.

это шикарное утверждение :)

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

функции bind, обладающей некоторыми специальными свойствами

bind = join . fmap

где ты ты тут видишь специальные свойства? в списке это вообще обычный concatMap

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

А вот тут немного непонятно.

А что такого?

Порядок вычислений определяется композицией: если написано f (g x), то функция f будет вычисляться после функции g. Это если забыть про ленивость; если же вспомнить про ленивость, то порядок вычислений определяется левой ногой компилятора, в монаде мы работаем или где ещё.

Порядок «действий», вообще говоря, монадой тоже не определяется; если написано do {action1; action2}, то совершенно не факт, что action1 каким-то образом оказывается «перед» action2; более того, монада может быть вообще коммутативной, и тогда этот код совершенно эквивалентен do {action2; action1}.

А функция bind никакими специальными свойствами не обладает, это обычная функция, каких полно.

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

А вот оно как оказывается.

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

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

Как так чистая функция, а вернула два разных значения. Значит не такая уж она и чистая.

http://ideone.com/Ax6zT

Ошибаешься. Значение, возвращаемое функцией getLine (cобственно, это не функция вообще) имеет тип IO String, а не String. Значение типа IO String получается одно и то же. Интерпретируется рантаймом в разные моменты по-разному.

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

Ну касперскому виднее. Основная идея там в том, что директивы сишного препроцессора, оперирующие блоками кода, представляют собой вполне себе функциональный язык.

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

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

Лол.

1)«Инструкция» содержится в функции.

2)Значение типа «World» которое протаскивается через монаду IO имеет размер 0 байт и оптимизируется компилятором хаскеля в ничто. Те на физическом уровне от IO даже следа не остается. Все чего добивается IO это сохранение строгого порядка вызова функций при протаскивании кода через оптимизатор хаскеля.

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

Монады в хаскеле понадобились для того что бы зафиксировать порядок вызова функций. Больше они ни для чего не нужны.

Особенно Maybe, List и прочие не имеющие к вводу-выводу никакого отношения.

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

cобственно, это не функция вообще

Все ясно. Все что не чистое просто назвали «нефункция». Отличный подход к разработке языка

Отличный подход к выдёргиванию из контекста. А теперь перечитай и попытайся понять, что тебе пишут.

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

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

Ну есть же монады и кроме IO, ау! Посмотрите Parsec, например: монад выше крыши, IO — нет.

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

Чтобы до тебя немножко дошло, приведу реализацию маленького кусочка монады IO на чистом Хаскеле, без самой IO:

module MIO where
import Prelude(Monad(..), String, (++)) -- импортируем только класс Monad и тип "строка", больше ничего
data MIO x =
    Pure x | -- ничего не делать
    Input (String -> MIO x) | -- ввести строчку и действовать в зависимости от неё
    Output String (MIO x) -- вывести строчку и продолжать далее
instance Monad MIO where
    return x = Pure x
    Pure x >>= h = h x
    Input f >>= h = Input (\s -> f s >>= h)
    Output s mx >>= h = Output s (mx >>= h)
input :: MIO String
input = Input return -- прочитать строчку и вернуть её как есть
output :: String -> MIO ()
output s = Output s (return ()) -- вывести строчку и более ничего не делать
Рантайм для этого дела будет уже написан с использованием IO; но не забудь, что для настоящей IO рантайм впендюрен в компилятор.
module Runtime (run, MIO.MIO, MIO.input, MIO.output) where
import qualified MIO
run :: MIO.MIO x -> IO x
run (MIO.Pure x) = return x
run (MIO.Input f) = getLine >>= run . f
run (MIO.Output s mx) = putStrLn s >> run mx
Пример использования:
module Example where
import Runtime
example :: MIO ()
example =
    do output "What is your name?"
       name <- input
       output ("Hello, " ++ name ++ "!")
Запускаем:
*Example> run example
What is your name?
Makar
Hello, Makar!
*Example>

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

>А теперь перечитай и попытайся понять, что тебе пишут.

То что в хаскеле наворотили костылей только чтобы можно было назвать язык чистым - это я уже понял.

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

А как же побочный эффект в виде сообщения на экране?

Ещё раз, для непонятливых. Сам факт вычисления некоей функции не приводит ни к каким сообщениям. Сообщение выводится только тогда, когда на окончательное значение, на результат этой функции, натравливается рантайм.

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

Лол.

1)«Инструкция» содержится в функции.

2)Значение типа «World» которое протаскивается через монаду IO имеет размер 0 байт и оптимизируется компилятором хаскеля в ничто. Те на физическом уровне от IO даже следа не остается. Все чего добивается IO это сохранение строгого порядка вызова функций при протаскивании кода через оптимизатор хаскеля.

Лол.

Всё, чем занимается компилятор, к хаскелю уже не имеет никакого отношения. Код на хаскеле пишется под абстрактную математическую машину с прочным теоретическим фундаментом, выполнение действий IO в который не входит. Никаких инструкций в функциях не содержится. То, что компилятор потом преобразует это в работающую программу, можно считать просто удачным совпадением.

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

Все ясно. Все что не чистое просто назвали «нефункция».

Функция в хаскеле имеет аргумент. getLine аргументов не имеет.

putStrLn, например, это функция типа String -> IO (). У неё аргумент есть, типа String.

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

«Инструкция» содержится в функции.

Нет.

Значение типа «World»

Нет никаких значений типа «World». Не путай хаскель с клином, это разные языки.

на физическом уровне

На физическом уровне электроны по (полу-)проводникам бегают.

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

То что в хаскеле наворотили костылей

В Haskell 98 костылей нет (если не брать FFI addendum). Некоторые расширения - да, иначе как костылями не назовёшь.

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

Функция в хаскеле имеет аргумент. getLine аргументов не имеет.

Стоп. Тут уже запутался я. f = 1 не функция?

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

То что в хаскеле наворотили костылей только чтобы можно было назвать язык чистым - это я уже понял.

Итак, мы подошли к самому главному. Что, по твоему мнению, является чистым функциональным языком? Особенно меня интересует часть про отсутствие «костылей».

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

Стоп. Тут уже запутался я. f = 1 не функция?

Нет, значение. Функция имеет тип a -> b

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

IO выглядит так:

type IO a = RealWorld -> (a, RealWorld)

IO НЕ выглядит так. То, что тебе показали кусочек РЕАЛИЗАЦИИ (причём ОДНОЙ ИЗ возможных реализаций) - это чтобы тебе понятнее было, и только.

Попробуй, запусти ghci и набери :i RealWorld, и убедись, что такого типа в Хаскеле НЕТ.

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

>Нет никаких значений типа «World». Не путай хаскель с клином, это разные языки.

А ну то есть эта статья http://www.haskell.org/haskellwiki/IO_inside лжет, а у тебя инфа 100%.

Вот только материалам с сайта haskell.org и почему то верю больше чем тебе.

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

f = 1 не функция?

Depends, если уж на то пошло. Числовые литералы в Хаскеле полиморфны, и тип f отсюда однозначно не выводится.

Другой вопрос, если там что-то нормальное, скажем, Integer или Float, то - нет, не функция.

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

IO выглядит так:

type IO a = RealWorld -> (a, RealWorld)

Это не хаскель, а возможная реализация рантайма, выполненная на хаскелле. Go figure, как говорится.

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

А ну то есть эта статья http://www.haskell.org/haskellwiki/IO_inside лжет, а у тебя инфа 100%.

Ещё раз, для альтернативно одарённых. Эта статья описывает небольшой кусочек одной из возможных реализаций Хаскеля. НЕ Хаскель сам по себе.

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