Re[4]: C hack, фича шарпа :)
От: Quintanar Россия  
Дата: 22.04.05 13:17
Оценка: 8 (1)
Здравствуйте, Gaperton, Вы писали:

Q>>yeild return != continuations. И я не слышал о реализациях через стек.

G>Ок, объясни разницу.

yield неявно создает продолжение только для текущей функции, а не для программы в целом. И мы не можем ничего сделать со стеком. Если язык поддерживает продолжения или позволяет легко писать в CPS стиле, то проблемы стека нет, но C# не такой.
В С# мы можем написать, например, следующий код:
let a = choose_from list1 in
let b = choose_from list2 in
if a = b then a else fail ();;

Где choose_from возвращает по элементу из списка (сохраняя продолжения), а fail вызывает последнее сохраненное продолжение. Но не сможем такой:
let do_something x =
if x = 3 then true else fail ();;

let x = choose_from list in
do_something x;;

Или еще хуже, когда мы обнаруживаем, что элемент не тот вообще в другом месте программы
Re[5]: C hack, фича шарпа :)
От: Курилка Россия http://kirya.narod.ru/
Дата: 22.04.05 13:20
Оценка:
Здравствуйте, Quintanar, Вы писали:

Q>Здравствуйте, Курилка, Вы писали:


Q>>>Точно не так же гладко. Например, ни одна библиотека не позволит работать с продолжениями также гладко, как это позволяет Scheme. Даже в Lisp, самом гибком языке, соответствующая библиотека имеет существенные ограничения.


К>>А вот тут можно чуть подробнее?


Q>Про Лисп:

Q>Если происходит CPS преобразование программы (есть такая библиотека), то нельзя пользоваться в call-with-current-continuation некоторыми специальными формами (типа обработки исключений, вроде). Если же используется полуавтоматическое преобразование как у Грехема, то все функции должны удовлетворять довольно жестким условиям. В частности, любой путь исполнения должен заканчиваться или вызовом другой аналогичной функции или специальным макросом возврата результата + еще кое что. Это можно посмотреть в его книге.

Пасиб, как раз недавно начал...
Re[4]: C hack, фича шарпа :)
От: Трурль  
Дата: 22.04.05 13:21
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Ну раз ты это говоришь, то имеет смысл разобраться поподробнее, что такое continuations .

Имхо — извращение, ещё большее, чем монады .
Re[5]: C hack, фича шарпа :)
От: Quintanar Россия  
Дата: 22.04.05 13:25
Оценка:
Здравствуйте, Трурль, Вы писали:

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


G>>Ну раз ты это говоришь, то имеет смысл разобраться поподробнее, что такое continuations .

Т>Имхо — извращение, ещё большее, чем монады .

Не согласен. Во-первых, продолжения существенно проще для понимания, во-вторых, в некоторых задачах они очень удобны. Например, при обходе какой-нибудь сложной структуры, как тут уже говорили.
Re[5]: о хвостовой рекурсии.
От: Gaperton http://gaperton.livejournal.com
Дата: 22.04.05 13:27
Оценка:
Здравствуйте, Quintanar, Вы писали:

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


Q>>>Совсем необязательно, чтобы вызов каждой функции обязательно шел через стек. На ФЯ можно написать большую программу, которая вообще не будет использовать стек для вызова функций. Если все функции хвостово-рекурсивные, компилятор проведет оптимизацию и вызов функций будет выглядеть как jump.

G>>Не совсем так. Обычно виртуальная машина поддерживает хвостовую рекурсию именно как вызов функции, т. е. она не переводится в jump. Стеком нельзя не пользоваться, на нем выделяются локальные переменные. Кстати, мне точно известно, что дотнетовская виртуальная машина Mono тоже поддерживает хвостовую рекурсию.

Q>Я приводил в Декларативном Программировании пример программы на OCaml с использованием continuations. Это была простая операционная система. Все функции были хвостово-рекурсивными и для проверки я запустил тест на переключение двух задач огромное количество раз. Поскольку память не расходовалась вообще, я сделал вывод, что стек не используется и все вызовы функций преобразованы в прямые переходы.


Память не расходуется, это так, но стек используется (для аллокации локальных переменных). Просто при "хвостовом" вызове вместо создания нового стек-фрейма переиспользуется фрейм последнего вызова — так проще.

Если применяется виртуальная машина — то обычно делают специальную поддержку для хвостовой рекурсии на уровне команд виртуальной машины. При компиляции в машинный код в некоторых местах возможны оптимизации посредством замены на прямые переходы.

В принципе, это не так важно, это детали.
Re[6]: C hack, фича шарпа :)
От: Трурль  
Дата: 22.04.05 13:33
Оценка:
Здравствуйте, Quintanar, Вы писали:

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

Глобальный goto еще проще для понимания и тоже очень удобен в некоторых задачах.
Хотя собсвенно против продолжений ничего не имею, но где-нибудь глубоко в библиотеках, или в макросах, или в промежуточном коде.
Re[7]: C hack, фича шарпа :)
От: Quintanar Россия  
Дата: 22.04.05 13:40
Оценка:
Здравствуйте, Трурль, Вы писали:

Т>Глобальный goto еще проще для понимания и тоже очень удобен в некоторых задачах.

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

Да, это верно, хотя сравнение все-таки не совсем точное. Продолжения могут привести к очень запутанному коду, с этим не поспоришь.
Re[5]: yeild return != continuations
От: Gaperton http://gaperton.livejournal.com
Дата: 22.04.05 15:46
Оценка:
Здравствуйте, Quintanar, Вы писали:

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


Q>>>yeild return != continuations. И я не слышал о реализациях через стек.

G>>Ок, объясни разницу.

Q>yield неявно создает продолжение только для текущей функции, а не для программы в целом. И мы не можем ничего сделать со стеком. Если язык поддерживает продолжения или позволяет легко писать в CPS стиле, то проблемы стека нет, но C# не такой.

То есть, разница только в том, что в C# continuation не является first-class object, т.е.
1) нельзя явно создать continuation и
2) явно передать его в функцию параметром (всегда происходит возврат только в вызывающий continuation).

В результате continuation passing style применять невозможно. Я правильно понимаю?
Re[5]: C hack, фича шарпа :)
От: Gaperton http://gaperton.livejournal.com
Дата: 22.04.05 16:04
Оценка:
Здравствуйте, Трурль, Вы писали:

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


G>>Ну раз ты это говоришь, то имеет смысл разобраться поподробнее, что такое continuations .

Т>Имхо — извращение, ещё большее, чем монады .

Меж тем, как говорит Андрей Собчук, от них может быть и польза
http://www.smalltalk.ru/articles/web-continuations.html
Re[6]: yeild return != continuations
От: Quintanar Россия  
Дата: 22.04.05 16:53
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>То есть, разница только в том, что в C# continuation не является first-class object, т.е.

G>1) нельзя явно создать continuation и
G>2) явно передать его в функцию параметром (всегда происходит возврат только в вызывающий continuation).
G>В результате continuation passing style применять невозможно. Я правильно понимаю?

CPS — это, насколько я понимаю, нечто типа объектно-ориентированного стиля. Некоторые языки поддерживают его с рождения, в некоторых его можно в какой-то степени имитировать. В C# с ним очень плохо, поскольку невозможно красиво эмулировать функции без возврата, сильно мешает стек. В ФЯ с этим легче за счет того, что 1) функции гораздо короче и меньше проблем с их CPS-изацией 2) можно использовать хвостовую оптимизацию и 3) лексические замыкания помогают легко запомнить локальное состояние.
Т.е. писать в CPS на C# можно, но нет никакого смысла с точки зрения понятности программы и быстроты разработки. Можно как в статье применять его в ограниченных пределах и все.
Re[6]: yeild return != continuations
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 22.04.05 18:04
Оценка:
Gaperton пишет:
> Q>>>yeild return != continuations. И я не слышал о реализациях через стек.
> G>>Ок, объясни разницу.
>
> Q>yield неявно создает продолжение только для текущей функции, а не для
> программы в целом. И мы не можем ничего сделать со стеком. Если язык
> поддерживает продолжения или позволяет легко писать в CPS стиле, то
> проблемы стека нет, но C# не такой.
> То есть, разница *только *в том, что в C# continuation не является
> first-class object, т.е.
> 1) нельзя явно создать continuation и
> 2) явно передать его в функцию параметром (всегда происходит возврат
> только в вызывающий continuation).
>
> В результате continuation passing style применять невозможно. Я
> правильно понимаю?

имхо, не совсем. CPS *можно* применять без перво-классных продолжений.
Поскольку я внятно прояснить эти вопросы не смог, дам некоторые
англоязычные ссылки:
Continuations <br />
for Curmudgeons

continuation <br />
from Avi Briant (автор Seaside)
,
CPS,
coroutine

--
Andrei N.Sobchuck
JabberID: andreis@jabber.ru. ICQ UIN: 46466235.
Posted via RSDN NNTP Server 1.9
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[7]: yeild return != continuations
От: Gaperton http://gaperton.livejournal.com
Дата: 22.04.05 18:46
Оценка:
Здравствуйте, Quintanar, Вы писали:

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


G>>То есть, разница только в том, что в C# continuation не является first-class object, т.е.

G>>1) нельзя явно создать continuation и
G>>2) явно передать его в функцию параметром (всегда происходит возврат только в вызывающий continuation).

Q>Т.е. писать в CPS на C# можно, но нет никакого смысла с точки зрения понятности программы и быстроты разработки. Можно как в статье применять его в ограниченных пределах и все.


Ладно, CPS — это в конце концов вторично. Подтвердите или опровергните изначальные тезисы 1 и 2 (когда я говорю о continuation в С# я имею в виду yield return). Вы согласны с ними?
Re[8]: C hack, фича шарпа :)
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 22.04.05 19:52
Оценка:
Здравствуйте, stalcer, Вы писали:

К>>...в шарпе создаётся объект, хранящий этот самый контекст...


S>Вот в этом-то я сильно сомневаюсь . Скорее всего локальные переменные все таки хранятся в стеке.


Нет ничего проще чем проверить на практике. Вот реализация итератора из примера:
[CompilerGenerated]
private sealed class _Power_d__0 : IEnumerator<object>, IEnumerator, IDisposable
{
    private int _1__state;
    private object _2__current;
    public int _counter_5__1;
    public int _result_5__2;
    public int exponent;
    public int number;

    public _Power_d__0(int _1__state)
    {
        this._1__state = _1__state;
    }

    private bool MoveNext()
    {
        switch (_1__state)
        {
            case 0:
                _1__state = -1;
                _counter_5__1 = 0;
                _result_5__2 = 1;
                break;

            case 1:
                _1__state = -1;
                break;

            default:
                return false;
        }
        if (_counter_5__1++ < exponent)
        {
            _result_5__2 *= number;
            _2__current = _result_5__2;
            _1__state = 1;
            return true;
        }
        return false;
    }
    
    void IEnumerator.Reset()
    {
        throw new NotSupportedException();
    }
 
    void IDisposable.Dispose(){}
    
    object IEnumerator<object>.Current
    {
        get { return _2__current; }
    }
    
    object IEnumerator.Current
    {
        get { return _2__current; }
    }
}
... << RSDN@Home 1.1.4 beta 6 rev. 433>>
AVK Blog
Re[11]: C hack, фича шарпа :)
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 22.04.05 20:29
Оценка: 72 (4)
Здравствуйте, Serginio1, Вы писали:

S> А нука покажи рекурсивный обход на FW 2.


Вот, на скорую руку накидал. Вроде работает.
using System;
using System.Collections;
using System.Collections.Generic;

public class Node
{
    private readonly string _name;
    private readonly List<Node> _children;

    public Node(string name, params Node[] children)
    {
        _name = name;
        _children = new List<Node>(children);
    }

    public override string ToString()
    {
        return _name;
    }

    public IEnumerable EnumerateRecursively()
    {
        yield return this;
        foreach (Node c in _children)
            foreach (Node cc in c.EnumerateRecursively())
                yield return cc;
    }
}

public class Test
{
    static void Main()
    {
        Node root = new Node("1",
            new Node("11",
                new Node("111",
                    new Node("1111")),
                new Node("112"),
                new Node("113",
                    new Node("1131",
                        new Node("11311",
                            new Node("113111",
                                new Node("1131111"),
                                new Node("1131112",
                                    new Node("11311121")),
                                new Node("1131113")))))),
            new Node("12"),
            new Node("13"));

        foreach (Node node in root.EnumerateRecursively())
             Console.WriteLine(node);
    }
}
... << RSDN@Home 1.1.4 beta 6 rev. 433>>
AVK Blog
Re[8]: C hack, фича шарпа :)
От: Gaperton http://gaperton.livejournal.com
Дата: 22.04.05 20:52
Оценка: 10 (3)
Здравствуйте, Cyberax, Вы писали:

C>Не рулят. Фибры — весьма глючны, непортабельны, давно не развиваются и

C>не дают много преимуществ.
C>http://blogs.msdn.com/larryosterman/archive/2005/01/05/347314.aspx

Файберы — рулят, ни разу не глючны, на портабельность плевать — будут проблемы и похуже при попытке портировать нечно с Win32 (хотя аналоги есть и в Unix под названием user-level threads), развиваться там нечему — все крайне просто (весь API — вызовов 6), и даже если бы не было файберов в API, их можно было бы написать ручками на asm-е.

И разумеется, файберы дают массу преимуществ при грамотном использовании. Применение файберов в рамках legacy-продуктов CQG позволило нам более чем вдвое удешевить разработку и рефакторинг некоторых подсистем клиента и сервера. Про глючность — выдумки, у нас уже три года сервера на файберах крутятся, и ни одной проблемы с ними не было.

Что касательно производительности — накладные расходы на переключение файбера мизерные по сравнению и с переключением контекста потока, и с раскруткой стека при коллбэчном асинхронном стиле программирования, что позволяет применять их совершенно по другому — плодить их в большом количестве, часто переключать контексты, и т.д. Короче, файберы рулят со страшной силой.

Статья эта — отстой полный.

They're also HARD to deal with — you essentially have to write your own scheduler.

Ай-ай-ай. Как раз поэтому файберы и хороши, что можно (но совсем не обязательно) писать свой шедулер. Наш шедулер занимает 468 строк на С++. Пишется за пару недель. И он очень хорош, просто великолепен. Управляется с приоритетами так, как нужно нам, а не оперсистеме, и работает нормально на том количестве параллельных активностей, которая удобна нам, а не разработчикам ядра. Нам, например, удобно, чтобы их было порядка 10К, а не идиотская сотня с идиотскими пулами.

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

Второй момент — на файберах удобно реализовывать сопрограммы и continuations. Что не требует планировщика — автор очевидно этот случай вообще не рассматривает. Афтарлох, короче.

The other reason that fibers have remained obscure is more fundamental. It has to do with Moore's law (there's a reason for the posts yesterday and the day before).

Ну-ну. Закон Мура что-то не помогает виндам чувствовать себя нормально хотя-бы с 1К потоков на процесс — я уже не говорю о большом количестве активно взаимодействующих потоков, которые часто переключаются и жрут мало CPU на обработку одной мессаги. То есть в том сценарии, когда мы в процентах много теряем на переключение контекста — мы продолжим терять столько же. И закон Мура ровным счетом никак не помогает.
Re[9]: C hack, фича шарпа :)
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 23.04.05 09:46
Оценка:
Gaperton пишет:
> Далее, я написал очень много файберного кода, и как врач говорю, что в

Что-то к green threads они добавляют или их возможности полностью
єквивалентны?

--
Andrei N.Sobchuck
JabberID: andreis@jabber.ru. ICQ UIN: 46466235.
Posted via RSDN NNTP Server 1.9
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[10]: C hack, фича шарпа :)
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 23.04.05 10:40
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>Что-то к green threads они добавляют или их возможности полностью

ANS>єквивалентны?

Это они и есть
... << RSDN@Home 1.1.4 beta 6 rev. 433>>
AVK Blog
Re[12]: C hack, фича шарпа :)
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 25.04.05 07:34
Оценка:
Здравствуйте, AndrewVK, Вы писали:

Пример достаточно простой. Вариантов в общем то 2 Re[12]: C hack, фича шарпа :)
Автор: Serginio1
Дата: 22.04.05
. Кстати как они в итоге реализованы ?????
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
и солнце б утром не вставало, когда бы не было меня
Re[8]: yeild return != continuations
От: Quintanar Россия  
Дата: 25.04.05 08:19
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>>>То есть, разница только в том, что в C# continuation не является first-class object, т.е.

G>>>1) нельзя явно создать continuation и
G>>>2) явно передать его в функцию параметром (всегда происходит возврат только в вызывающий continuation).

G>Ладно, CPS — это в конце концов вторично. Подтвердите или опровергните изначальные тезисы 1 и 2 (когда я говорю о continuation в С# я имею в виду yield return). Вы согласны с ними?


2) поскольку кроме yield (return | break) ничего больше нет, то мы вернемся в вызвавшую функцию. Поэтому мы не можем передать продолжение, созданное в месте вызова yield выше. Наверно, можно передать this, но все это будет некрасивым хаком.

1) Можно, но только для данной функции и при наличии больших ограничений.

Короче, мы зашли куда-то не туда. yield на нормальные продолжения похож очень слабо, нет вообще смысла их сравнивать, поскольку yield был создан для упрощения программирования итераторов и только.
Re[9]: А что это за атрибут такой интересный?
От: xvost Германия http://www.jetbrains.com/company/people/Pasynkov_Eugene.html
Дата: 25.04.05 08:32
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


AVK>
AVK>[CompilerGenerated]
AVK>private sealed class _Power_d__0 : IEnumerator<object>, IEnumerator, IDisposable
AVK>


В MSDN о нем ни слова....?
С уважением, Евгений
JetBrains, Inc. "Develop with pleasure!"
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.