Здравствуйте, Evgeny.Panasyuk, Вы писали:
F>>и своя половина эрланга с менее удобным EP>Насколько я вижу, основное удобство в Erlang это Pattern Matching (в C++ PM по типам реализуется легко, так как уже встроено в компилятор, а вот PM по выражениям/значениям — да, сложнее и не удобно).
да, это удобство от динамической типизации.
EP>А вот например "чистота" и иммутабельность внутри тел функций — это скорее минус, императивный код и проще и удобнее.
дело привычки. меня это уже не беспокоит.
куда больше угнетает отсутствие композиции, как в хакселе, и необходимость писать кучу скобок.
...coding for chaos...
Re[46]: Эрланг и все-все-все (на самом деле, не совсем)
Здравствуйте, neFormal, Вы писали:
F>>>и своя половина эрланга с менее удобным EP>>Насколько я вижу, основное удобство в Erlang это Pattern Matching (в C++ PM по типам реализуется легко, так как уже встроено в компилятор, а вот PM по выражениям/значениям — да, сложнее и не удобно). F>да, это удобство от динамической типизации.
Насколько я вижу, динамическая типизация тут ни при чём, это реализуется и в статической. То есть сообщение с полностью стёртым типом, можно сопоставлять со статически типизированными шаблонами/patterns, получая на выходе значение статически типизированное с точностью до типизации шаблона (для шаблона вида ((char, _), int, double), получим значение типа tuple<tuple<char, any>, int, double>).
Кстати, а насколько оправданны сообщения со стёртыми типами? Не лучше ли будет статическое описание возможных типов сообщений для процесса а-ля variant?
Re[47]: Эрланг и все-все-все (на самом деле, не совсем)
Здравствуйте, neFormal, Вы писали:
BZ>>>особенно в многопоточной среде кстати. EP>>Какая разница мутируем ли мы локальные переменные функций? F>а какие языки позволяют мутировать только локальные переменные?
Например в Haskell есть ST Monad, которая в определённом смысле позволяет мутировать локальные переменные в ограниченной области видимости, при этом возвращая чистый результат. Конечно неудобно, через многоэтажные замыкания (скрытые под синтаксических сахаром do), но всё же позволяет.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Насколько я вижу, динамическая типизация тут ни при чём, это реализуется и в статической.
в статике сложнее сопоставить туплы, которые в эрланге повсюду. плюс вложенность.
в статике одна ф-ция с кучей разномастных по типам реализаций расползётся куда сильнее. а в динамике достаточно соблюдать арность ф-ции.
вдобавок без типов код пишется на порядок быстрее. в том же хаскеле или скалке подгон типов под решение занимает кучу времени.
EP>Кстати, а насколько оправданны сообщения со стёртыми типами? Не лучше ли будет статическое описание возможных типов сообщений для процесса а-ля variant?
большинство сообщений уникальны. плодить для них одноразовые типы — это лишняя работа. поэтому даже местные структуры используются в основном для состояний.
но поскольку куча народу полагается на типизацию, то там есть свои сигнатуры, которые обрабатываются редактором и статическим анализатором.
по мне лучше тесты. правда в эрланге с ними очень плохо, потому что поднимать всё дерево процессов долго и неудобно.
...coding for chaos...
Re[48]: Эрланг и все-все-все (на самом деле, не совсем)
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Например в Haskell есть ST Monad, которая в определённом смысле позволяет мутировать локальные переменные в ограниченной области видимости, при этом возвращая чистый результат. Конечно неудобно, через многоэтажные замыкания (скрытые под синтаксических сахаром do), но всё же позволяет.
монады — это боль хаскелекода.не дай б-г ты вляпался в одну из них. и всё. тяни её до самого верха.
так что я не соглашусь. там ты мутируешь не столько локальные переменные, сколько целую ветку ф-ций и вычислений.
поэтому шутка про "тридэ-экшон в три строки" — это нифига не шутка.
...coding for chaos...
Re[47]: Эрланг и все-все-все (на самом деле, не совсем)
Здравствуйте, neFormal, Вы писали:
EP>>Насколько я вижу, динамическая типизация тут ни при чём, это реализуется и в статической. F>в статике сложнее сопоставить туплы, которые в эрланге повсюду. плюс вложенность.
Вложенность тоже не проблема.
F>в статике одна ф-ция с кучей разномастных по типам реализаций расползётся куда сильнее.
Разные реализации-то не на ровном месте появились — а от того что для самой задачи требуется разная обработка. Если не требуется, то есть же шаблоны.
F>а в динамике достаточно соблюдать арность ф-ции.
"перегрузки", только реализованные вручную, а не компилятором.
F>вдобавок без типов код пишется на порядок быстрее. в том же хаскеле или скалке подгон типов под решение занимает кучу времени.
В C++ с этим намного проще чем в Haskell, так как типы выводятся по месту использования, эдакий duck-typing, получается прям как в динамически типизированных языках (правда с вытекающими отсюда подобными проблемами, только в compile-time).
EP>>Кстати, а насколько оправданны сообщения со стёртыми типами? Не лучше ли будет статическое описание возможных типов сообщений для процесса а-ля variant? F>большинство сообщений уникальны. плодить для них одноразовые типы — это лишняя работа. поэтому даже местные структуры используются в основном для состояний.
В тех случаях где стоит выбор между структурой и безликим кортежем — я предпочту структуру. Описать её это секундное дело, выразительность увеличивается (например именованные поля), плюс есть возможность посылать разные сообщения с одинаковыми наборами полей. В Erlang'е же, как я понял, для этого используются атомы, то есть по сути получаются именованные структуры с безымянными полями — poor man's struct.
F>по мне лучше тесты. правда в эрланге с ними очень плохо, потому что поднимать всё дерево процессов долго и неудобно.
Даже 100% покрытие тестами (по строчкам кода) не гарантирует того что отловлены все ошибки с типами. Более того, думаю в общем случае при динамической типизации такую гарантию вообще невозможно получить.
При статической же типизации отлавливается целый класс ошибок, практически бесплатно.
Re[49]: Эрланг и все-все-все (на самом деле, не совсем)
Здравствуйте, neFormal, Вы писали:
EP>>Например в Haskell есть ST Monad, которая в определённом смысле позволяет мутировать локальные переменные в ограниченной области видимости, при этом возвращая чистый результат. Конечно неудобно, через многоэтажные замыкания (скрытые под синтаксических сахаром do), но всё же позволяет. F>монады — это боль хаскелекода.не дай б-г ты вляпался в одну из них. и всё. тяни её до самого верха.
Это если какая-нибудь IO. В случае с ST есть runST — таким образом как раз реализуется сценарий "внутри функции мутации локальных переменных, а наружу выдаётся чистый немонадный результат".
F>так что я не соглашусь. там ты мутируешь не столько локальные переменные, сколько целую ветку ф-ций и вычислений.
Вот пример:
sumST :: Num a => [a] -> a
sumST xs = runST $ do-- runST takes out stateful code and makes it pure again.
n <- newSTRef 0 -- Create an STRef (place in memory to store values)
forM_ xs $ \x -> do-- For each element of xs ..
modifySTRef n (+x) -- add it to what we have in n.
readSTRef n -- read the value of n, and return it.
Здесь мутируется как раз "локальная переменная", а не ветка функций.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
F>>в статике одна ф-ция с кучей разномастных по типам реализаций расползётся куда сильнее. EP>Разные реализации-то не на ровном месте появились — а от того что для самой задачи требуется разная обработка. Если не требуется, то есть же шаблоны.
это больше похоже на перегрузку виртуальных методов или, действительно, шаблоны. только более выразительно.
F>>а в динамике достаточно соблюдать арность ф-ции. EP>Так там появляются точно такие же
"перегрузки", только реализованные вручную, а не компилятором.
фуууу!
EP>В тех случаях где стоит выбор между структурой и безликим кортежем — я предпочту структуру.
попытайся поюзать "безликие кортежи". очень быстро поймёшь преимущества.
EP>Описать её это секундное дело
поменять уже сложнее.
EP>выразительность увеличивается (например именованные поля)
для 2-3 полей это совершенно неважно.
EP>плюс есть возможность посылать разные сообщения с одинаковыми наборами полей.
оно и так есть. если чего-то не лезет, то сделать ещё вложенность.
EP>В Erlang'е же, как я понял, для этого используются атомы, то есть по сути получаются именованные структуры с безымянными полями
именованные туплы. атом — это тип.
это тоже довольно интересная находка. особенно в плане их обработки. много ф-ций заточено именно под именованные туплы.
EP>poor man's struct.
ага, мапы — это классы для бедных, а классы — это мапы для бедных.
F>>по мне лучше тесты. правда в эрланге с ними очень плохо, потому что поднимать всё дерево процессов долго и неудобно. EP>Даже 100% покрытие тестами (по строчкам кода) не гарантирует того что отловлены все ошибки с типами.
особенно, если типов нет.
я покрываю тестами фичи, а не строчки. поэтому мне нужно, чтобы конкретная ветка вычислений работала на всех ожидаемых входных данных.
EP>При статической же типизации отлавливается целый класс ошибок, практически бесплатно.
и вводится новый класс ошибок компиляции. чтоб жизнь мёдом не казалась.
когда оно тебе помогало?
я часто слышу о пользе, даже приводят примеры, но меня оно ещё ни разу не спасало. т.е. вообще.
...coding for chaos...
Re[50]: Эрланг и все-все-все (на самом деле, не совсем)
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Это если какая-нибудь IO. В случае с ST есть runST — таким образом как раз реализуется сценарий "внутри функции мутации локальных переменных, а наружу выдаётся чистый немонадный результат".
да, спутал. у меня другая монада была.
...coding for chaos...
Re[49]: Эрланг и все-все-все (на самом деле, не совсем)
Здравствуйте, neFormal, Вы писали:
EP>>В тех случаях где стоит выбор между структурой и безликим кортежем — я предпочту структуру. F>попытайся поюзать "безликие кортежи". очень быстро поймёшь преимущества.
Использовал, и в Python, и в C++. Преимущества вижу только внутри какого-нибудь метапрограммирования, там где у нас действительно набор безликих полей.
Например в C++ STL в некоторых местах используется pair, причём по смыслу там не просто пара безликих элементов, а у каждого элемента своё особое предназначение.
std::pair<iterator, bool> std::set::insert( const value_type& value );
Постоянно приходится вспоминать какой там порядок элементов в этой паре. Хорошо хоть типы есть, да.
EP>>Описать её это секундное дело F>поменять уже сложнее.
Намного проще чем сообщения-кортежи, так как компилятор поможет найти все ссылающиеся места.
EP>>выразительность увеличивается (например именованные поля) F>для 2-3 полей это совершенно неважно.
Если сам придумал, сразу же использовал и забыл — то может и неважно. В других же случаях даже с парами возникают неудобства — пример выше.
EP>>В Erlang'е же, как я понял, для этого используются атомы, то есть по сути получаются именованные структуры с безымянными полями F>именованные туплы. атом — это тип. F>это тоже довольно интересная находка.
Насколько я понял, атом же по сути это строка, которую в некоторых случаях можно писать без кавычек.
EP>>При статической же типизации отлавливается целый класс ошибок, практически бесплатно. F>и вводится новый класс ошибок компиляции. чтоб жизнь мёдом не казалась. F>когда оно тебе помогало?
Постоянно. Да, с помощью тестов можно отловить подобные ошибки, но при статической типизации обнаружение происходит намного раньше, плюс я могу себе позволить не писать юнит-тесты для простых/очевидных/тривиальных вещей.
Re[50]: Эрланг и все-все-все (на самом деле, не совсем)
Здравствуйте, Evgeny.Panasyuk, Вы писали:
F>>попытайся поюзать "безликие кортежи". очень быстро поймёшь преимущества. EP>Использовал, и в Python, и в C++. Преимущества вижу только внутри какого-нибудь метапрограммирования, там где у нас действительно набор безликих полей. EP>Постоянно приходится вспоминать какой там порядок элементов в этой паре. Хорошо хоть типы есть, да.
по мне, проблема столь же надуманна, как и то, что забудешь, какого типа у тебя переменная, и, мол, поэтому надо использовать венгерку.
тут всё решение в понятных именах переменных. не TempPair, а IdToUser.
EP>>>Описать её это секундное дело F>>поменять уже сложнее. EP>Намного проще чем сообщения-кортежи, так как компилятор поможет найти все ссылающиеся места.
наверное, это единственная проблема. но больше связана с динамикой, чем с безликими кортежами.
решается анализаторами. костыльно, да.
EP>Если сам придумал, сразу же использовал и забыл — то может и неважно. В других же случаях даже с парами возникают неудобства — пример выше.
возможно дело в том, что твои пары потом ещё долго обрабатываются.
в случае же эрланга очень быстро происходит передача кортежей в вызовы. а там уже можно по сигнатуре посмотреть, что да как.
я так всё меньше смотрю на код и всё больше на имена переменных и сигнатуры ф-ций.
EP>Насколько я понял, атом же по сути это строка, которую в некоторых случаях можно писать без кавычек.
это не строка. атом — это специальный тип, который пишется в апострофах только, если выбивается за разрешённый формат. например atom против '$ATOM'
атомы хранятся в специальной таблице на протяжении всей жизни приложения. и количество их ограничено настройкой VM. поэтому генерить атомы противопоказано.
EP>Постоянно. Да, с помощью тестов можно отловить подобные ошибки, но при статической типизации обнаружение происходит намного раньше, плюс я могу себе позволить не писать юнит-тесты для простых/очевидных/тривиальных вещей.
а я не могу позволить не писать тесты для каких-то случаев.
потому что типы типами, а глупость или невнимательность своё возьмут.
...coding for chaos...
Re[51]: Эрланг и все-все-все (на самом деле, не совсем)
Здравствуйте, neFormal, Вы писали:
EP>>Постоянно приходится вспоминать какой там порядок элементов в этой паре. Хорошо хоть типы есть, да. F>по мне, проблема столь же надуманна, как и то, что забудешь, какого типа у тебя переменная, и, мол, поэтому надо использовать венгерку. F>тут всё решение в понятных именах переменных. не TempPair, а IdToUser.
Так об этом и речь, вместо внятных имён получаем невнятные .first и .second.
EP>>Если сам придумал, сразу же использовал и забыл — то может и неважно. В других же случаях даже с парами возникают неудобства — пример выше. F>возможно дело в том, что твои пары потом ещё долго обрабатываются.
В каком смысле?
F>в случае же эрланга очень быстро происходит передача кортежей в вызовы. а там уже можно по сигнатуре посмотреть, что да как.
По какой сигнатуре?
F>я так всё меньше смотрю на код и всё больше на имена переменных и сигнатуры ф-ций.
Имён-то у полей внутри кортежа нет.
EP>>Насколько я понял, атом же по сути это строка, которую в некоторых случаях можно писать без кавычек. F>это не строка. атом — это специальный тип, который пишется в апострофах только, если выбивается за разрешённый формат. например atom против '$ATOM'
Это понятно, я о том что семантически это очень близко к обычной строке.
EP>>Постоянно. Да, с помощью тестов можно отловить подобные ошибки, но при статической типизации обнаружение происходит намного раньше, плюс я могу себе позволить не писать юнит-тесты для простых/очевидных/тривиальных вещей. F>а я не могу позволить не писать тесты для каких-то случаев. F>потому что типы типами, а глупость или невнимательность своё возьмут.
Код-то весь будет тестироваться, я имею в виду что для простых случаев можно обойтись только укрупнённым интеграционным тестированием, без юнит-тестов.
Re[52]: Эрланг и все-все-все (на самом деле, не совсем)
Здравствуйте, Evgeny.Panasyuk, Вы писали:
F>>тут всё решение в понятных именах переменных. не TempPair, а IdToUser. EP>Так об этом и речь, вместо внятных имён получаем невнятные .first и .second.
ну, это у тебя.
а у меня автоимён совсем нет, поэтому надо самому нормально их называть.
F>>в случае же эрланга очень быстро происходит передача кортежей в вызовы. а там уже можно по сигнатуре посмотреть, что да как. EP>По какой сигнатуре?
по сигнатуре ф-ции. там всё видно.
F>>я так всё меньше смотрю на код и всё больше на имена переменных и сигнатуры ф-ций. EP>Имён-то у полей внутри кортежа нет.
имена нужны при отправлении и получении. а промежуточные имена не нужны.
EP>Это понятно, я о том что семантически это очень близко к обычной строке.
уникальный строковый идентификатор, да.
...coding for chaos...
Re[44]: Эрланг и все-все-все (на самом деле, не совсем)
F>афаик в эрланге шедулер останавливает потоки, а не потоки решают, когда им отдать управление.
Так и есть. Каждому процессу выдается 1000 редукций (настраиваемо). Редукция — это вызов функции, посылка сообщения. Когда количество редукций доходит до нуля, процесс выталкивается в конец очереди, и начинает исполняться другой процесс.
Некоторые специальные процессы (типа IO) могут планировщиком насильно передвигаться вперед по очереди, потому что IO в Erlang'е приоритизировано.
Здравствуйте, Mamut, Вы писали:
M>Сильно зависит от алгоритмов. Есть алгоритмы, которые проще и удобнее в императивщине, есть которые в функциональщине.
Да, но в императивном коде можно ограничить себя чистым подмножеством, а в функциональном использовать императив намного труднее (монады с многоэтажными замыканиями)
M>Для 90% быдлокода, что мы все тут в основном пишем, функциональщина выигрывает по простоте и удобности, имхо.
Надо определится с терминами. Многие считают что ФП это "я тут замыкания заиспользовал" — в то время как подобные фичи ортогональны "ФП vs ИП", и присутсвуют и там и там (даже в древнем Smalltalk были замыкания).
Re[46]: Эрланг и все-все-все (на самом деле, не совсем)
Здравствуйте, Evgeny.Panasyuk, Вы писали:
M>>Сильно зависит от алгоритмов. Есть алгоритмы, которые проще и удобнее в императивщине, есть которые в функциональщине. EP>Да, но в императивном коде можно ограничить себя чистым подмножеством, а в функциональном использовать императив намного труднее (монады с многоэтажными замыканиями)
На самом деле многие базовые вещи в синтаксисе Эрланга идут совсем не из функциональщины, а из логического программирования. Но к сожалению они их так кастрировали (кстати как раз раз попыткой подвинуться в сторону функциональщины), что почти все фантастические бонусы исчезли. Мы тут используем в одном проекте полноценный Пролог и работа с ним доставляет только удовольствие. Но почти ничего из его главных возможностей не сохранено в Эрланге. Там это всё обрезали, сохранив только визуальные элементы синтаксиса. Так что даже наличие атомов в Эрланге не имеет особого смысла, в отличие от Пролога.