Текущий архив: 2013.06.30;
Скачать: CL | DM;
Вниз
ООП vs ФП Найти похожие ветки
← →
Rouse_ © (2013-02-08 23:34) [120]Да, забыл добавить ИМХО, каюсь :)
← →
Игорь Шевченко © (2013-02-08 23:46) [121]Kerk © (08.02.13 23:33) [119]
Жалко, у меня Пратт ушел в страну вечной охоты - я бы его процитировал.
(Пока искал, смотрю, у книги уже 4-ое издание, надо бы купить, там даже про ML есть:
http://www.ozon.ru/context/detail/id/1158230/ )
← →
Игорь Шевченко © (2013-02-08 23:48) [122]Вот она, какая у меня была
http://www.umup.narod.ru/1021_1.html
про Снобол сейчас кто-нибудь помнит, интересно ?
← →
Kerk © (2013-02-08 23:53) [123]Да, списочек языков там реально тру-олдскул :)
Среди языков открытием последних дней для меня стал Datalog. Очень интересно выглядит.
← →
Jeer © (2013-02-09 00:04) [124]Ну да.. я однажды, давно уж, о Питоне услышал, вогнал себя туда - после Perl это было более чем занятно. И понял, что садомазохизм, известный мне по очень старым книжкам, меркнет перед этим Явлением.
← →
Иксик © (2013-02-09 19:50) [125]Удалено модератором
← →
Rouse_ © (2013-02-09 20:51) [126]
> Jeer © (09.02.13 00:04) [124]
> Ну да.. я однажды, давно уж, о Питоне услышал, вогнал себя
> туда - после Perl это было более чем занятно. И понял, что
> садомазохизм, известный мне по очень старым книжкам, меркнет
> перед этим Явлением.
Однако ж достаточно большое количество современных онлайн игр написано на питоне. EVE-Online как пример этому (кстати самая известная космическая одиссея, можно сказать) :)
← →
Kerk © (2013-02-09 21:19) [127]Вот претензии к Питону неплохо бы обосновать, да :)
← →
Rouse_ © (2013-02-09 22:11) [128]Удалено модератором
Примечание: Выражения выбираем
← →
Jeer © (2013-02-10 22:10) [129]
> Вот претензии к Питону неплохо бы обосновать, да :)
Претензий нет - есть неприятие по выразительности чтения, а потому - мной не использование.
А так, да - весьма интересный язык, пользуются им многие.
← →
Иксик © (2013-02-11 00:09) [130]Вообще интересно. Чем больше читаю по ФП, тем больше кажется, что в ближайшее время они станут мейнстримом. Через вещи вроде linq и лямбда-функций они становятся не такими уж чужими для среднего программера.
F# вообще хоть сейчас можно использовать в реальной жизни. Сейчас выбираем javascript библиотеку и я случайно наткнулся на http://websharper.com. Заговорил о нем с коллегами и выяснилось, что один как раз проходит курс по функциональным языкам на Coursera.
← →
Игорь Шевченко © (2013-02-11 00:11) [131]
> Чем больше читаю по ФП, тем больше кажется, что в ближайшее
> время они станут мейнстримом
Как раньше в ближайшее время не стало, так и сейчас не станет. Мне кажется. Каждая парадигма имеет свою нишу.
> F# вообще хоть сейчас можно использовать в реальной жизни
LISP с 1958 года можно использовать в реальной жизни. Более того, он используется. Но мэйнстримом не стал.
← →
Иксик © (2013-02-11 01:27) [132]
> Игорь Шевченко © (11.02.13 00:11) [131]
>
>
> > Чем больше читаю по ФП, тем больше кажется, что в ближайшее
> > время они станут мейнстримом
>
>
> Как раньше в ближайшее время не стало, так и сейчас не станет.
> Мне кажется. Каждая парадигма имеет свою нишу.
Ну это всего лишь имхо, но я помню, что когда впервые прочитал что-то про ФП для меня это было что-то настолько далеким и темным, что я дальше не пошел и забыл про него, как про что-то экзотическое. А сейчас начал читать и смотрю: это знакомо, это знакомо, это более-менее знакомо, т.к. с недавних пор множество вещей из ФП перешло в мейнстримовые языки.
> LISP с 1958 года можно использовать в реальной жизни. Более
> того, он используется. Но мэйнстримом не стал.
Я к тому, что F# можно легко использовать с MS продуктами, а это все же сильно снижает порог вхождения. Т.е. я могу его прямо сейчас начать использовать в текущем проекте, который под .Net. Все же это намного проще, чем ставить новую среду, изучать новые библиотеки, привыкать к новой экосистеме.
← →
boriskb © (2013-02-11 08:22) [133]
> Игорь Шевченко © (08.02.13 23:48) [122]
> Вот она, какая у меня былаhttp://www.umup.narod.ru/1021_1.
> html
И у меня эта книга встретилась в самом начале и оказала немаленькое влияние на формирование соответствующих взглядов.
Кто-то у меня её свиснул :(
← →
Kerk © (2013-02-11 16:01) [134]По поводу удобности забавное мнение :)
Хватит уже спорить о юзабильности или не юзабильности языков. Тот факт, что javascript является одним из самых используемых языков программирования, как бы намекает нам на то, что не юзабельных языков не бывает, бывает мало карго-культа и недостаточно хипстеров. Я серьезно, возьмите haskell, ocaml, lisp, любую бесовщину возьмите. Взяв, монополизируйте бесовщину в отдельно взятом секторе, киньте туда хипстеров, стартаперов и добавьте модных словечек {scalability, big data, high load, lean startup} по вкусу.
http://juick.com/dk/2217232
← →
знайка (2013-02-11 17:25) [135]javascript-у альтернативы нет, по большому счету, как бы тоже намекает. :)
← →
Mystic © (2013-02-12 15:50) [136]
> Ну вот я даже не поленился переписать те же самые функции
> (сделаем вид, что в стандартной библиотеке ни одной из них
> нет :)
Как бы не в духе ФП. Не видно никакой разницы с обычными языками. Демонстрация встроенных средств работы со списками, на более. Ну чуть меньше писанины, но это не такой уж и большой плюс.
Второй аспект в том, что если это возможно, то кто-то это будет использовать. А значит разбираться с этим придется.
К математической нотации... После того, как аксиомы сформированы, математика уходит быстро в сторону от такого символизма.
А идея ФП состоит в том, что...lstLength :: [a] -> Integer
lstLength [] = 0
lstLength x:xs = 1 + lstLength xs
lstSumm :: [Integer] -> Integer
lstSumm [] = 0
lstSumm x:xs = x + lstSumm xs
lstProd :: [Integer] -> Integer
lstProd [] = 1
lstProd x:xs = x * lstProd xs
Мы видим, что эти три функции имеют общую структуру. По сути, нам надо три функции:
lstGeneric [] = f1 -- Результат обработки пустого списка
lstGenetic x:xs = f3 f2 x xs
И теперь для lstLength у нас f1=0, f2=1, f3=сложение. Для lstProd у нас f1=1, f2=x, f3=произведение.
Но чем дальше по этому пути продвигаться, тем больше болит голова.
← →
Kerk © (2013-02-12 16:16) [137]
> Mystic © (12.02.13 15:50) [136]
> Как бы не в духе ФП.
С чего бы?
> А идея ФП состоит в том, что...
Это не идея ФП, это твоя идея. Нечто подобное можно и в Delphi соорудить.
> Второй аспект в том, что если это возможно, то кто-то это
> будет использовать. А значит разбираться с этим придется.
В этом коде нет ничего, что было бы недоступно в современных мейнстримных языках. Разве что синтаксис непривычный.
Если уж на то пошло, то в ФП это все нафиг не нужно, т.к. в любом Ф-языке все это делается с помощью библиотечных функций. Твой пример чисто умозрительный. Кто-то решил поиграться, ну молодец.
← →
Kerk © (2013-02-12 16:21) [138]Если уж говорить про дух ФП, то функция "посчитать произведение элементов" в реальной жизни выглядела бы примерно так:
fun xs = List.foldl (fn (x, acc) => x+acc) 1 xs
Тут и функция высшего порядка и анонимная функция и в целом достаточно общЕ.
← →
Kerk © (2013-02-12 16:22) [139]Имя функции забыл, но не суть
fun lstProd xs = List.foldl (fn (x, acc) => x+acc) 1 xs
← →
Kerk © (2013-02-12 16:25) [140]Или даже так, выкинем параметр. Сделаем partial application, чтоб еще больше ФП :)
val lstProd = List.foldl (fn (x, acc) => x+acc) 1;
← →
Kerk © (2013-02-12 16:37) [141]Да елки-палки. Там не +, а * конечно же. Умножаем же.
Сорри за такое количество сообщений подряд.
← →
jack128 © (2013-02-13 09:11) [142]если мы говорим про ФП, то операторы там должны быть обычными функциями, так что нуно так писать
val product = List.fold (*) 1
← →
Вариант (2013-02-13 09:50) [143]
> Mystic © (12.02.13 15:50) [136]
> Как бы не в духе ФП. Не видно никакой разницы с обычными
> языками
А обязательно, что бы программирование было функциональным, его код должен сильно отличаться от императивного и напрочь не читаться с первого раза???
Все вполне в духе. Функция определяет себя через себя саму же.
Могу привести исходники этих функций на эрланге из модуля lists , весьма похоже на функции Керка, с той разницей, что в эрланге сделано с хвостовой рекурсией ну и да, там принято выносить работу с пустым списком в отдельное определение, что не является на мой взгляд принципиальным. А так написано весьма понятно для читающего код, то есть требуется более низкий уровень вхождения, чем для вашего примера. Если писать проще и понятней, то голова болеть не будет:-) Конечно ко всему сказанному добавлю ИМХО.....
← →
Kerk © (2013-02-13 11:37) [144]
> jack128 © (13.02.13 09:11) [142]
Точно, так еще проще, как-то я сходу не сообразил :)
В синтаксисе SML это будет выглядеть так:val product = List.foldl op* 1;
← →
Mystic © (2013-02-13 14:29) [145]
>val product = List.foldl op* 1;
Это один уровень вложенности, я просто добавил еще несколько в том же духе, как это обычно бывает в практических задачах. И сразу обнаружил проблемы с восприятием у себя. Большую часть времени борешься не с задачей, а с ФП. А если юзать фичи по минимуму, то чувствуется ограничение на неизменяемость переменных. Вечно ломаешь голову, как перевести императивных исходник в функциональный вид. И мысь: а почему бы не взять какой-нить Питон?
Еще для затравки: что тут делается понятно из названия. Вроде и код понятен. А вот повторить его в похожей задаче уже напряг.
randomQsort :: (Ord a) => [a] -> IO [a]
randomQsort [] = return ([])
randomQsort xs = do
pos <- getStdRandom (randomR (0, -1 + length xs))
let op = xs !! pos
left <- randomQsort (filter (< op) xs)
right <- randomQsort (filter (> op) xs)
return (left ++ (filter (== op) xs) ++ right)
← →
Kerk © (2013-02-13 14:52) [146]Т.е. твоя критика заключается в том, что это не то, к чему ты привык?
← →
Вариант (2013-02-13 15:09) [147]
> Mystic © (13.02.13 14:29) [145]
Если уж очень нужны состояния, протаскивайте их параметром функции, а так это дело привычки. Нужны состояния - или тащи параметром или делай "нечистые" функции. От реальной жизни убежать таки сложно бывает. но во многих случаях можно.
Пример ваш с быстрой сортировкой понятен, даже не зная синтаксиса языка - тут конечно роль играют и правильно подобранные имена функций
Повторить сразу сложно от небольшого опыта - это у всех есть. Но если оно не надо, то стоит ли об этом горевать. Будет надо, будет использоваться сперва со "словарем", а потом и без него по мере привычки
А так чего-только в MSDN например непонятного еще написано...
Вот аналогичный пример, правда без случайного деления на части списка. Довольно просто все
sort([Pivot|T]) ->
sort([ X || X <- T, X < Pivot]) ++
[Pivot] ++
sort([ X || X <- T, X >= Pivot]);
sort([]) -> [].
← →
Вариант (2013-02-13 15:24) [148]
> Mystic © (13.02.13 14:29) [145]
Кстати таки и сам неправильно написал, ибо синтаксис не знаю,
> правда без случайного деления на части списка
не верно, тут
без случайного выбора элемента сравнения из списка судя по всему.
← →
Mystic © (2013-02-13 22:20) [149]
> Если уж очень нужны состояния, протаскивайте их параметром
> функции, а так это дело привычки. Нужны состояния - или
> тащи параметром или делай "нечистые" функции. От реальной
> жизни убежать таки сложно бывает. но во многих случаях можно.
>
В вышеуказанном примере быстрой сортировки используются монады, еще один вариант. Пример то понятен, но в общих чертах.
Аналогичный пример все-таки имеет сложность O(N^2) для случая отсортированных (или почти отсортированных) списков.
И мы ничего не говорили про расход памяти. А это тоже важный момент, попробуй при помощи своего sort отсортировать массив целых чисел от 1_000_000 до 1? Засемь время и сравнить с Ц++? Решение без дополнительного выделения памяти на Haskell, конечно, возможно. Можно наслаждаться оптимизированных чистым Haskell-кодом:
import Control.Monad
import Data.Array.IO
import Data.IORef
qsort :: IOUArray Int Int -> Int -> Int -> IO ()
qsort a lo hi = do
let z :: IO (IORef Int)
z = newIORef 0
(.=) = writeIORef
ref .=. action = do v <- action; ref .= v
(!) = readArray
(.!) a ref = readArray a =<< get ref
get = readIORef
(.<) = liftM2 (<)
(.>) = liftM2 (>)
(.<=) = liftM2 (<=)
(.>=) = liftM2 (>=)
(.&&) = liftM2 (&&)
(h,l,p,t) <- liftM4 (,,,) z z z z
when (lo < hi) $ do
l .= lo
h .= hi
p .=. (a!hi)
doWhile (get l .< get h) $ do
while ((get l .< get h) .&& ((a.!l) .<= get p)) $ do
modifyIORef l succ
while ((get h .> get l) .&& ((a.!h) .>= get p)) $ do
modifyIORef h pred
b <- get l .< get h
when b $ do
t .=. (a.!l)
lVal <- get l
hVal <- get h
writeArray a lVal =<< a!hVal
writeArray a hVal =<< get t
lVal <- get l
writeArray a hi =<< a!lVal
writeArray a lVal =<< get p
hi" <- fmap pred (get l)
qsort a lo hi"
lo" <- fmap succ (get l)
qsort a lo" hi
where doWhile cond foo = do
foo
b <- cond
when b $ doWhile cond foo
while cond foo = do
b <- cond
when b $ foo >> while cond foo
main = do
a <- (newListArray (0,9) [10,9..1]) :: IO (IOUArray Int Int)
printArr a
putStrLn "Sorting..."
qsort a 0 9
putStrLn "Sorted."
printArr a
where printArr a = mapM_ (\x -> print =<< readArray a x) [0..9]
(отсюда)
http://stackoverflow.com/questions/7717691/why-is-the-minimalist-example-haskell-quicksort-not-a-true-quicksort
← →
Вариант (2013-02-14 07:07) [150]
> Mystic © (13.02.13 22:20) [149]
Сравнивать с Ц++ не буду, ибо плюс эрланга не могучем быстродействии. Тут он заведомо проиграет. И да, для меня расход памяти НЕ важный момент, ибо пишу не для PIC или ATMEL, да и нет дико большого расхода памяти в моих задачах. SQL Server больше у нас жрет и все равно память только на 1/4 задействована. Слышал что хаскель и F# могут примерно поспорить по скорости с Ц++, но считаю, что плюс функциональных языков не в скорости выполнения вычислений, а в другом. Выразительности, краткости и т.п. Если они экономят память и скорость у них приличная- ради бога, если нет, главное что бы все было в разумных рамках.
Естественно считаю, что краткость не должна быть в ущерб читаемости кода. У ФП свои фишки. Тут весь вопрос стоит в том - а нужны ли тебе эти фишки, а нужна ли тебе скорость и небольшая память, можно ли найти баланс между всеми твоими хотелками. Мне например просто удобно работать не думая о памяти, мне очень нравится паттерн матчинг, мне нравится и list comprehension, хотя вот им почти не пользуюсь в коде, только в скриптах и многое другое, чего нет в дельфи или сделано там по другому. Скорость выполнения кода и расход памяти для моих задач вполне приемлем.
Но когда надо сделать задачу с ГУИ, я даже не думаю и иду к дельфи или C#. А вот в прочих случая уже выбираю чаще ФП в последнее время, но не всегда. Кстати некоторые ФЯ имеют порты к библиотеками написанным на других языках... Это уж если очень хочется и сладкого и кислогоLOL
И да -про монады не знаю, вернее читал это слово, но не проникся, как и всем хаскелем. Не потому , что не нравится, просто все объять - нет времени:-)
← →
Mystic © (2013-02-14 11:38) [151]Хорошо бы не думать о памяти, но на сервере ее всего 64 гига, да на видеокарточке еще шесть :"-(
Самое ресурсоемкое приложение у нас отъедало порядка тридцати гиг, но это Ц++. Что было бы с ФП грустно представить.
Ну а на хаскеле можно соперничать с Ц++, но в большой ущерб читаемости.
← →
Kerk © (2013-02-14 14:07) [152]Ну в общем пришли к тому, с чего начали. ФП начинает выигрышно смотреться там, где ресурсы не поджимают :)
Кстати, по поводу ресурсов. Всякие паралельные вычисления без ФП вообще не представить. Так что этом плане, вероятно, за ФП будущее.
← →
Mystic © (2013-02-14 14:37) [153]
> Всякие паралельные вычисления без ФП вообще не представить.
Только почему-то OpenCL имеет C-подобный синтаксис. Да и сейчас ФП в параллельном программировании занимает специфическую нишу, хотя времени прошло лет пять, а это много.
Имхо, ФП просто "не взлетело"
← →
Kerk © (2013-02-14 14:46) [154]
> Mystic © (14.02.13 14:37) [153]
Т.е. OpenCL - это не специфичная ниша, а всякие mapreduce - специфичная? Ну понятно :)
← →
Иксик © (2013-02-14 15:59) [155]
> Иксик © (11.02.13 00:09) [130]
>
> Вообще интересно. Чем больше читаю по ФП, тем больше кажется,
> что в ближайшее время они станут мейнстримом.
Поправка: не обязательно сами ФП языки, но ФП фичи скорее всего. Т.е. возможно они просто вольются в языки типа с#.
← →
Mystic © (2013-02-15 13:33) [156]
> Иксик © (14.02.13 15:59) [155]
Этим фичам уже много лет, больше десятка. Пока что они не спешат вливаться в мейнстрим. Есть отдельно Scala, в C# понемногу добавляют функциональные фичи.
← →
Kerk © (2013-02-15 14:07) [157]Жаль, что понемногу. Но если в C# 2.0, спустя 40 лет, появились дженерики, а в C# 1.0 так вообще круть - сборщик мусора, то вполне можно надеятся, что в C# 29.0 программистам предложат прогрессивную новую технологию - сопоставление с образцом. Задержка в 40-50 лет вполне приемлима.
Троллю, да. Не сдержался :)
← →
знайка (2013-02-15 14:37) [158]
> что в C# 29.0 программистам предложат прогрессивную новую
> технологию
а до тех пор в дотнете есть f#. $)
← →
Иксик © (2013-02-15 23:33) [159]
> Mystic © (15.02.13 13:33) [156]
>
>
> > Иксик © (14.02.13 15:59) [155]
>
>
> Этим фичам уже много лет, больше десятка. Пока что они не
> спешат вливаться в мейнстрим. Есть отдельно Scala, в C#
> понемногу добавляют функциональные фичи.
> <Цитата>
>
> Kerk © (15.02.13 14:07) [157]
>
> Жаль, что понемногу. Но если в C# 2.0, спустя 40 лет, появились
> дженерики, а в C# 1.0 так вообще круть - сборщик мусора,
> то вполне можно надеятся, что в C# 29.0 программистам предложат
> прогрессивную новую технологию - сопоставление с образцом.
> Задержка в 40-50 лет вполне приемлима.
>
> Троллю, да. Не сдержался :)
Я как раз про C#, на нем в последние годы. Я мало смыслю в ФП, но кроме дженериков вроде LINQ со всякими там лямбда экспрешеннами, анонимные функции, новые асинхронные методы - может я неправ, но имхо от этого пахнет ФП.
Страницы: 1 2 3 4 вся ветка
Текущий архив: 2013.06.30;
Скачать: CL | DM;
Память: 0.85 MB
Время: 0.02 c