Re[7]: Мастер-класс по ФП
От: VoidEx  
Дата: 07.01.09 04:48
Оценка:
Здравствуйте, VoidEx, Вы писали:

Я там на самом деле лишь интереса ради в Chan писал Int -> Int. Лучше писать сами считанные байты, но не суть.
Re[2]: Мастер-класс по ФП
От: thesz Россия http://thesz.livejournal.com
Дата: 07.01.09 05:16
Оценка:
BZ>>я часто сталкиваюсь с двумя точками зрения — первая "я знаком с ФП, но оно никакой выгоды в программировании не даёт", и вторая "я знаком с ФП, но так и не научился использовать его для повышения эффективности программирования". собственно, это одно и то же, разница только в том, на кого (ФП или самого человека) возлагается вина за отсутствие результата

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


Прошу прощения, но ФП ни под что конкретно не заточено.

Это всё в глазах наблюдателя.

S>А на том, что типично пишут программисты, оно особенно не нужно.


Какие программисты-то?
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[4]: Мастер-класс по ФП
От: thesz Россия http://thesz.livejournal.com
Дата: 07.01.09 05:19
Оценка:
Здравствуйте, subdmitry, Вы писали:

S>Здравствуйте, deniok, Вы писали:


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


S>Я считаю, что начинать надо с малого. Лично мне не очень понятно, как добиться на Хаскелле решения такой простой проблемы и (серьезно!) хочу его увидеть.


Что за проблема-то?

S>Оно не такое уж и бессмысленное. У меня при программировании часто возникает код, подобный написанному. Хочу понять, как получить его аналог в функциональных языках.


Лови:
doIt = do
    increment vA
    vB ! vA --> vD *= 10
    vF vG --> vH $= 0


Монады и операторы — твои друзья.

S>Некоторые тут, кстати, заявляют, что Хаскель лучший императивный язык...


Это не тут.

Это в Майкрософте.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[4]: Мастер-класс по ФП
От: thesz Россия http://thesz.livejournal.com
Дата: 07.01.09 05:28
Оценка: 3 (1)
Y>>Пойми я тоже не хочу никого унизить, просто тут уже сразу видно невооруженным взглядом, отсутствие какой-либо базы, а без базы, тебе никто не сможет даже объяснить, почему ты не прав.

S>...решение этой задачи на Хаскелле. Особенно интересно в многопоточном варианте.


Приведенноё мной решение будет работать и с несколькими потоками тоже.

S>Если, конечно, наличествующая у вас база это позволяет сделать, а не просто утверждать, что "глобальные переменные это плохо".


Я это сделал.

Теперь жду от тебя аналогичного.

http://thesz.mskhug.ru/svn/hiersort/sim/Assembler.hs — код "ассемблера"
http://thesz.mskhug.ru/svn/hiersort/tests/matmul/MatMulProg.hs — пример использования
sendval ixlist inp v = do
    modindex <- nodemodindex node $ take 2 ixlist
    asend (oIndexes group fullixlist++oNode node) modindex arity (inp,v)
    where
        ixlen = length ixlist
        fullixlist
            | ixlen == 3 =
                sum ixlist:ixlist
                -- sum (take 2 ixlist):ixlist
                -- 0:ixlist
            | otherwise  = ixlist
        node = inpnode inp
        group = nodegroup node
        arity = inparity inp

nodeS dimn x y ix@[_,i,j,k] = do
    r <- fadd x y
    c <- ilt k dimn
    aif c
        (do
            k1 <- iadd k 1
            sendval [i,j,k1] SInputX r
        )
        (sendval [i,j] CInputX r)


Сделай-ка аналогичный "ассемблер" на твоём любимом ЯП. Чтобы не менее удобно было — чтобы можно было определять свои "подпрограммы" и тп.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[7]: Мастер-класс по ФП
От: subdmitry Россия  
Дата: 07.01.09 05:37
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Вот вам полный прикол:


Большое спасибо, это очень интересно.

То есть созданные в одной функции монадические переменные можно передавать в другие функции, но не делать глобальными. То есть для честного решения того примера в функцию DoIt() надо передать 7 переменных, чего народ ужаснулся. А так же передавать их во всю цепочку функций, из которых DoIt() вызывается. Меня сейчас будут пинать, но, признаться, в ряде случаев вариант с глобальными переменными мне нравится больше.

А можно описывать все функции в модуле как where-блок к блоку do в функции main, это не создат ли эффекта, что порожденные в блоке do переменные станут типа глобальными для этих функций?

VE>
VE>main = do
VE>    chan <- newChan :: IO ByteReads
VE>    s <- getChanContents chan
Насчет последней строчки. Она не лишняя? Или это очистка очереди от какого-то мусора?
VE>


VE>Кстати, я думал, что в Chan может быть один писатель, но не падает. Везёт, или писателей таки может быть куча?


Да вроде оно Control.Concurrent.Chan. По идее должно работать с несколькими потоками.
And if you listen very hard the alg will come to you at last.
Re[3]: Итог размышлнеий
От: FR  
Дата: 07.01.09 06:05
Оценка:
Здравствуйте, NotGonnaGetUs, Вы писали:

NGG>з.ы.

NGG>К дискуссии о "промышленном" решении можно будет вернуться, когда ФП окажется в массах и массы, пробежавшись по всем граблям n-раз, обобщат их до шаблонов, "запахов" и приниципов

Тот же Ерланг давно "промышленный".
Re[3]: Итог размышлнеий
От: FR  
Дата: 07.01.09 06:45
Оценка: 3 (2) +3
Здравствуйте, NotGonnaGetUs, Вы писали:

NGG>Посмотрел на нашу битву реализаций и решил-таки (благо новый год и есть свободное время) познакомиться с одним из языков формальных спецификаций (Z) поближе, что в итоге позволило взглянуть на поднятую тему под немного другим углом.


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


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

Ну и еще к разности культур, меня интересуют сейчас функциональные (а до этого динамические)
языки как инструмент для повышения производительности одиночки или небольшой группы.
Для этих целей такие языки очень хороши и по моему позволяют довольно сильно уменьшить
самую рутиную часть программирование — кодирование, так как по сути написание текста
на выразительных языках ближе к проектированию (или к конструированию)
чем к кодированию.
Re[3]: Мастер-класс по ФП
От: subdmitry Россия  
Дата: 07.01.09 06:50
Оценка:
Здравствуйте, thesz, Вы писали:

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

T>Прошу прощения, но ФП ни под что конкретно не заточено.
T>Это всё в глазах наблюдателя.

Я под ФП понимаю направление человеческой мысли, разработавшей вполне конкретные языки (Lisp, ML, Haskell, Erlang, etc) со вполне конкретными фичами. Чисто функциями без side-эффектов можно писать и на С++, но его к ФП не причисляют, так как там этих фич и соответствующего синтаксического сахара нет (автоматическое управление паматью, patter matching, lambda functions, curring, high-order functions, etc). Реальная заточка этих фич — работа с рекурентными типами данных.

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

Правда да, есть еще APL-J-K... Но это уже несколько другая область человеческой мысли, уж относят ли ее к ФП или нет.

S>>А на том, что типично пишут программисты, оно особенно не нужно.


T>Какие программисты-то?


Да самые разные. Вот, например, по-видимому самый широкий класс приложений — написание GUI к базам данных. Что-то не слышал, чтобы их вообще кто-то пытался писать на ФЯ. А почему? А потому что разработанные в ФЯ фичи для таких приложений малополезны.
And if you listen very hard the alg will come to you at last.
Re[5]: Мастер-класс по ФП
От: subdmitry Россия  
Дата: 07.01.09 06:52
Оценка:
Здравствуйте, thesz, Вы писали:

T>Лови:

T>
T>doIt = do
T>    increment vA
T>    vB ! vA --> vD *= 10
T>    vF vG --> vH $= 0
T>


T>Монады и операторы — твои друзья.


Еще нет, все никак не разберусь толком с монадами. Нельзя ли в паре слов описать, как эти vA, vB и т.д. попадают в функцию? Для простоты можно ограничиться только первой операцией.
And if you listen very hard the alg will come to you at last.
Re[5]: Мастер-класс по ФП
От: subdmitry Россия  
Дата: 07.01.09 07:09
Оценка:
Здравствуйте, thesz, Вы писали:

T>Сделай-ка аналогичный "ассемблер" на твоём любимом ЯП. Чтобы не менее удобно было — чтобы можно было определять свои "подпрограммы" и тп.


Могу предложить только интерпретатор Пролога, реализованный на Турбо Ассемблере, и то только в виде бинарника (сорцы утеряны). Смотреть в IDA.
http://eoda.by.ru/Data/CrackMes/aliencpu.rar
And if you listen very hard the alg will come to you at last.
Re[8]: Мастер-класс по ФП
От: VoidEx  
Дата: 07.01.09 07:16
Оценка:
Здравствуйте, subdmitry, Вы писали:


S>То есть для честного решения того примера в функцию DoIt() надо передать 7 переменных, чего народ ужаснулся. А так же передавать их во всю цепочку функций, из которых DoIt() вызывается. Меня сейчас будут пинать, но, признаться, в ряде случаев вариант с глобальными переменными мне нравится больше.

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

VE>>
VE>>main = do
VE>>    chan <- newChan :: IO ByteReads
VE>>    s <- getChanContents chan
S>Насчет последней строчки. Она не лишняя? Или это очистка очереди от какого-то мусора?
VE>>


Этой строкой я беру ленивый список всех попадающих в канал значений, который затем передаю в reader. Так же можно делать с файлами, например. reader, как можно заметить, понятия не имеет ни о каких Chan'ах, что даёт нам ещё одну степень абстракции. Я мог и reader'а-то не писать, а сразу написать, что мне со списком делать.
Re[7]: Мастер-класс по ФП
От: geniepro http://geniepro.livejournal.com/
Дата: 07.01.09 08:48
Оценка:
Здравствуйте, VoidEx, Вы писали:

VE>Кстати, я думал, что в Chan может быть один писатель, но не падает. Везёт, или писателей таки может быть куча?


В канал может писать кто угодно, в чей он области видимости, главное что бы тип записываемых данных подошёл. Фактически это же просто очередь с атомарным доступом (как у MVar)...
Re[4]: Мастер-класс по ФП
От: geniepro http://geniepro.livejournal.com/
Дата: 07.01.09 08:51
Оценка:
Здравствуйте, subdmitry, Вы писали:

S>Здравствуйте, deniok, Вы писали:


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


S>Я считаю, что начинать надо с малого. Лично мне не очень понятно, как добиться на Хаскелле решения такой простой проблемы и (серьезно!) хочу его увидеть.


S>Оно не такое уж и бессмысленное. У меня при программировании часто возникает код, подобный написанному. Хочу понять, как получить его аналог в функциональных языках.


А нельзя ли поподробнее? С описанием типов всех этих A, B, C, D...

S>Некоторые тут, кстати, заявляют, что Хаскель лучший императивный язык...


Уточнение: не лучший, а самый прекрасный в мире (Haskell is the world's finest imperative language)...
Re[6]: Мастер-класс по ФП
От: thesz Россия http://thesz.livejournal.com
Дата: 07.01.09 08:53
Оценка:
T>>
T>>vA = ...что-то там такое...
T>>increment var = do { x <- getV var; setV var (x+1) }
T>>doIt = do
T>>    increment vA
T>>    vB ! vA --> vD *= 10
T>>    vF vG --> vH $= 0
T>>

T>>Монады и операторы — твои друзья.
S>Еще нет, все никак не разберусь толком с монадами. Нельзя ли в паре слов описать, как эти vA, vB и т.д. попадают в функцию? Для простоты можно ограничиться только первой операцией.

vA — это название твоей A. В Хаскеле с большой буквы называются конструкторы данных.

То, что increment пришлось определять в отличии от встроенного ++, не беда совершенно.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[8]: Мастер-класс по ФП
От: VoidEx  
Дата: 07.01.09 09:00
Оценка:
Здравствуйте, geniepro, Вы писали:

G>В канал может писать кто угодно, в чей он области видимости, главное что бы тип записываемых данных подошёл. Фактически это же просто очередь с атомарным доступом (как у MVar)...


Спасибо, просто у меня почему-то было ощущение, что это один писатель, много читателей. Не знаю, откуда взялось [ощущение].
Re[4]: Мастер-класс по ФП
От: thesz Россия http://thesz.livejournal.com
Дата: 07.01.09 09:16
Оценка:
S>>>Еще одно мнение в копилку — ФП дает выигрыш на узком классе задач, связанных со сложной работой с динамическими структурами данных (списками, деревьями, etc) — на что оно, собственно, и заточено.
T>>Прошу прощения, но ФП ни под что конкретно не заточено.
T>>Это всё в глазах наблюдателя.

S>Я под ФП понимаю направление человеческой мысли, разработавшей вполне конкретные языки (Lisp, ML, Haskell, Erlang, etc) со вполне конкретными фичами.


Теперь тебе осталось выяснить, как же понимает ФП весь остальной мир.

S>Чисто функциями без side-эффектов можно писать и на С++, но его к ФП не причисляют, так как там этих фич и соответствующего синтаксического сахара нет (автоматическое управление паматью, patter matching, lambda functions, curring, high-order functions, etc).


Вот в лиспе нет pattern matching и currying. Там даже tail call optimization нет. Он всё ещё ФЯ?

(с моей точки зрения, кстати, не так, чтобы особо

S> Реальная заточка этих фич — работа с рекурентными типами данных.


По-моему, здесь мы имеем дело с так называемым non-sequitur.

С логическим скачком, иными словами.

Не видно, как из перечисленных тобой свойств ФП следует заточенность под работу с рекурсивными типами данных.

S>Естественно, в других языках есть и другие заточки, например, на работу с массивами.


А в ФП нет? Почему? "Single Assignment C" does ring any bell?

S>>>А на том, что типично пишут программисты, оно особенно не нужно.


T>>Какие программисты-то?


S>Да самые разные. Вот, например, по-видимому самый широкий класс приложений — написание GUI к базам данных. Что-то не слышал, чтобы их вообще кто-то пытался писать на ФЯ.


По-моему, ты не слышал, как кто-либо вообще хоть что-нибудь писал на ФЯ.

S>А почему? А потому что разработанные в ФЯ фичи для таких приложений малополезны.


А с моей точки зрения потому, что уровень писателей таких приложений в своей массе весьма низок. Потому, что платят мало, потому, что средний наниматель таких программистов сам невысокого уровня.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[6]: Мастер-класс по ФП
От: thesz Россия http://thesz.livejournal.com
Дата: 07.01.09 09:17
Оценка:
T>>Сделай-ка аналогичный "ассемблер" на твоём любимом ЯП. Чтобы не менее удобно было — чтобы можно было определять свои "подпрограммы" и тп.
S>Могу предложить только интерпретатор Пролога, реализованный на Турбо Ассемблере, и то только в виде бинарника (сорцы утеряны). Смотреть в IDA.
S>http://eoda.by.ru/Data/CrackMes/aliencpu.rar

Не уворачивайся. Давай исходник "ассемблера" на твоем ИЯП.

Потрудись немного, уважь старика Зефирова, всё равно сейчас делать нечего.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[9]: Мастер-класс по ФП
От: geniepro http://geniepro.livejournal.com/
Дата: 07.01.09 09:58
Оценка: 18 (2)
Здравствуйте, VoidEx, Вы писали:

VE>Здравствуйте, geniepro, Вы писали:


G>>В канал может писать кто угодно, в чей он области видимости, главное что бы тип записываемых данных подошёл. Фактически это же просто очередь с атомарным доступом (как у MVar)...


VE>Спасибо, просто у меня почему-то было ощущение, что это один писатель, много читателей. Не знаю, откуда взялось [ощущение].


Я как-то баловался
Автор: geniepro
Дата: 14.05.07
-- сто тыщ потоков в один канал писать заставяля. А вот 300 тыщ потоков уже, блин, своппинг вызывают... Да, не Ерланг, всё-таки...

Кстати, с новым сборщиком мусора на этом тесте результаты чуть ли не на порядок лучше (на Pentium DualCore 1.6):
(опции +RTS -K100M -N2 -g2 -RTS )
10 100000 Time = 3.36
100 10000 Time = 3.80
1000 1000 Time = 5.55
10000 100 Time = 6.47
100000 10 Time = 7.42
250000  4 Time = 9.28

import IO
import Time
import System
import Control.Concurrent
import Control.Concurrent.Chan

data Ticker = Tick | Done

n_threads',          n_incs' :: Int
n_threads'  = 1000;  n_incs' = 1000

-- Командная строка: имя.exe +RTS -K100M -N2 -g2 -RTS кол-во_потоков кол-во_инкрементов

main = do
    arg <- getArgs
    let (n_threads, n_incs) = case (map read arg) of
            nt:ni:_ -> (nt,         ni)
            _       -> (n_threads', n_incs')

    t1  <- Time.getClockTime
    hSetBuffering stdout NoBuffering
    putStr $ "Config: " ++ show n_threads ++ " by " ++ show n_incs ++ "  Starting... "

    ticker <- newChan
    finish <- newChan
    result <- newChan

    let foo 0 = finish `writeChan` ()
        foo n = ticker `writeChan` Tick >> yield >> foo (n-1)

        makeThreads 0 = return ()
        makeThreads n = forkIO (foo n_incs) >> makeThreads (n-1)

        tick :: Int -> IO ()
        tick k = do msg <- readChan ticker
                    case msg of
                        Tick -> tick (k+1)
                        Done -> result `writeChan` k

        wait 0 = ticker `writeChan` Done
        wait n = readChan finish >> wait (n-1)

    forkIO     (tick 0)
    forkIO     (wait n_threads)
    makeThreads n_threads

    putStr "Finishing... "
    val <- readChan result
    putStr $ "Done: " ++ show val
    t2  <- Time.getClockTime; printTimeDif t2 t1

printTimeDif ft st = putStrLn $ " Time = " ++ show(Time.tdHour td) ++ ":" ++ show(Time.tdMin td) ++ ":"
                                           ++ show nsecs           ++ "." ++ snms
  where
    td           = ft `Time.diffClockTimes` st
    secs         = Time.tdSec     td
    ms           = Time.tdPicosec td `div` 1000000000
    (nsecs, nms) = if ms < 0 then (secs - 1, ms + 1000) else (secs, ms)
    snms         = reverse $ take 3 $ (reverse $ show nms) ++ "000"
Re[5]: Мастер-класс по ФП
От: geniepro http://geniepro.livejournal.com/
Дата: 07.01.09 10:04
Оценка:
Здравствуйте, thesz, Вы писали:

T>Вот в лиспе нет pattern matching и currying. Там даже tail call optimization нет. Он всё ещё ФЯ?


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

....

T>Потрудись немного, уважь старика Зефирова, всё равно сейчас делать нечего.


эх, а я вот и не заметил эти новогодние дни, потому как отдыхал всего пару дней...
Re[6]: Мастер-класс по ФП
От: thesz Россия http://thesz.livejournal.com
Дата: 07.01.09 18:13
Оценка:
T>>Вот в лиспе нет pattern matching и currying. Там даже tail call optimization нет. Он всё ещё ФЯ?
G>Ну вапще-то используя библиотеки, можно в лисп добавить и паттерн-матчинг, и карринг. А хвостовая рекурсия прямо указана в стандарте схемы, да и в CL тоже есть...

"Я так и думал." (C) Администратор из Half-Life 2.

Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.