Re[44]: Паттерны проектирования - копипаста!
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.01.13 12:21
Оценка:
Здравствуйте, Tanker, Вы писали:

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


T>>>Конечно вернет, а что тут особенного ? При чем вычислится ровно один элемент. А если например ты будешь вызывать вот так Any(x => x == "тарелка борща"); то никогда не вернет.


S>>За счет чего while(true) остановится на одном элементе?


T>Очевидно, за счет средств ОС — потоки, файберы. Никакого обмана.

К сожалению, не вижу никакого повода для того что бы средства ОС вмешались в цикл while(true) и на потоках и файберах обеспечили бы разрывность его выполнения. Этот цикл в коде на C# не отличается от многих других, которые не нуждаются в файберах.
Re[45]: Паттерны проектирования - копипаста!
От: Tanker  
Дата: 10.01.13 12:36
Оценка:
Здравствуйте, samius, Вы писали:

T>>Очевидно, за счет средств ОС — потоки, файберы. Никакого обмана.

S>К сожалению, не вижу никакого повода для того что бы средства ОС вмешались в цикл while(true) и на потоках и файберах обеспечили бы разрывность его выполнения. Этот цикл в коде на C# не отличается от многих других, которые не нуждаются в файберах.

Если ты забыл, то разговор был про "хотя бы один способ эмуляции yield return без поддержки языка".
А вот поводов использовать потоки и файберы хотя бы для генераторов выше крыши даже в С#, хочешь, создай новый тред,а я покажу примеры, правда может не сейчас а как водится через пару месяцев.
The animals went in two by two, hurrah, hurrah...
Re[46]: Паттерны проектирования - копипаста!
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.01.13 12:42
Оценка:
Здравствуйте, Tanker, Вы писали:

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


T>>>Очевидно, за счет средств ОС — потоки, файберы. Никакого обмана.

S>>К сожалению, не вижу никакого повода для того что бы средства ОС вмешались в цикл while(true) и на потоках и файберах обеспечили бы разрывность его выполнения. Этот цикл в коде на C# не отличается от многих других, которые не нуждаются в файберах.

T>Если ты забыл, то разговор был про "хотя бы один способ эмуляции yield return без поддержки языка".

Я пока ни одного не увидел. Начал читать статью по твоей ссылке про корутины на MC++.
T>А вот поводов использовать потоки и файберы хотя бы для генераторов выше крыши даже в С#, хочешь, создай новый тред,а я покажу примеры, правда может не сейчас а как водится через пару месяцев.
Я же не утверждал что нет поводов использовать потоки и файберы. Я про то, что на мой взгляд цикл из твоего примера ничем не отличается от любых других циклов без yield, await и т.п. Мне непонятно, почему он будет выполняться частями.
Re[38]: Паттерны проектирования - копипаста!
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.01.13 14:00
Оценка:
Здравствуйте, Tanker, Вы писали:

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


I>>>Это можно эмулировать десятком способов, не было только языковой поддержки. Например в winapi есть такая вещь, как файберы — очень интересная штукенция.

S>> Покажите мне, как эмулировать Enumerable.TakeWhile на файберах. Его устройство в терминах yield return мне понятно.

T>Точно так же, как и без файберов

Если "точно так же", то в чём смысл использовать файберы?
T> Надеюсь идея ясна:
Нет. Без описания типа вашего c, или хоты бы без кода функций yield() идея совершенно неясна.
Ну и для понятности стоило бы всё-таки привести код Enumerable.TakeWhile, а не пару малопонятных корутин.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[47]: Паттерны проектирования - копипаста!
От: Tanker  
Дата: 10.01.13 15:16
Оценка:
Здравствуйте, samius, Вы писали:

T>>Если ты забыл, то разговор был про "хотя бы один способ эмуляции yield return без поддержки языка".

S>Я пока ни одного не увидел. Начал читать статью по твоей ссылке про корутины на MC++.

T>>А вот поводов использовать потоки и файберы хотя бы для генераторов выше крыши даже в С#, хочешь, создай новый тред,а я покажу примеры, правда может не сейчас а как водится через пару месяцев.

S>Я же не утверждал что нет поводов использовать потоки и файберы. Я про то, что на мой взгляд цикл из твоего примера ничем не отличается от любых других циклов без yield, await и т.п. Мне непонятно, почему он будет выполняться частями.

Ты напиши по русски, а то я не понимаю какой ещ цикл ты хочешь увидеть. Вроде бесконечный цикл и any я тебе показал
The animals went in two by two, hurrah, hurrah...
Re[48]: Паттерны проектирования - копипаста!
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.01.13 15:25
Оценка:
Здравствуйте, Tanker, Вы писали:

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


S>>Я же не утверждал что нет поводов использовать потоки и файберы. Я про то, что на мой взгляд цикл из твоего примера ничем не отличается от любых других циклов без yield, await и т.п. Мне непонятно, почему он будет выполняться частями.


T>Ты напиши по русски, а то я не понимаю какой ещ цикл ты хочешь увидеть. Вроде бесконечный цикл и any я тебе показал

Вроде как уже написал. И по-русски.
Re[39]: Паттерны проектирования - копипаста!
От: Tanker  
Дата: 10.01.13 15:57
Оценка:
Здравствуйте, Sinclair, Вы писали:

T>>Точно так же, как и без файберов

S>Если "точно так же", то в чём смысл использовать файберы?

Смысл в том, что короутины получаеются взрослые, со всеми прибамбасами — рекурсией, вызовом других короутин и тд и тд. В C# скажем нет возможности сделать var x = yield; кроме как разводить грязь навроде
var request = new Request<string>();
...
yield return request; 
var x = request.Value;


T>> Надеюсь идея ясна:

S>Нет. Без описания типа вашего c, или хоты бы без кода функций yield() идея совершенно неясна.

        public void yield(R value)
        {
            _next.Send(value); // отдать по цепочке
        }

        public R yield()
        {
            return _input.Get(); // блокирующий ресурс, будит вызывающий код, для примера см BlockingCollection
        }


c это просто враппер вокруг короутины для доступа к методам yield

S>Ну и для понятности стоило бы всё-таки привести код Enumerable.TakeWhile, а не пару малопонятных корутин.


Мне комбинаторs не нужены, лень тестировать и отлаживать, вот, накидал приблизительный код, адаптировал из имеющихся комбинаторов и тестов (where + select). Вобще комбинаторы здесь баловство, все хочется выпилить полноценный Linq2Co, но руки не дойдут

        public static Co<T> TakeWhile<T>(this Co<T> pipe, Func<T, bool> predicate)
        {
            return pipe.Then(c => 
            {
                while (true)
                {
                    var x = c.yield(); // read from input
        
                    if (predicate(option.Value))
                    {
                        c.yield(option.Value); // write to output
                        continue;
                    }
                    break;
                }
            });
        }

...
       [TestMethod]
        public void LinqSimpleTest()
        {
            var source = Co.New<string>();
            var result = new StringBuilder();
            var x = (from s in source where isNumber(s) select s).TakeWhile(x => x != "6").Then(n => saveTo(result));

            f.Send("1");
            f.Send("2");
            f.Send("text");
            f.Send("4");
            f.Send("5");
            f.Send("6");
            f.Close();

            Assert.AreEqual("1245", result.ToString());
        }
The animals went in two by two, hurrah, hurrah...
Re[49]: Паттерны проектирования - копипаста!
От: Tanker  
Дата: 10.01.13 15:59
Оценка:
Здравствуйте, samius, Вы писали:

S>>>Я же не утверждал что нет поводов использовать потоки и файберы. Я про то, что на мой взгляд цикл из твоего примера ничем не отличается от любых других циклов без yield, await и т.п. Мне непонятно, почему он будет выполняться частями.


T>>Ты напиши по русски, а то я не понимаю какой ещ цикл ты хочешь увидеть. Вроде бесконечный цикл и any я тебе показал

S>Вроде как уже написал. И по-русски.

Потому что функция выполняется в отдельном потоке. Каждый вызов yield явно останавливает с помощнь Monitor.Wait а каждый вызов MoveNext итератора пробуждает xthtp Monitor.PulseAll.
The animals went in two by two, hurrah, hurrah...
Re[50]: Паттерны проектирования - копипаста!
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.01.13 16:27
Оценка:
Здравствуйте, Tanker, Вы писали:

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


T>Потому что функция выполняется в отдельном потоке. Каждый вызов yield явно останавливает с помощнь Monitor.Wait а каждый вызов MoveNext итератора пробуждает xthtp Monitor.PulseAll.

Вот теперь идея понятна, спасибо. Разве что я не соглашусь что это эмуляция yield return.
Так же, наверное можно, на цикле сообщений сэмулировать. Все-таки это эмуляция семантики, но не конкретного решения с машиной состояний и замыканием.
Re[51]: Паттерны проектирования - копипаста!
От: Tanker  
Дата: 10.01.13 16:34
Оценка:
Здравствуйте, samius, Вы писали:

T>>Потому что функция выполняется в отдельном потоке. Каждый вызов yield явно останавливает с помощнь Monitor.Wait а каждый вызов MoveNext итератора пробуждает xthtp Monitor.PulseAll.

S>Вот теперь идея понятна, спасибо. Разве что я не соглашусь что это эмуляция yield return.
S>Так же, наверное можно, на цикле сообщений сэмулировать. Все-таки это эмуляция семантики, но не конкретного решения с машиной состояний и замыканием.

Я эмулировал не шарповкий yield, а питоновские короутины. Генератор это баловства ради прямо сегодня написал, что бы разобраться с монитором.
The animals went in two by two, hurrah, hurrah...
Re[52]: Паттерны проектирования - копипаста!
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.01.13 16:41
Оценка:
Здравствуйте, Tanker, Вы писали:

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


S>>Так же, наверное можно, на цикле сообщений сэмулировать. Все-таки это эмуляция семантики, но не конкретного решения с машиной состояний и замыканием.


T>Я эмулировал не шарповкий yield, а питоновские короутины. Генератор это баловства ради прямо сегодня написал, что бы разобраться с монитором.


Вот оно что, я об этом узнал лишь сейчас.
Re[40]: Паттерны проектирования - копипаста!
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.01.13 04:56
Оценка:
Здравствуйте, Tanker, Вы писали:

T>Смысл в том, что короутины получаеются взрослые, со всеми прибамбасами — рекурсией, вызовом других короутин и тд и тд. В C# скажем нет возможности сделать var x = yield; кроме как разводить грязь навроде

T>
T>var request = new Request<string>();
T>...
T>yield return request; 
T>var x = request.Value;
T>

Брр. Во-первых, мы говорили не про корутины, а про Enumerable Pattern.
Во-вторых, в C# скажем есть возможность сделать
var x = await getX;



T>
T>        public void yield(R value)
T>        {
T>            _next.Send(value); // отдать по цепочке
T>        }

T>        public R yield()
T>        {
T>            return _input.Get(); // блокирующий ресурс, будит вызывающий код, для примера см BlockingCollection
T>        }
T>

Кто такие _next и _input? Как устроены Send и Get?
У меня складывается впечатление, что вы пытаетесь переизобрести RxLib, совместив IObservable и IEnumerable в вашем Co.

T>c это просто враппер вокруг короутины для доступа к методам yield

А что завёрнуто внутрь этого враппера?

S>>Ну и для понятности стоило бы всё-таки привести код Enumerable.TakeWhile, а не пару малопонятных корутин.


T>Мне комбинаторs не нужены, лень тестировать и отлаживать, вот, накидал приблизительный код, адаптировал из имеющихся комбинаторов и тестов (where + select). Вобще комбинаторы здесь баловство, все хочется выпилить полноценный Linq2Co, но руки не дойдут


T>
T>        public static Co<T> TakeWhile<T>(this Co<T> pipe, Func<T, bool> predicate)
T>        {
T>            return pipe.Then(c => 
T>            {
T>                while (true)
T>                {
T>                    var x = c.yield(); // read from input
        
T>                    if (predicate(option.Value))
T>                    {
T>                        c.yield(option.Value); // write to output
T>                        continue;
T>                    }
T>                    break;
T>                }
T>            });
T>        }

T>...
T>       [TestMethod]
T>        public void LinqSimpleTest()
T>        {
T>            var source = Co.New<string>();
T>            var result = new StringBuilder();
T>            var x = (from s in source where isNumber(s) select s).TakeWhile(x => x != "6").Then(n => saveTo(result));

T>            f.Send("1");
T>            f.Send("2");
T>            f.Send("text");
T>            f.Send("4");
T>            f.Send("5");
T>            f.Send("6");
T>            f.Close();

T>            Assert.AreEqual("1245", result.ToString());
T>        }
T>

1. Похоже на опечатку. Вы имели в виду var f = (from s in ...), и x.Value?
2. А чего так сложно-то? В оригинале мы имеем
public static IEnumerable<T> TakeWhile<T>(this IEnumerable<T> source, Predicate<T> predicate)
{
  foreach(var x in source)
    if (predicate(x))
      yield return x;
    else 
      break;
    }

3. У вас всё ещё не видно поддержки стандартных енумераторов. Это ограничивает интероперабельность со стандартными коллекциями. Или она таки есть, но я её не вижу?
4. Енумераторное решение помимо Send и Get работает с IDisposable, гарантируя освобождение ресурсов. У вас как с поддержкой исключений? Получит ли корутина аналог Dispose() в тот момент, когда вызывающая её корутина решила "хватит" (как это происходит в настоящем TakeWhile)?
5. Могу ли я скормить один и тот же источник в два разных TakeWhile? Вот так:
[TestMethod]
public void LinqSimpleTest()
{
  var source = new List<string>();
  var result = new StringBuilder();
  var x1 = (from s in source where isNumber(s) select s).TakeWhile(x => x != "6").GetEnumerator();
  var x2 = (from s in source where isNumber(s) select s).TakeWhile(x => x != "2").GetEnumerator();
  source.AddRange(new string[] {"1", "2", "text", "4", "5", "6"});
  foreach(var i1 in x1)
    Console.WriteLn(i1);
  foreach(var i2 in x2)
    Console.WriteLn(i2);

Ввша реализация с _next.Send() меня настораживает.
Также настораживает то, что я не вижу способа в корутине работать с разнотипными значениями. У вас оба yield имеют тип T. Непонятно, как мне сделать

async string FormatUser(Task<string> name, Task<int> age)
{
   return await name + ", " await age + ", лет";
}
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[45]: Паттерны проектирования - копипаста!
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.01.13 05:04
Оценка: +2
T>Но по моему это глупусть, на потоках намного проще а издержки те же самые.
Насчёт издержек есть внутренне чувство ошибочности. AFAIR, файберы а) не отжирают по мегабайту стека на рыло в адресном пространстве процесса и б) значительно дешевле переключают контекст.
Скажем, в серверном приложении заводить целый отдельный поток каждый раз, как кто-то напишет from i in items where i.name.Length > 0 выглядит несколько страшным.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[41]: Паттерны проектирования - копипаста!
От: Tanker  
Дата: 11.01.13 09:20
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Во-вторых, в C# скажем есть возможность сделать

S>
S>var x = await getX;
S>


Здесь тоже есть такая возможность, но это я не реализовывал. Цель написания либы это эксперименты с короутинами и мониторами

S>Кто такие _next и _input? Как устроены Send и Get?


_next это следующая короутина. _input это вход, просто блокирующий ресурс. Для примера можно взять BlockingCollection<>, будет оно самое, только я написал свой, с целью разобраться с мониторами.

S>У меня складывается впечатление, что вы пытаетесь переизобрести RxLib, совместив IObservable и IEnumerable в вашем Co.


Короутины древнее не только IEnumerable, но всех дотнетов, виндовсов и линуксов вместе взятых. Так что скорее await и yield return выглядят попыткой изобрести короутины.
Скажем на короутинах эвенты и коллекции можно обрабатывать одним и тем же кодом.
Кроме того, RX это реактивный код, а мне нужен императивный.

T>>c это просто враппер вокруг короутины для доступа к методам yield

S>А что завёрнуто внутрь этого враппера?

Изоляция чисто для интелисенса, а то короутина поддерживает IEnumerable например.

T>>Мне комбинаторs не нужены, лень тестировать и отлаживать, вот, накидал приблизительный код, адаптировал из имеющихся комбинаторов и тестов (where + select). Вобще комбинаторы здесь баловство, все хочется выпилить полноценный Linq2Co, но руки не дойдут


S>1. Похоже на опечатку. Вы имели в виду var f = (from s in ...), и x.Value?


Да, опечатка. Я говорил, что это приблизительный код.

S>2. А чего так сложно-то? В оригинале мы имеем


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

S>3. У вас всё ещё не видно поддержки стандартных енумераторов. Это ограничивает интероперабельность со стандартными коллекциями. Или она таки есть, но я её не вижу?


В моем первом примере про генератор все это есть. Пока только короутина и генератор это разные классы, у меня тут хаос и шатание, три разных варианта пробую. Но вобще достаточно одного.

S>4. Енумераторное решение помимо Send и Get работает с IDisposable, гарантируя освобождение ресурсов. У вас как с поддержкой исключений? Получит ли корутина аналог Dispose() в тот момент, когда вызывающая её корутина решила "хватит" (как это происходит в настоящем TakeWhile)?


С исключениями посложнее из за отдельного потока. Исключения буду делать по мере необходимости. Пока "я пейшу бес ашыбок".

S>5. Могу ли я скормить один и тот же источник в два разных TakeWhile? Вот так:


Конечно. Но вообще говоря linq это не то, ради чего нужны короутины. Меня прежде всего интересует возможность делать энергичный императивный код ленивым.

S>Ввша реализация с _next.Send() меня настораживает.


Это именно то ради чего я начал изучать короутины

S>Также настораживает то, что я не вижу способа в корутине работать с разнотипными значениями. У вас оба yield имеют тип T.


Да, библиотечка далека от завершения. Я на ней в основном проверяю кое какие идеи, это не продакшн код. Правда публиковать его не буду, хочу все таки опробовать в продакшне.
The animals went in two by two, hurrah, hurrah...
Re[46]: Паттерны проектирования - копипаста!
От: Tanker  
Дата: 11.01.13 09:45
Оценка:
Здравствуйте, Sinclair, Вы писали:

T>>Но по моему это глупусть, на потоках намного проще а издержки те же самые.

S>Насчёт издержек есть внутренне чувство ошибочности. AFAIR, файберы а) не отжирают по мегабайту стека на рыло в адресном пространстве процесса и б) значительно дешевле переключают контекст.
S>Скажем, в серверном приложении заводить целый отдельный поток каждый раз, как кто-то напишет from i in items where i.name.Length > 0 выглядит несколько страшным.

Дотнет в общем случае не поддерживает файберы и требует слишком большого количества телодвижений:

Since fibers running managed code all exist on the same thread, switching between them causes problems for the exception handlers on a "managed" fiber. To avoid this I hook in the CLR host from unmanaged code, and using four undocumented APIs I inform the runtime about the presence of fibers, and notify it just before switching between fibers.


У файбера как минимум свой стек + fiber local storage. А мегабайт стека у потока можно и уменьшить, это как раз и не проблема. Переключение потоков много времени занимает, я как нибудь сделаю замеры, сравню с питоновской динамикой, не думаю что результаты будут провальными.

Либа то не ради Linq2Co начиналась, Linq это побочный эффект. Задача телеграфа, Odd Word problem и подобные очень легко решаются на короутинах. Без толковой поддержки в самом рантайме linq просто баловство, т.к. поток будет на каждый источник, комбинатор, транзитный и терминальный узлы. Т.е. одна строчка на linq в N комбинаторов породит 2N потоков, оптимизациями я пока не планирую заниматься, мне сейчас нужен как можно более чистый и читабельный код.
The animals went in two by two, hurrah, hurrah...
Re[42]: Паттерны проектирования - копипаста!
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.01.13 09:52
Оценка:
Здравствуйте, Tanker, Вы писали:

T>_next это следующая короутина.

Откуда корутина "знает", кто там следующий?

T>_input это вход, просто блокирующий ресурс. Для примера можно взять BlockingCollection<>, будет оно самое, только я написал свой, с целью разобраться с мониторами.

С мониторами всё не так, как с фиберами. Если чо. Использование потоков для корутин — это жуткий, чудовищный оверкилл.

S>>У меня складывается впечатление, что вы пытаетесь переизобрести RxLib, совместив IObservable и IEnumerable в вашем Co.


T>Короутины древнее не только IEnumerable, но всех дотнетов, виндовсов и линуксов вместе взятых. Так что скорее await и yield return выглядят попыткой изобрести короутины.

И тем не менее.

T>Скажем на короутинах эвенты и коллекции можно обрабатывать одним и тем же кодом.

T>Кроме того, RX это реактивный код, а мне нужен императивный.
Вы что-то путаете. Императивный код — это IEnumerable, и он уже есть. Именно Rx потенциально позволяет обрабатывать евенты и коллекции одним и тем же кодом, т.к. содержит врапперы для превращения одного в другое.

T>Изоляция чисто для интелисенса, а то короутина поддерживает IEnumerable например.


S>>2. А чего так сложно-то? В оригинале мы имеем


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

Ну вот отсюда и мораль, что "эмуляция" выходит чудовищно дорогостоящей по ресурсам и многословной в синтаксисе.

T>В моем первом примере про генератор все это есть. Пока только короутина и генератор это разные классы, у меня тут хаос и шатание, три разных варианта пробую. Но вобще достаточно одного.

Скорее всего этот один вариант будет слишком тяжёлый. Но эксперименты — это интересно
Мне пока нравится идея Rx — в том смысле, что некоторый код удобнее писать в "активном" стиле, а некоторый — в "пассивном". "Пассивный" стиль — это всякие бесконтекстные штуки, типа "когда смениласьСистемнаяЦветоваяСхема -> ПерерисуйВсеОкна". Как только нужен контекст (скажем, детект дабл-клика), программирование в таком стиле превращается в адов кошмар. Я хочу иметь простой и понятный код, который описывает, как из потока кликов выделить дабл-клики, и простота и понятность требуют активного стиля. А сами дабл-клики — бесконтекстны, поэтому для их обработки я хочу писать в пассивном стиле.
Потому Rx выглядит сексуально — в нём оба стиля присутствуют, с возможностью явного переключения.
Побочный эффект — возможность писать "как бы активный" код, который на самом деле реактивный.
Единственное преимущество такого кода перед традиционным — низкое потребление ресурсов. Потому что если я хочу решить задачу "отпарсить HTTP-запрос по мере его прихода в сокет", то проще всего это сделать через blocking input.
Но это требует целого отдельного потока, который жрёт стек, но большую часть времени спит и затрудняет шедулинг.
IOCP гораздо эффективнее, но он требует пассивного стиля написания, что усложняет работу.
Хочу сразу всё — писать код парсинга в "активном стиле", но автоматически преобразовывать его в "реактивный" без отжирания ресурсов ОС.
Хочу иметь возможность так выворачивать не только работу с дискретными множествами (IEnumerable<T>), но и с потоками.
Потому что я хочу взять парсер XML, который имеет наглость активно читать из переданного ему StreamReader, в лучшем случае блокируя поток в ожидании инпута, и подсунуть к нему AntiStream, в который я буду пихать байты в удобном мне темпе.

T>С исключениями посложнее из за отдельного потока. Исключения буду делать по мере необходимости. Пока "я пейшу бес ашыбок".

Пока что я вижу сложности не в потоках, а в том, что у вас нет никакой семантики для Dispose.

T>Конечно. Но вообще говоря linq это не то, ради чего нужны короутины. Меня прежде всего интересует возможность делать энергичный императивный код ленивым.

Непонятно, как это будет работать с учётом единственности _next.

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

удачи. Да, не трогайте фиберы — вам не удастся их завести без манипуляций с CLR Host.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[47]: Паттерны проектирования - копипаста!
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.01.13 10:28
Оценка:
Здравствуйте, Tanker, Вы писали:
T>Либа то не ради Linq2Co начиналась, Linq это побочный эффект. Задача телеграфа, Odd Word problem и подобные очень легко решаются на короутинах.
А можно привести сами задачи? А то мне кажется, что на Rx или Linq или async/await они решаются ещё легче.

T>Без толковой поддержки в самом рантайме linq просто баловство, т.к. поток будет на каждый источник, комбинатор, транзитный и терминальный узлы. Т.е. одна строчка на linq в N комбинаторов породит 2N потоков, оптимизациями я пока не планирую заниматься, мне сейчас нужен как можно более чистый и читабельный код.

Именно поэтому я и считаю решение на потоках с мониторами не более чем курьёзом.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[48]: Паттерны проектирования - копипаста!
От: Tanker  
Дата: 11.01.13 10:59
Оценка:
Здравствуйте, Sinclair, Вы писали:

T>>Либа то не ради Linq2Co начиналась, Linq это побочный эффект. Задача телеграфа, Odd Word problem и подобные очень легко решаются на короутинах.

S>А можно привести сами задачи? А то мне кажется, что на Rx или Linq или async/await они решаются ещё легче.

http://c2.com/cgi/wiki?OddWordProblem, там есть ссылка на решения чуть не на всех языках
http://code.google.com/p/coroutines/wiki/UserGuide — там есть описание задачи и само решение
The animals went in two by two, hurrah, hurrah...
Re[43]: Паттерны проектирования - копипаста!
От: Tanker  
Дата: 11.01.13 11:22
Оценка:
Здравствуйте, Sinclair, Вы писали:

T>>_next это следующая короутина.

S>Откуда корутина "знает", кто там следующий?

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

S>Вы что-то путаете. Императивный код — это IEnumerable, и он уже есть. Именно Rx потенциально позволяет обрабатывать евенты и коллекции одним и тем же кодом, т.к. содержит врапперы для превращения одного в другое.


IEnumerable это pull. RX это push. Мне же надо сразу и то и другое.

S>Потому Rx выглядит сексуально — в нём оба стиля присутствуют, с возможностью явного переключения.


Вот это я не понял, поясни пожалуйста. Как детектить дабл клики я знаю. А что такое активный стиль в RX ?

S>Единственное преимущество такого кода перед традиционным — низкое потребление ресурсов. Потому что если я хочу решить задачу "отпарсить HTTP-запрос по мере его прихода в сокет", то проще всего это сделать через blocking input.

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

blocking input нормально решается с короутинами. Шедулинг будет такой же как и с await.

S>IOCP гораздо эффективнее, но он требует пассивного стиля написания, что усложняет работу.

S>Хочу сразу всё — писать код парсинга в "активном стиле", но автоматически преобразовывать его в "реактивный" без отжирания ресурсов ОС.

Это и есть короутины

T>>С исключениями посложнее из за отдельного потока. Исключения буду делать по мере необходимости. Пока "я пейшу бес ашыбок".

S>Пока что я вижу сложности не в потоках, а в том, что у вас нет никакой семантики для Dispose.

Диспозить вобщем не проблема, но я это даже не начинал,

T>>Конечно. Но вообще говоря linq это не то, ради чего нужны короутины. Меня прежде всего интересует возможность делать энергичный императивный код ленивым.

S>Непонятно, как это будет работать с учётом единственности _next.

По дефолту _next это короутина Fork. Собтсвенно из за этого и получается 2N потоков. Т.е. цепь может выглядет реально вот так
source->Fork->Where->Fork->TakeUntil->Fork->Select->Fork\
            \                                            ->Join->Fork->terminal
            \>Where->Fork->TakeWhile->Fork->Select->Fork/

А можно даже завести цикл и получится один из вариантов рекурсии.
The animals went in two by two, hurrah, hurrah...
Re[44]: Паттерны проектирования - копипаста!
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.01.13 08:56
Оценка:
Здравствуйте, Tanker, Вы писали:
T>Конвейер жостко связаный и мутабельный, по крайней мере в текущей реализации. Как сделать иммутабельный я пока что не пробовал.
Ок, понятно.
Имхо, вам стоит покопать в сторону Task<T>. Очень похожий функционал, плюс будете иметь синтаксическую поддержку в языке.

T>IEnumerable это pull. RX это push. Мне же надо сразу и то и другое.

IObservable и IEnumerable дуальны.
Вызываете IEnumerable.ToObservable() и получаете Push. Вызываете foreach(item in observable) — и получаете Pull. См. http://msdn.microsoft.com/en-us/library/hh211873(v=vs.103).aspx
T>Вот это я не понял, поясни пожалуйста. Как детектить дабл клики я знаю. А что такое активный стиль в RX ?
Ну собственно это и есть активный стиль. Когда я пишу алгоритм над IObservable так, как будто это pull, пользуясь либо IEnumerable, либо Query Comprehension.

T>blocking input нормально решается с короутинами. Шедулинг будет такой же как и с await.

Ну то есть вы эмулируете await, только без синтаксической поддержки. Смысл неясен. Особенно пугают упоминания monitor.PulseAll и прочие прожорливые вещи.

T>Это и есть короутины

Корутины — это всего лишь один из способов представить требуемое. И не факт, что самый хороший.
T>Диспозить вобщем не проблема, но я это даже не начинал,
Диспозить проблема в присутствии исключений. Почитайте блог Липперта на предмет особенностей обработки исключений в iterator block.

T>А можно даже завести цикл и получится один из вариантов рекурсии.

Интересно.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.