Re[10]: "LINQ как шаг к ФП". Стиль изложения.
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 22.01.09 16:23
Оценка:
Здравствуйте, LaPerouse, Вы писали:

LP>Все равно неестественно и не натурально


Вдогонку. Отсюда.

So, in the end, has Haskell simply re-invented the imperative wheel?

In some sense, yes. The I/O monad constitutes a small imperative sub-language inside Haskell, and thus the I/O component of a program may appear similar to ordinary imperative code. But there is one important difference: There is no special semantics that the user needs to deal with. In particular, equational reasoning in Haskell is not compromised. The imperative feel of the monadic code in a program does not detract from the functional aspect of Haskell. An experienced functional programmer should be able to minimize the imperative component of the program, only using the I/O monad for a minimal amount of top-level sequencing. The monad cleanly separates the functional and imperative program components. In contrast, imperative languages with functional subsets do not generally have any well-defined barrier between the purely functional and imperative worlds.


Перевод

Ну так что, Haskell просто-напросто изобрёл императивное колесо?

В некотором смысле да. Монада IO образует маленький императивный подъязычок внутри Haskell и, таким образом, компоненты ввода-вывода программы могут являться кодом, похожим на обычный императивный. Но есть одно важное отличие: нет никакой специальной семантики, которая необходима пользователю, чтобы работать с императивом. В частности equational reasoning не скомпрометирован. Императивный привкус монадического кода не преуменьшает функциональные особенности Haskell. Опытный ФП программист способен минимизировать императивную составляющую программы, используя монаду IO для минимального количества топ-левел последовательности действий (приношу ивзинения за корявый перевод). Монада явно разделяет функциональный и императивный код. Напротив, ИЯ с функциональным подмножеством в целом не имеют хорошо определённого барьера между чистым функциональным и императивным мирами.

Re[11]: "LINQ как шаг к ФП". Стиль изложения.
От: LaPerouse  
Дата: 22.01.09 16:24
Оценка: 1 (1)
Здравствуйте, thesz, Вы писали:

LP>>Если я могу получить все, что мне требуется получить от хаскеля,


T>А что требуется?


Ну, теперь мне требуется LINQ

Если серьезно, то не так уж и много (для java):

1. Какой-то сахар на уровне языка, чтобы можно было легко оперировать с соотв. структурами данных (кортежи, односвязные списки)
2. ФВП, удобный синтаксис для их определения. Удобный синтаксис для лямбда-функций. Замыкания.
3. Templates как в С++
4. Сопоставление с образцом

Удобный и естественный способ работать с мутабельными данными, но это уже есть.

Дополнительные требования: компилятор должен оптимизировать хвостовую рекурсию. В javac все печально
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[12]: "LINQ как шаг к ФП". Стиль изложения.
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 22.01.09 16:26
Оценка:
Здравствуйте, LaPerouse, Вы писали:

LP>Если серьезно, то не так уж и много (для java):


Эх.. Больная мозоль!..
Re[11]: "LINQ как шаг к ФП". Стиль изложения.
От: LaPerouse  
Дата: 22.01.09 16:30
Оценка:
Здравствуйте, lomeo, Вы писали:

L>В общем не всё так плохо в императивном программировании на чистях ФЯ.


Все, что ты привел, очень интересно. Но на самом деле GUI, всякая интерактивность и другие по определению императивные вещи — это далеко не единственные случае, когда требуется императивность. Вот я работаю в области энергетики, часто приходится писать алгоритмы по раскрутке/трансформации электроцепей. Очень часто наиболее разумное решение оказывается именно императивным (хотя и далеко не всегда). Я считаю, что язык должен предоставлять возможности для естественного императивного программирования.
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[12]: "LINQ как шаг к ФП". Стиль изложения.
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 22.01.09 16:40
Оценка:
Здравствуйте, LaPerouse, Вы писали:

L>>В общем не всё так плохо в императивном программировании на чистях ФЯ.


LP>Все, что ты привел, очень интересно. Но на самом деле GUI, всякая интерактивность и другие по определению императивные вещи — это далеко не единственные случае, когда требуется императивность. Вот я работаю в области энергетики, часто приходится писать алгоритмы по раскрутке/трансформации электроцепей. Очень часто наиболее разумное решение оказывается именно императивным (хотя и далеко не всегда). Я считаю, что язык должен предоставлять возможности для естественного императивного программирования.


Императивное — это значит последовательное, разве нет? Ну и плюс отсюда вытекает состояние. Т.е. я не имел в виду именно GUI, интерактивность и т.д. Надо было придумать какой-то пример, вот я его и взял. На самом деле, как мне кажется, нет разницы что именно мы программируем. Если мы можем удобно запрограммировать императивно на Haskell одну вещь, то, наверное, сможем и другую. Т.е. я не вижу, почему твой императивный алгоритм на Haskell запишется хуже, чем на Яве (раз уж ты её приводил в пример). Можно как нибудь раскрыть этот момент?
Re[13]: "LINQ как шаг к ФП". Стиль изложения.
От: LaPerouse  
Дата: 22.01.09 16:55
Оценка:
Здравствуйте, lomeo, Вы писали:

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


L>>>В общем не всё так плохо в императивном программировании на чистях ФЯ.


LP>>Все, что ты привел, очень интересно. Но на самом деле GUI, всякая интерактивность и другие по определению императивные вещи — это далеко не единственные случае, когда требуется императивность. Вот я работаю в области энергетики, часто приходится писать алгоритмы по раскрутке/трансформации электроцепей. Очень часто наиболее разумное решение оказывается именно императивным (хотя и далеко не всегда). Я считаю, что язык должен предоставлять возможности для естественного императивного программирования.


L>Императивное — это значит последовательное, разве нет? Ну и плюс отсюда вытекает состояние. Т.е. я не имел в виду именно GUI, интерактивность и т.д. Надо было придумать какой-то пример, вот я его и взял. На самом деле, как мне кажется, нет разницы что именно мы программируем. Если мы можем удобно запрограммировать императивно на Haskell одну вещь, то, наверное, сможем и другую. Т.е. я не вижу, почему твой императивный алгоритм на Haskell запишется хуже, чем на Яве (раз уж ты её приводил в пример). Можно как нибудь раскрыть этот момент?


Вот боевой пример из эклипса, который я написал десять минут назад

/**
     * Функция трансформации последовательных соединений
     * @param s - схема
     * @return true, если была произведена нормализация, false в противном случае
     * @throws Exception 
     */
    public static boolean transform(Scheme s) throws TransformException
    {
        boolean res = false;
        
        List<INode> nodes = new ArrayList<INode>();
        
        for (INode node : s.getNodes())
            nodes.add(node);
        
        int len = nodes.size();
        for (int i=0; i<len; i++)
        {
            INode node = nodes.get(i);
            if (SchemeHelper.getElementsCount(node) == 2 && !SchemeHelper.isEntrantPoint(s, node))
            {
                IElement element1 = SchemeHelper.getElements(node).get(0);
                IElement element2 = SchemeHelper.getElements(node).get(1);
                
                if (element1.isLinear() && element2.isLinear())
                {
                    INode node1 = SchemeHelper.getOtherNode((LinearElement) element1, node);
                    INode node2 = SchemeHelper.getOtherNode((LinearElement) element2, node);
                    
                    IElement newElem = merge((LinearElement)element1, (LinearElement)element2);
                    
                    s.detachElement(element1);
                    s.detachElement(element2);
                    s.removeNode(node);
                    len--;
                    s.attachElement(newElem, new INode[]{node1, node2});
                    res = true;
                }
            }
        }
        
        return res;
    }


как видишь, алгоритм чисто императивный, используется мутабельная Scheme. Наиболее разумно на каждом шаге рекурсии модифицировать именно существующую схему, это разумнее, чем собирать новую. На java это можно делать легко и естественно, спрятав изменение состояния за интерфейсами. Подозреваю, что на хаскель был бы дикий изврат с монадой State или Scheme, завернутой в IO. В общем, было бы тоже самое, но был бы оверхед по синтаксису,который мне совершенно не нужен.
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[12]: "LINQ как шаг к ФП". Стиль изложения.
От: thesz Россия http://thesz.livejournal.com
Дата: 22.01.09 17:13
Оценка:
LP>Вот я работаю в области энергетики, часто приходится писать алгоритмы по раскрутке/трансформации электроцепей. Очень часто наиболее разумное решение оказывается именно императивным (хотя и далеко не всегда). Я считаю, что язык должен предоставлять возможности для естественного императивного программирования.

<a href=http://thesz.livejournal.com/920509.html&gt;Ба</a>! Мне кажется совсем обратное.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[14]: "LINQ как шаг к ФП". Стиль изложения.
От: thesz Россия http://thesz.livejournal.com
Дата: 22.01.09 17:28
Оценка:
LP>как видишь, алгоритм чисто императивный, используется мутабельная Scheme. Наиболее разумно на каждом шаге рекурсии модифицировать именно существующую схему, это разумнее, чем собирать новую.

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

При построении новой структуры старая остаётся доступной. Можно сравнить их по какому-либо параметру и оценить результаты.

LP>На java это можно делать легко и естественно, спрятав изменение состояния за интерфейсами. Подозреваю, что на хаскель был бы дикий изврат с монадой State или Scheme, завернутой в IO.


Нет. Обычная функция, Connect -> Connect.

Зачем здесь IO?

В компиляторах так я вообще бы запретил использовать изменяемые структуры. Потому, что там анализ добавляет информацию к уже существующей, что эффективно меняет тип. Что означает, что структуру надо строить заново.

Построение структуры вместо изменения уменьшает количество ошибок.

Такие, вот, дела.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[12]: "LINQ как шаг к ФП". Стиль изложения.
От: thesz Россия http://thesz.livejournal.com
Дата: 22.01.09 17:32
Оценка:
LP>>>Если я могу получить все, что мне требуется получить от хаскеля,
T>>А что требуется?
LP>1. Какой-то сахар на уровне языка, чтобы можно было легко оперировать с соотв. структурами данных (кортежи, односвязные списки)
LP>2. ФВП, удобный синтаксис для их определения. Удобный синтаксис для лямбда-функций. Замыкания.
LP>3. Templates как в С++

Отличный пункт.

LP>4. Сопоставление с образцом

LP>Удобный и естественный способ работать с мутабельными данными, но это уже есть.
LP>Дополнительные требования: компилятор должен оптимизировать хвостовую рекурсию. В javac все печально

Это можно получить много, где. В том же OCaml. Про использование OCaml и изменяемых графовых структур — см. ссылку на статью, что я дал чуть прежде.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[14]: "LINQ как шаг к ФП". Стиль изложения.
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 23.01.09 07:13
Оценка:
Здравствуйте, LaPerouse, Вы писали:

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


Почему наиболее разумно?

LP>На java это можно делать легко и естественно, спрятав изменение состояния за интерфейсами. Подозреваю, что на хаскель был бы дикий изврат с монадой State или Scheme, завернутой в IO. В общем, было бы тоже самое, но был бы оверхед по синтаксису,который мне совершенно не нужен.


Если писать на Scheme, завёрнутой в IO, то оверхед будет только при разыменовании примитивных переменных (i, len в нашем случае). И от этого оверхеда можно избавиться, определив свои функции над IORef Int. Т.е. сделать код один в один (и даже короче, за счёт того, что одинаковые участки легко выделять в Haskell и очень тяжело в Яве).

Однако, я бы этот алгоритм скорее всего записал чисто функционально. К сожалению, ничего не знаю о типе Scheme.
Re[15]: "LINQ как шаг к ФП". Стиль изложения.
От: LaPerouse  
Дата: 23.01.09 20:44
Оценка:
Здравствуйте, lomeo, Вы писали:

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


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


L>Почему наиболее разумно?


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

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

LP>>На java это можно делать легко и естественно, спрятав изменение состояния за интерфейсами. Подозреваю, что на хаскель был бы дикий изврат с монадой State или Scheme, завернутой в IO. В общем, было бы тоже самое, но был бы оверхед по синтаксису,который мне совершенно не нужен.


L>Если писать на Scheme, завёрнутой в IO, то оверхед будет только при разыменовании примитивных переменных (i, len в нашем случае). И от этого оверхеда можно избавиться, определив свои функции над IORef Int. Т.е. сделать код один в один (и даже короче, за счёт того, что одинаковые участки легко выделять в Haskell и очень тяжело в Яве).




L>Однако, я бы этот алгоритм скорее всего записал чисто функционально.


А зря. Это как раз тот случай, когда лучше отодвинуть религию на второй план. На Хаскель надейся, но сам не плошай

>>К сожалению, ничего не знаю о типе Scheme.


Сейчас нет исходников, а то я бы запостил ее сюда. Об этом типе нужно знать только то, что в контракте есть методы для добавления ноды, присоединения элемента к указанным нодам, отсоединения элемента от схемы:

addNode(INode node)
attachElement(IElement element, INode[] nodes)
detachElement(IElement element)
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[15]: "LINQ как шаг к ФП". Стиль изложения.
От: LaPerouse  
Дата: 23.01.09 20:51
Оценка:
Здравствуйте, thesz, Вы писали:

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


T>Теперь представь, что тебе надо оценивать изменения. Алгоритм преобразования такой, что не всегда даёт оптимизирующее преобразование. Ну, так случилось.


T>При построении новой структуры старая остаётся доступной. Можно сравнить их по какому-либо параметру и оценить результаты.


Ну можно сделать scheme.clone() перед тем, как скармливать ее алгоритму. Правда, при отсутствии прозрачности ссылок этим можно получить по почкам. Но тем не менее

LP>>На java это можно делать легко и естественно, спрятав изменение состояния за интерфейсами. Подозреваю, что на хаскель был бы дикий изврат с монадой State или Scheme, завернутой в IO.


T>Нет. Обычная функция, Connect -> Connect.


T>Зачем здесь IO?


В нее можно обернуть scheme и тем самым иметь состояние

T>Построение структуры вместо изменения уменьшает количество ошибок.


Мне это конечно же известно, но в некоторых случаях, когда изменения небольшие, а структура данных нетривиальная, то уместнее именно изменять. В примере выше как раз тот случай.
За ссылку спасибо, почитаю завтра.
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[16]: "LINQ как шаг к ФП". Стиль изложения.
От: thesz Россия http://thesz.livejournal.com
Дата: 23.01.09 22:53
Оценка:
LP>Мне это конечно же известно, но в некоторых случаях, когда изменения небольшие, а структура данных нетривиальная, то уместнее именно изменять. В примере выше как раз тот случай.

Вот уж извини, но это не тот случай. Если бы изменения большие и тривиальные, то есть, строить долго, зато мало вероятности ошибиться — тогда, да, можно (но не надо, NB!) на месте изменять.

А если и построить быстро и ошибка вероятна — лучше перестраивать. Всегда можно откатиться назад, если не проходит проверка преобразований на сохранение смысла сети.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[16]: "LINQ как шаг к ФП". Стиль изложения.
От: thesz Россия http://thesz.livejournal.com
Дата: 23.01.09 22:55
Оценка:
L>>Почему наиболее разумно?
LP>Суть алгоритма состоит в том, чтобы на каждой ноде, удовлетворяющей определенному условию (а именно, которая соединяет два линейных элемента) сделать следующее: заменить элементы, соединяемые этой нодой, новым элементом. Таким образом в императивном решении достаточно удалить эту ноду, эти два элемента и добавить новый элемент, который начинается на нодах, с которых начинались с другой стороны старые два элемента — это ровно три действия. В функциональном решении нужно клонировать каждую ноду, которая не удовлетворят этому условию, в новую схему, то есть получить часть схемы без нод, удовлетворяющих условию.

Это не так. Дей1ствия ровно те же. Клонирования большей части нод нет.

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


Во-во. Выспишься и увидишь, в чём был неправ.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[10]: "LINQ как шаг к ФП". Стиль изложения.
От: FR  
Дата: 24.01.09 18:30
Оценка: :)
Здравствуйте, LaPerouse, Вы писали:

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


То есть ты пишешь на Ocaml?
Re[13]: "LINQ как шаг к ФП". Стиль изложения.
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.01.09 16:50
Оценка: -1
Здравствуйте, lomeo, Вы писали:

L>Императивное — это значит последовательное, разве нет? Ну и плюс отсюда вытекает состояние. Т.е. я не имел в виду именно GUI, интерактивность и т.д. Надо было придумать какой-то пример, вот я его и взял. На самом деле, как мне кажется, нет разницы что именно мы программируем. Если мы можем удобно запрограммировать императивно на Haskell одну вещь, то, наверное, сможем и другую. Т.е. я не вижу, почему твой императивный алгоритм на Haskell запишется хуже, чем на Яве (раз уж ты её приводил в пример). Можно как нибудь раскрыть этот момент?


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

Меж тем заметное приемущество в объеме кода и в его понятности Хаскель дает только по сравнению с Явой или С++. С последним вообще очень удобно мериться если речь идет о выскокуровневых конструкциях. Там отсутствие GC и замыканий, плюс наличие небезопасного кода приводит к необходимости таких приседаний, что все что угодно на его фоне выглядит хорошо. Даже Ява, не то что Хаскель.

Ну, а сравнить Хаскель с чем-то более высокоуровенвым и приемущество как-то сразу улетучивается.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: "LINQ как шаг к ФП". Стиль изложения.
От: VoidEx  
Дата: 26.01.09 17:00
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ну, а сравнить Хаскель с чем-то более высокоуровенвым и приемущество как-то сразу улетучивается.

С чем например?

Ну и заодно приведи пример.
Я вот приведу пример на понятность:
take 20.randoms >>> print.maximum

И на краткость:
when True act = act >> return ()
when False _ = return ()


Только не надо про синтетичность примеров (when-то и в Немерле есть) и приводить свои примеры с использованием какой-нибудь штуки из .Net, которой нет на Хаскеле. Это не краткость языка.
Мне действительно хотелось бы посмотреть на язык с записью короче, чем у Хаскеля.
Re[15]: "LINQ как шаг к ФП". Стиль изложения.
От: Курилка Россия http://kirya.narod.ru/
Дата: 26.01.09 17:09
Оценка: +2 :)
Здравствуйте, VoidEx, Вы писали:

VE>Мне действительно хотелось бы посмотреть на язык с записью короче, чем у Хаскеля.


Если просто "у кого короче", то J переплюнет хаскель
Re[16]: "LINQ как шаг к ФП". Стиль изложения.
От: VoidEx  
Дата: 26.01.09 17:10
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Если просто "у кого короче", то J переплюнет хаскель


Этот язык я видел, да
Хотелось бы, конечно, не жертвовать понятностью ради короткости.
Re[15]: "LINQ как шаг к ФП". Стиль изложения.
От: IT Россия linq2db.com
Дата: 26.01.09 17:13
Оценка: +1 :))) :))) :)
Здравствуйте, VoidEx, Вы писали:

VE>Мне действительно хотелось бы посмотреть на язык с записью короче, чем у Хаскеля.


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