Re[19]: Литература по метапрограммированию
От: Undying Россия  
Дата: 09.06.11 08:32
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>
WH>def loop(arg)
WH>{
WH>    comp Rx
WH>    {
WH>        defcomp res = Request1(arg);
WH>        if (res.IsError)
WH>            loop(arg);
WH>        else
WH>            Request2(res);
WH>    }
WH>}
WH>


Можно тоже самое, но на шарпе и без синтаксического сахара? А то непонятно каким образом этот метод возвращает управлению потоку при ожидании результата выполнения.
Re[19]: Литература по метапрограммированию
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 09.06.11 09:11
Оценка:
WH>Тебя заклинило на pull подходе. А он не всегда оптимален.

pull хорош при описании структуры программы.
push хорош при описании потока управления
Re[19]: Литература по метапрограммированию
От: Undying Россия  
Дата: 12.06.11 08:03
Оценка: :)))
Здравствуйте, WolfHound, Вы писали:

WH>Но там есть очень интересный пример.

WH>От пользователя идет поток событий.
WH>Сначала стоит фильтр который ждет чтобы мужду событиями прошло не меньше Н миллисекунд. Ибо, зачем спамить сервер пока пользователь печатает.
WH>Потом стоит фильтр, который не пропускает два одинаковых события подряд.
WH>Далее делаются запросы к веб серверу.
WH>Причем если очередное событие пришло раньше, чем сервер ответил, то текущий запрос отменяется (он уже не актуален) и посылается новый.
WH>После чего ответ проталкивается в UI.

Что в этой задаче сложного и интересного?

IEnumerable<Step> EventsAnalytic(TaskPull pull, Queue<Event> events, Form form)
{
  SlyFilter filter = new SlyFilter(events);
  
  while (true)
  {
    Event event = filter.Filter();
    if (event != null)
    {
      Task task = pull.StartTask(ThreadLabel.Server, ServerSend(event));
      yield return new WaitStep(delegate
        {
          return task.IsCompleted || events.Count != 0;
        });

      if (task.IsCompleted)
      {
        ServerResult result = task.Finish<ServerResult>();
        // Изменяем UI
        form.Text = result.Title;
      }
    }
    else
    {
      yield return new WaitStep();
    }
  }
}

void Main()
{
  // Запускаем анализатор событий в главном потоке
  pull.StartTask(ThreadLabel.Main, EventAnalytic(pull, events, form);
}


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

WH>Тебя заклинило на pull подходе. А он не всегда оптимален.


Pull подход практически всегда оптимален, т.к. позволяет получить предсказуемо работающий код за счет строго определенного порядка обработки. При push подходе определенный порядок обработки принципиально невозможен, т.к. события приходят произвольным образом, соответственно сложность push кода зашкаливает даже на простых задачах.
Re[20]: Литература по метапрограммированию
От: WolfHound  
Дата: 12.06.11 11:22
Оценка:
Здравствуйте, Undying, Вы писали:

U>Что в этой задаче сложного и интересного?

А ты посмотри видео и сравни полученное решение со своим.
Что происходит у тебя не ясно.
Где глотание быстроприходящих сообщений?
Как происходит пробуждение уснувшей задачи?
Где отмена тормозящего запроса, если пришло новое событие?
Сколько потоков этот код держит во время ожидания?

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

yield это магатонны сахара.
А чтобы не ждать есть немерле.

U>Pull подход практически всегда оптимален, т.к. позволяет получить предсказуемо работающий код за счет строго определенного порядка обработки. При push подходе определенный порядок обработки принципиально невозможен, т.к. события приходят произвольным образом, соответственно сложность push кода зашкаливает даже на простых задачах.

То что ты не умеешь его готовить не значит что его готовить невозможно.
Если мы работаем с потоком сообщений то мы очень легко можем контролировать порядок событий.
Смотри видео. Там показаны примеры.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[21]: Литература по метапрограммированию
От: Undying Россия  
Дата: 12.06.11 13:00
Оценка:
Здравствуйте, WolfHound, Вы писали:

U>>Что в этой задаче сложного и интересного?

WH>А ты посмотри видео и сравни полученное решение со своим.

Данное решение логически не содержит практически ничего лишнего, так что максимум что можно это записать его лаконичнее, но не принципиально проще.

WH>Что происходит у тебя не ясно.

WH>Где глотание быстроприходящих сообщений?

filter.Filter();

WH>Как происходит пробуждение уснувшей задачи?


По таймеру. Можно дополнить форсированными пробуждениями, но в данной задаче это бессмысленно.

WH>Где отмена тормозящего запроса, если пришло новое событие?


Если нужна именно отмена старого запроса, а не игнорирование его результатов, то нужно добавить пару строчек кода:

if (!task.IsCompleted)
  pull.StartTask(CancelServerQuery());


WH>Сколько потоков этот код держит во время ожидания?


Ни одного, естественно.

WH>yield это магатонны сахара.


Yield это всего лишь одна конструкция, логически очень простая и прозрачная. Оценить простоту и прозрачность того синтаксического сахара, который ты предлагаешь я не могу, т.к. с первого взгляда не понятно ничего, а разъяснить ты отказался.

WH>А чтобы не ждать есть немерле.


Вы уже ждали 5 лет, хотя уже в 2005 можно было написать решение, делающее асинхронный код столь же простым сколь и обычный синхронный.

WH> То что ты не умеешь его готовить не значит что его готовить невозможно.


Я не понимаю английский на слух, поэтому смотреть видео мне смысла никакого. Если есть ссылка на код, то приведи, посмотрю.
Re[22]: Литература по метапрограммированию
От: WolfHound  
Дата: 12.06.11 14:32
Оценка:
Здравствуйте, Undying, Вы писали:

U>Данное решение логически не содержит практически ничего лишнего, так что максимум что можно это записать его лаконичнее, но не принципиально проще.

Можно принципиально проще.
    var txt = new TextBox(); 
    var lst = new ListBox { Top = txt.Height + 10 }; 
    var frm = new Form { 
        Controls = { txt, lst } 
    }; 
 
    // Turn the user input into a tamed sequence of strings. 
    var textChanged = from evt in Observable.FromEvent<EventArgs>(txt, "TextChanged") 
                      select ((TextBox)evt.Sender).Text; 
 
    var input = textChanged 
                .Throttle(TimeSpan.FromSeconds(1)) 
                .DistinctUntilChanged(); 
 
    // Bridge with the web service's MatchInDict method. 
    var svc = new DictServiceSoapClient("DictServiceSoap"); 
    var matchInDict = Observable.FromAsyncPattern<string, string, string, DictionaryWord[]> 
        (svc.BeginMatchInDict, svc.EndMatchInDict); 
 
    Func<string, IObservable<DictionaryWord[]>> matchInWordNetByPrefix = 
        term => matchInDict("wn", term, "prefix"); 
 
    // The grand composition connecting the user input with the web service. 
    var res = from term in input 
              from word in matchInWordNetByPrefix(term).TakeUntil(input) 
              select word; 
 
    // Synchronize with the UI thread and populate the ListBox or signal an error. 
    using (res.ObserveOn(lst).Subscribe( 
        words => { 
            lst.Items.Clear(); 
            lst.Items.AddRange((from word in words select word.Word).ToArray()); 
        }, 
        ex => { 
            MessageBox.Show("An error occurred: " + ex.Message, frm.Text, 
                            MessageBoxButtons.OK, MessageBoxIcon.Error); 
        })) 
    { 
        Application.Run(frm); 
    } // Proper disposal happens upon exiting the application.


U>filter.Filter();

И где там написано в течении какого времени дропать события?

U>По таймеру.

Жесть. И откуда таймер узнает о том с какой частотой нужно пробуждать задачу?
Да и зачем ее вообще пробуждать если пользователь ничего не делает?
Тебе что производительность девать некуда? А как на счет батарейки на мобиле?

U>Можно дополнить форсированными пробуждениями, но в данной задаче это бессмысленно.

А это уже пуш

U>Yield это всего лишь одна конструкция, логически очень простая и прозрачная.

Переписывание кода в конечный автомат это конечно очень просто.

U>Оценить простоту и прозрачность того синтаксического сахара, который ты предлагаешь я не могу, т.к. с первого взгляда не понятно ничего, а разъяснить ты отказался.

А в гугле тебя забанили?

U>Вы уже ждали 5 лет, хотя уже в 2005 можно было написать решение, делающее асинхронный код столь же простым сколь и обычный синхронный.

Ничего мы не ждали.

U>Я не понимаю английский на слух, поэтому смотреть видео мне смысла никакого. Если есть ссылка на код, то приведи, посмотрю.

http://go.microsoft.com/fwlink/?LinkId=208528
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: Литература по метапрограммированию
От: lseder lseder.livejournal.com
Дата: 18.06.11 07:52
Оценка:
Нашел, вроде по теме — http://www.languageworkbenches.net/submissions.html
Народ вовсю изгаляется...
Re[23]: Литература по метапрограммированию
От: Undying Россия  
Дата: 19.06.11 09:07
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


U>>Данное решение логически не содержит практически ничего лишнего, так что максимум что можно это записать его лаконичнее, но не принципиально проще.

WH>Можно принципиально проще.

Псевдосинхронная запись имеет практически такую же сложность как обычный синхронный код. Вся разница лишь в том, что вместо синхронного ожидания окончания запроса используется yield, что позволяет не занимать поток на время ожидания. Соответственно практически все приемы программирования, которые можно использовать в синхронном коде можно использовать и в асинхронном, а, следовательно, при использовании псевдосинхронной записи порог вхождения для решения асинхронных задач практически такой же как для решения обычных синхронных задач. Асинхронность задачи перестает быть дополнительной сложностью.

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


Кстати, никакой отмены устаревших запросов в решении на Rx нет. Вместо этого есть игнорирование результатов устаревшего запроса, что и делалось в приведенном мной примере.

Еще порадовал этот код:

    var textChanged = from evt in Observable.FromEvent<EventArgs>(txt, "TextChanged") 
                      select ((TextBox)evt.Sender).Text;


Рефлекшен, два явных приведения... Сразу видно технология двадцать первого века, с ностальгией вспомнился шарп 1.0.

U>>По таймеру.

WH>Жесть. И откуда таймер узнает о том с какой частотой нужно пробуждать задачу?
WH>Да и зачем ее вообще пробуждать если пользователь ничего не делает?
WH>Тебе что производительность девать некуда? А как на счет батарейки на мобиле?

Ежели мы пишем софт для мобилы и лишние вызовы являются реальной проблемой, то нужно добавить немножко форсов:


IEnumerable<Step> EventsAnalytic(TaskPull pull, Form form)
{
  // Получаем ссылку на таску и на поток, в котором она запущена
  StateStep stateStep = new StateStep();
  yield return stateStep;

  SlyFilter filter = new SlyFilter(events, TimeSpan.FromSeconds(1));

  Queue<Event> events = new Queue<Event>();
  form.txt.TextChanged += delegate
  {
    events.Enqueue(new Event());
    // Инициируем внеочередный вызов таски
    stateStep.Force();
  };
  
  while (true)
  {
    Event event = filter.Filter();
    if (event != null)
    {
      Task task = pull.StartTask(ThreadLabel.Server, ServerSend(stateStep, event));
      // Указываем допустимое время ожидания и задаем, что поток должен инициировать вызов таски по истечению времени таймаута
      yield return new WaitStep(timeout, timeout, delegate
        {
          return task.IsCompleted || events.Count != 0;
        });

      if (task.IsCompleted)
      {
        ServerResult result = task.Finish<ServerResult>();
        // Изменяем UI
        form.lst.Items.Clear();
        form.lst.Items.AddRange(result.Items);
      }
    }

    if (events.Count != 0)
      yield return new WaitStep(TimeSpan.FromSeconds(1));
    else
      yield return new WaitStep(TimeSpan.FromHours(1));
  }
}

void Main()
{
  // Запускаем анализатор событий в главном потоке
  pull.StartUITask(EventsAnalytic(pull, form);
}


Теперь никаких лишних вызовов шагов нет, решение можно смело использовать на мобильной платформе.

U>>Можно дополнить форсированными пробуждениями, но в данной задаче это бессмысленно.

WH>А это уже пуш

С чего это? Как без форсов задача записывалась как IEnumerable шагов, так и с форсами также записывается. Что там так принципиально поменялось-то, что pull превратился в push? Там вся разница, что без форсов обработка следующего шага иницируется только по таймеру, а с форсами как по таймеру, так и по событиям. Разница между pull и push явно не в этом.

U>>Yield это всего лишь одна конструкция, логически очень простая и прозрачная.

WH>Переписывание кода в конечный автомат это конечно очень просто.

Зачем для использования yield'а знать и уметь переписывать код в конечный автомат? Я вот понятия не имею как оно там в шарпе переписывается, что никак мне использовать yield не мешает. Единственное что нужно знать, что в месте вызова yield управление будет возвращено вызывающему методу.

U>>filter.Filter();

WH>И где там написано в течении какого времени дропать события?

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

U>>Оценить простоту и прозрачность того синтаксического сахара, который ты предлагаешь я не могу, т.к. с первого взгляда не понятно ничего, а разъяснить ты отказался.

WH>А в гугле тебя забанили?

В этом посте http://rsdn.ru/forum/philosophy/4304148.1.aspx
Автор: WolfHound
Дата: 09.06.11
ты привел мегасахар для записи асинхронных задач. В каком гугле надо искать что этот сахар означает?

U>>Вы уже ждали 5 лет, хотя уже в 2005 можно было написать решение, делающее асинхронный код столь же простым сколь и обычный синхронный.

WH>Ничего мы не ждали.

И как ты решал асинхронные задачи до выхода Rx?

U>>Я не понимаю английский на слух, поэтому смотреть видео мне смысла никакого. Если есть ссылка на код, то приведи, посмотрю.

WH>http://go.microsoft.com/fwlink/?LinkId=208528
Re[24]: Литература по метапрограммированию
От: WolfHound  
Дата: 19.06.11 10:48
Оценка:
Здравствуйте, Undying, Вы писали:

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

Логика просто звездец.
Эдак можно договориться до того что ничего учить не надо.

U>Кстати, никакой отмены устаревших запросов в решении на Rx нет. Вместо этого есть игнорирование результатов устаревшего запроса, что и делалось в приведенном мной примере.

То, что ты ее не видишь, не значит, что ее нет.
Отписка от события запускает отмену.

U>Рефлекшен, два явных приведения... Сразу видно технология двадцать первого века, с ностальгией вспомнился шарп 1.0.

Там можно и без рефлекшена. Просто писать больше.
А если не использовать C# можно и без рефлекшена и писать меньше.

U>Ежели мы пишем софт для мобилы и лишние вызовы являются реальной проблемой, то нужно добавить немножко форсов:

Это ты называешь простым кодом?
Код на Rx читается почти как спецификация.
А тут у тебя куча деталей реализации вылезла.

U>Теперь никаких лишних вызовов шагов нет, решение можно смело использовать на мобильной платформе.

Вот только его никто не поймет.
А если логика станет чуть сложнее, то его совсем никто не поймет.

WH>>А это уже пуш

U>С чего это?
По определению.

U>Как без форсов задача записывалась как IEnumerable шагов, так и с форсами также записывается. Что там так принципиально поменялось-то, что pull превратился в push? Там вся разница, что без форсов обработка следующего шага иницируется только по таймеру, а с форсами как по таймеру, так и по событиям. Разница между pull и push явно не в этом.

Именно в этом.
push это инициация обработки по событию.

U>Зачем для использования yield'а знать и уметь переписывать код в конечный автомат? Я вот понятия не имею как оно там в шарпе переписывается, что никак мне использовать yield не мешает. Единственное что нужно знать, что в месте вызова yield управление будет возвращено вызывающему методу.

Ну и в моём случае не нужно знать, во что это перепишется.

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

Очень даже интересен.
Ибо фильтрация событий по времени их прихода.

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

Те превратишь решение в push...

U>в отличии от Rx псевдосихронный способ записи ничего не навязывает.

Кроме горы никому не нужного мусора...

U>В этом посте http://rsdn.ru/forum/philosophy/4304148.1.aspx
Автор: WolfHound
Дата: 09.06.11
ты привел мегасахар для записи асинхронных задач. В каком гугле надо искать что этот сахар означает?

Там еще и название есть.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[24]: Литература по метапрограммированию
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.06.11 11:05
Оценка:
Здравствуйте, Undying, Вы писали:

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

Верно я понимаю что речь об асинхронной модели, описанной Рихтером или не Рихтером? Если да, то не совсем корректно ее сравнивать с Rx, ведь Rx это библиотека комбинирования push-based коллекций. А та модель — собственно async workflow. Если ее сравнивать с чем-то подобным, то можно с этим. Async workflow много где описан, просто в этой статье есть примеры на C#.
Да, с перечислителями будет поэлегантнее, хоть они и не для этого делались. Да и возможностей с ними побольше. Ветвление, циклы, try/catch (на F# возможно с async workflow, на C# — нет).

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

Rx не для workflow. Он позволяет лишь "когда придет ответ оттуда, засунь его туда". Но последовательно связывать асинхронные вычисления — нет. Или я слабо его себе представляю. Обсуждаемый пример Rx — делает одну подписку и красиво ей управляет. Как засунуть это в более сложный workflow — я слабо представляю.
Т.е. async workflow и async enumerator позволят ответ с сервера послать асинхронно другому серверу "в теле" того же метода (в ковычках потому как управление таки будет возвращаться между делом). А с Rx придется делать две разные подписки. (если это не так, надеюсь что поправят).

U>Кстати, никакой отмены устаревших запросов в решении на Rx нет. Вместо этого есть игнорирование результатов устаревшего запроса, что и делалось в приведенном мной примере.

Именно.

U>Еще порадовал этот код:

U>
U>    var textChanged = from evt in Observable.FromEvent<EventArgs>(txt, "TextChanged") 
U>                      select ((TextBox)evt.Sender).Text; 
U>


U>Рефлекшен, два явных приведения... Сразу видно технология двадцать первого века, с ностальгией вспомнился шарп 1.0.

Рефлекшн — только подписка и отписка. Да и то, не уверен. Там может стоять Emit. Не копался.
двух приведений нет. В первом случае просто явный параметр для метода FromEvent, да и нужен он лишь для событий с типизированными аргументами. Второй — приведение sender-а к TextBox-у. А можно было записать
select txt.Text;

как в случае с
txt.TextChanged += (s, a) => { DoSomethingWith(txt.Text); }

А кроме того, там еще и отписка реализована.

U>В этом посте http://rsdn.ru/forum/philosophy/4304148.1.aspx
Автор: WolfHound
Дата: 09.06.11
ты привел мегасахар для записи асинхронных задач. В каком гугле надо искать что этот сахар означает?

ссылку давал выше как пример async workflow
http://weblogs.asp.net/podwysocki/archive/2008/10/15/functional-c-implementing-async-computations-in-c.aspx
Мое имхо: async workflow удобно юзать в языках с поддержкой workflow. А так как C# его не поддерживает в достаточной мере(те select и let от LINQ-а выглядят довольно криво в случае с async, не позволяют ветвления, катчи и т.п.), то уж лучше юзать в C# асинхронные перечислители. Но все-таки призываю разделять случаи с workflow и случаи с управлением асинхронной подписки (Rx).
Re[25]: Литература по метапрограммированию
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 19.06.11 16:23
Оценка: 7 (1)
Здравствуйте, samius, Вы писали:

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


S>Да, с перечислителями будет поэлегантнее, хоть они и не для этого делались. Да и возможностей с ними побольше. Ветвление, циклы, try/catch (на F# возможно с async workflow, на C# — нет).

Это всего лишь комбинаторы. Все есть в Rx.

S>Rx не для workflow. Он позволяет лишь "когда придет ответ оттуда, засунь его туда". Но последовательно связывать асинхронные вычисления — нет. Или я слабо его себе представляю. Обсуждаемый пример Rx — делает одну подписку и красиво ей управляет. Как засунуть это в более сложный workflow — я слабо представляю.

S>Т.е. async workflow и async enumerator позволят ответ с сервера послать асинхронно другому серверу "в теле" того же метода (в ковычках потому как управление таки будет возвращаться между делом). А с Rx придется делать две разные подписки. (если это не так, надеюсь что поправят).
Не так. Последовательность вызовов делается оператором SelectMany, или через yield return + Observable.Interte в императивном стиле.

U>>Еще порадовал этот код:

U>>
U>>    var textChanged = from evt in Observable.FromEvent<EventArgs>(txt, "TextChanged") 
U>>                      select ((TextBox)evt.Sender).Text; 
U>>


U>>Рефлекшен, два явных приведения... Сразу видно технология двадцать первого века, с ностальгией вспомнился шарп 1.0.

S>Рефлекшн — только подписка и отписка. Да и то, не уверен. Там может стоять Emit. Не копался.
там reflection, но есть типизированная версия + геренратор extension-методов.
Re[26]: Литература по метапрограммированию
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.06.11 18:17
Оценка:
Здравствуйте, gandjustas, Вы писали:

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


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


S>>Да, с перечислителями будет поэлегантнее, хоть они и не для этого делались. Да и возможностей с ними побольше. Ветвление, циклы, try/catch (на F# возможно с async workflow, на C# — нет).

G>Это всего лишь комбинаторы. Все есть в Rx.
Да, нашел в Rx весь арсенал для workflow builder-а

S>>Rx не для workflow. Он позволяет лишь "когда придет ответ оттуда, засунь его туда". Но последовательно связывать асинхронные вычисления — нет. Или я слабо его себе представляю. Обсуждаемый пример Rx — делает одну подписку и красиво ей управляет. Как засунуть это в более сложный workflow — я слабо представляю.

Вижу, ошибался.
S>>Т.е. async workflow и async enumerator позволят ответ с сервера послать асинхронно другому серверу "в теле" того же метода (в ковычках потому как управление таки будет возвращаться между делом). А с Rx придется делать две разные подписки. (если это не так, надеюсь что поправят).
G>Не так. Последовательность вызовов делается оператором SelectMany, или через yield return + Observable.Interte в императивном стиле.
Observable.Iterate?
Re[27]: Литература по метапрограммированию
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 20.06.11 08:50
Оценка: 7 (1)
Здравствуйте, samius, Вы писали:

S>>>Т.е. async workflow и async enumerator позволят ответ с сервера послать асинхронно другому серверу "в теле" того же метода (в ковычках потому как управление таки будет возвращаться между делом). А с Rx придется делать две разные подписки. (если это не так, надеюсь что поправят).

G>>Не так. Последовательность вызовов делается оператором SelectMany, или через yield return + Observable.Interte в императивном стиле.
S>Observable.Iterate?
Угу. Тут пример — http://blogs.msdn.com/b/jeffva/archive/2010/07/23/rx-on-the-server-part-1-of-n-asynchronous-system-io-stream-reading.aspx
Re[25]: Литература по метапрограммированию
От: Undying Россия  
Дата: 21.06.11 04:39
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Эдак можно договориться до того что ничего учить не надо.


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

WH>То, что ты ее не видишь, не значит, что ее нет.

WH>Отписка от события запускает отмену.

Код с неявными побочными эффектами? Тот кто будет это поддерживать будет вам очень благодарен.

WH>Код на Rx читается почти как спецификация.

WH>А тут у тебя куча деталей реализации вылезла.

Что конкретно вылезло? Единственный некрасивый момент в решении это способ передачи ссылок на таску и поток выполнения внутрь описания шагов из-за стандартной проблемы яйца и курицы.

WH>А если логика станет чуть сложнее, то его совсем никто не поймет.


Ты не способен понимать синхронный код? Асинхронное решение с использованием псевдосинхронном записи практически ничем от синхронного не отличается. Соответственно псевдосинхронную запись без каких-либо проблем понимают даже студенты.

WH>push это инициация обработки по событию.


Тогда и обычный IEnumerable это пуш. Т.к. все функции программы в конечном итоге вызываются по событию.

WH>Очень даже интересен.

WH>Ибо фильтрация событий по времени их прихода.

И что там интересного? Если прошла секунда со времени прихода последнего события, то фильтр возвращает это событие и очищает очередь событий. Если нет, то возвращает null. Хотя собственно даже очередь здесь не нужна, можно хранить только последнее событие.
Re[28]: Литература по метапрограммированию
От: samius Япония http://sams-tricks.blogspot.com
Дата: 21.06.11 04:59
Оценка:
Здравствуйте, gandjustas, Вы писали:

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


S>>>>Т.е. async workflow и async enumerator позволят ответ с сервера послать асинхронно другому серверу "в теле" того же метода (в ковычках потому как управление таки будет возвращаться между делом). А с Rx придется делать две разные подписки. (если это не так, надеюсь что поправят).

G>>>Не так. Последовательность вызовов делается оператором SelectMany, или через yield return + Observable.Interte в императивном стиле.
S>>Observable.Iterate?
G>Угу. Тут пример — http://blogs.msdn.com/b/jeffva/archive/2010/07/23/rx-on-the-server-part-1-of-n-asynchronous-system-io-stream-reading.aspx
Все понятно стало. Т.е. фактически для сцепления с императивом заюзан тот же трюк с асинхронным перечислителем.
Благодарю, был неправ в своих догадках.
Re[26]: Литература по метапрограммированию
От: WolfHound  
Дата: 21.06.11 07:15
Оценка:
Здравствуйте, Undying, Вы писали:

U>Разумеется. Использовать более сложное решение имеет смысл только в том случае, если оно кардинально расширяет наши возможности по решению наших задач по сравнению с более простым и прозрачным решением. Впрочем правильно приготовленные простые решения очень часто обладают и куда большей мощностью, чем решения сложные, т.к. в простых решениях нужные сущности не прикрыты слоями абстракций.

Твое решение сложнее.
Намного сложнее.
Ты просто посмотри на ту гору грязи, не имеющую отношения к делу, которую ты написал.

U>Код с неявными побочными эффектами? Тот кто будет это поддерживать будет вам очень благодарен.

Это стандартное поведение.
Так что запомнить это нужно раз и навсегда.

U>Что конкретно вылезло? Единственный некрасивый момент в решении это способ передачи ссылок на таску и поток выполнения внутрь описания шагов из-за стандартной проблемы яйца и курицы.

Да у тебя там чуть менее чем весь код детали реализации.

U>Ты не способен понимать синхронный код? Асинхронное решение с использованием псевдосинхронном записи практически ничем от синхронного не отличается. Соответственно псевдосинхронную запись без каких-либо проблем понимают даже студенты.

Там столько деревьев, что за ними не видно леса.

U>Тогда и обычный IEnumerable это пуш. Т.к. все функции программы в конечном итоге вызываются по событию.

Ты не понимаешь чем push отличается от pull.
В случае с IEnumerable ты вытягиваешь данные. Это pull.
А в случае с пробуждением кода внешний код проталкивает данные тебе. Это push.

U>И что там интересного? Если прошла секунда со времени прихода последнего события, то фильтр возвращает это событие и очищает очередь событий. Если нет, то возвращает null. Хотя собственно даже очередь здесь не нужна, можно хранить только последнее событие.

Интересно записать это одной строчкой:
    var input = textChanged 
                .Throttle(TimeSpan.FromSeconds(1)) 
                .DistinctUntilChanged();
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[27]: Литература по метапрограммированию
От: Undying Россия  
Дата: 21.06.11 16:47
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>В случае с IEnumerable ты вытягиваешь данные. Это pull.

WH>А в случае с пробуждением кода внешний код проталкивает данные тебе. Это push.

В случае псевдосинхронной записи данные всегда вытягивает TaskPull. Force никаких данных к себе не проталкивает, оно лишь говорит TaskPull'у, что ему надо вытянуть к себе данные прямо сейчас.

U>>И что там интересного? Если прошла секунда со времени прихода последнего события, то фильтр возвращает это событие и очищает очередь событий. Если нет, то возвращает null. Хотя собственно даже очередь здесь не нужна, можно хранить только последнее событие.

WH>Интересно записать это одной строчкой:
WH>
WH>    var input = textChanged 
WH>                .Throttle(TimeSpan.FromSeconds(1)) 
WH>                .DistinctUntilChanged(); 
WH>


Зачем это записывать одной строчкой? У тебя число буковок в коде самоцель?

WH>Ты просто посмотри на ту гору грязи, не имеющую отношения к делу, которую ты написал.


Это у тебя претензии не к способу решения асинхронных задач, а к императивному стилю вообще. Ты считаешь, что функциональный стиль лучше императивного, я считаю наоборот. Спорить на эту тему бессмысленно, т.к. по видимому у нас действительно совершенно разные типы мышления.
Re[28]: Литература по метапрограммированию
От: WolfHound  
Дата: 21.06.11 17:07
Оценка:
Здравствуйте, Undying, Вы писали:

U>В случае псевдосинхронной записи данные всегда вытягивает TaskPull. Force никаких данных к себе не проталкивает, оно лишь говорит TaskPull'у, что ему надо вытянуть к себе данные прямо сейчас.

Само сообщение уже информация.
Ты как ни крутись, а это pull.
Просто по определению.

U>Зачем это записывать одной строчкой? У тебя число буковок в коде самоцель?

У меня цель чтобы в коде небыло ни одной буквы которая не относится к решению задачи.
Rx очень близок к идеалу.
Хотя можно и лучше.
Но не на C#.

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

У меня претензии к коду, который занимается деталями реализации.
Его быть не должно.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[27]: Литература по метапрограммированию
От: Undying Россия  
Дата: 21.06.11 17:19
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Это стандартное поведение.

WH>Так что запомнить это нужно раз и навсегда.

Т.е. для чтения кода, использующего подобные библиотеки, нужно держать в памяти кучу мусорных знаний. Я как-то предпочитаю писать библиотеки, которые этого не требуют.
Re[29]: Литература по метапрограммированию
От: Undying Россия  
Дата: 21.06.11 17:32
Оценка:
Здравствуйте, WolfHound, Вы писали:

U>>Зачем это записывать одной строчкой? У тебя число буковок в коде самоцель?

WH>У меня цель чтобы в коде небыло ни одной буквы которая не относится к решению задачи.

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

Например, если в зависимости от свойств события интервал Throttle нужно будет делать разный, то как измениться код на Rx? А если интервал будет зависеть от предшествующих событий?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.