M>>Практически все описаные антипаттерны возникают из отсутсвия в языке и среде нативной поддержки собственно модели акторов.
BZ>из твоих слов получается что акторы являются антипаттерном в любом языке кроме эрланга
Из моих слов получается:
Практически все описаные антипаттерны возникают из отсутсвия в языке и среде нативной поддержки собственно модели акторов. Отсюда все эти стенания о спинлоках, задержке сообщений и прочем и прочем. Это не говоря уже об отсутствии необходимой инфраструктуры, следящей за завершением исполнения процессов, изоляции процессов и многого другого. Откуда проистекают стенания о невозможности следить за акторами с «богатым состоянием» и т.п.
Здравствуйте, LaPerouse, Вы писали:
LP>Как без корутин сделать такой код
вообще есть три варианта реализации асинхронности:
1. stackless coroutines — синтаксический сахар в языке, который разворачивается в конечный автомат при компиляции
2. stackful coroutines — каким-то способом выделяется множество стеков (alloca, fibers и т.д.) и переключение между ними осуществляется вручную. этот способ часто может быть реализован на чисто библиотечном уровне, док-во этого — соответствующие библиотеки Boost
3. green threads — это stackful coroutines с регулярным автоматическим переключением между ними, реализованным в VM. ruby/erlang делают это через определённое кол-во шагов интерпретации, ghc — при выделении очередного блока памяти (а память в single-assignment языках выделяется постоянно)
LP>Это-то понятно. Но пример в исходном сообщении как раз показывает, что обработка ответа на асинхронный вызов может быть сложной, так как в нетривиальном случае обработка зависит от состояния.
Обработка любого ответа в любом случае может быть нетривиальной
LP>
LP>resp = await cast(actor, msg);//происходит возврат управления из функции, актор готов принимать сообщения
LP>//Отсюда выполнение продолжится, когда придет ответ на запрос
LP>process(resp);
LP>
Да, promises и прочая немного помогают. На практике для них все равно чаще всего нет внятной инфраструктуры по управлению ими (возможно, еще появится с ростом популярности)
Здравствуйте, LaPerouse, Вы писали:
LP>"Но с эрлангом или без, от конечного автомата все равно не убежите. Другое дело, он может быть замаскирован безстековыми корутинами или продожениями." ?
нет в эрланге ни того, ни жругого, ни третьего. там зелёные потоки
LP>Ну стековые корутины это вообще экзотика. При слове корутины все представляют себе yeild return иил async/await.
вот с этого следовало начинать
идея сопрограмм появилась в 60-х годах, в частности в Симуле-67, и до недавнего времени была представлена исключительно стёковыми сопрограммами. их несложно реализовать на уровне ассемблера, и даже в C есть набор функций, достаточный для их реализации — alloca/setjmp/longjmp
а генерация конечных автомтов — это как рах экзотика, реализованная только в C#. я лично о ней впервые услышал несколько месяцев назад, когда стал изучать пропозалы C++
Здравствуйте, BulatZiganshin, Вы писали:
BZ>Здравствуйте, LaPerouse, Вы писали:
LP>>Как без корутин сделать такой код
BZ>3. green threads — это stackful coroutines
То есть coroutines. Чтд.
BZ>с регулярным автоматическим переключением между ними, реализованным в VM. ruby/erlang делают это через определённое кол-во шагов интерпретации, ghc — при выделении очередного блока памяти (а память в single-assignment языках выделяется постоянно)
Тут нужно переключать не абы когда (как в случае c green threads в общем случае), а именно после отправки асинхронного сообщения, и возвращать управление после получения ответа на запрос.
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[10]: Об очередном антипаттерне. Модель акторов.
Здравствуйте, BulatZiganshin, Вы писали:
BZ>а генерация конечных автомтов — это как рах экзотика, реализованная только в C#. я лично о ней впервые услышал несколько месяцев назад, когда стал изучать пропозалы C++
Просто открываем любой C# проект — код будет усыпан yield return и async-ами. В С++ проектах редко можно встретить применение сопрограмм. Так что есть экзотика?
Социализм — это власть трудящихся и централизованная плановая экономика.
LP>>Это-то понятно. Но пример в исходном сообщении как раз показывает, что обработка ответа на асинхронный вызов может быть сложной, так как в нетривиальном случае обработка зависит от состояния.
M>Обработка любого ответа в любом случае может быть нетривиальной
Ну в примере из исходного сообщения как раз показан простой и сложный способ обработки ответа.
Социализм — это власть трудящихся и централизованная плановая экономика.
LP>>Ну в примере из исходного сообщения как раз показан простой и сложный способ обработки ответа.
M>Я, если честно, не вижу там простого-сложного, и в чем вообще проблема
Здравствуйте, LaPerouse, Вы писали:
_>>Почему? ) LP>Потому что это callback. Я думал, это очевидно.
Что ещё за callback через очередь сообщений? ) Ну да ладно, пускай будет для простоты обсуждения. )))
LP>Callback отличается от актора тем, что он снабжен контекстом вызова. Response приходит в определенном контексте — в котором был послан request. LP>В случае актора reponse может прийти в ЛЮБОМ контексте. Он может прийти даже сам по себе, без всякого request, если другой актор послал это сообщение по какому-то событию,
А можно увидеть определение актора, которое обязывает нас принимать произвольное число непонятных сообщений? ) С чего вообще актор обязан принимать какие-то сообщения? Если скажем ему для работы не нужны никакие дополнительных данные...
LP>хотя в данном случае Response не совсем правильное название для такого сообщения. LP>Поэтому нужен конечный автомат, чтобы разобрать состояния.
Конечный автомат нужен, если плодить сложные акторы, выполняющих множество разных ролей. Если же делать по актору на каждую роль, то никакие конечные автоматы не нужны.
LP>Callback: LP>... LP>Actor: LP>...
Вот прямо в данном примере видно, что зачем-то объединили в один актор три независимых дела. Если их разделить на три отдельных актора, то никаких проблем уже не возникает.
LP>Актор можно переписать, сделав в какой-то степени похожим на колбак, то есть снадбив контекстом вызова, при помощи сопрограммы: LP>..
Если у нас это отдельные акторы, то просто пишем аналогичный линейный код без всяких сопрограмм и всё.
LP>Если в языке нету поддержки сопрограмм, то приходится реализовывать актор при помощи явных конечных автоматов. Если бы ты внимательно прочитал вторую часть моего соообщения, этого обсуждения не было бы.
Сопрограммы используются для линеаризации асинхронного кода. Не важно какого происхождение. На базе системных потооков или лёгких потоков или вообще из асинхронного IO. По твому получается, что любой нелинеризованный асинхронный код обязательно содержит конечный автомат. Это весьма забавное утверждение. )))
_>>Хм, а разве есть какое-то принципиальное отличие этого моего примера и данного кода _>>из пункта номер 1 изначального сообщения темки? ) Заменяем CalculateSomething на DownloadData, a someHardCalculation на "обработка следующих сообщений в очереди (GUI приложения)"... LP>Если бы ты взял не первый пример (который как раз демонстрировал НЕПРАВИЛЬНОЕ использование актора), а последний, ты бы не написал это сообщение.
Так а почему оно не правильное, если ты сам согласился, что получился удобный код? )
Re[11]: Об очередном антипаттерне. Модель акторов.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, LaPerouse, Вы писали:
_>>>Почему? ) LP>>Потому что это callback. Я думал, это очевидно.
_>Что ещё за callback через очередь сообщений? ) Ну да ладно, пускай будет для простоты обсуждения. )))
Очередь — это особенность реализации. К самой концепции callback-ов не имеющая отношения.
In computer programming, a callback is a piece of executable code that is passed as an argument to other code, which is expected to call back (execute) the argument at some convenient time.
LP>>Callback отличается от актора тем, что он снабжен контекстом вызова. Response приходит в определенном контексте — в котором был послан request. LP>>В случае актора reponse может прийти в ЛЮБОМ контексте. Он может прийти даже сам по себе, без всякого request, если другой актор послал это сообщение по какому-то событию,
_>А можно увидеть определение актора, которое обязывает нас принимать произвольное число непонятных сообщений? ) С чего вообще актор обязан принимать какие-то сообщения? Если скажем ему для работы не нужны никакие дополнительных данные...
Ну да, в hellow world они действительно красивые и причесанные. Только вот в реальной практике почему-то 90 процентов акторов выглядят именно так, как я показал.
Вообще, когда актору требуется получить что-то от другого актора для обработки сообщения — тривиальнейшая ситуация. Это известно любому, кто хоть немного сталкивался с акторами.
LP>>хотя в данном случае Response не совсем правильное название для такого сообщения. LP>>Поэтому нужен конечный автомат, чтобы разобрать состояния.
_>Конечный автомат нужен, если плодить сложные акторы, выполняющих множество разных ролей. Если же делать по актору на каждую роль, то никакие конечные автоматы не нужны.
Настолько не нужны, что даже разработчики akka рекомендуют делать акторы через автоматы, поддержка которых сделана прямо в akka ))
LP>>Callback: LP>>... LP>>Actor: LP>>...
_>Вот прямо в данном примере видно, что зачем-то объединили в один актор три независимых дела. Если их разделить на три отдельных актора, то никаких проблем уже не возникает.
Где объединил-то? Используются как раз три разных актора. ))
_>Сопрограммы используются для линеаризации асинхронного кода. Не важно какого происхождение. На базе системных потооков или лёгких потоков или вообще из асинхронного IO. По твому получается, что любой нелинеризованный асинхронный код обязательно содержит конечный автомат. Это весьма забавное утверждение. )))
Ну, это ты хорошо за меня придумал. Это где из моих слов выходит такое?
_>>>Хм, а разве есть какое-то принципиальное отличие этого моего примера и данного кода _>>>из пункта номер 1 изначального сообщения темки? ) Заменяем CalculateSomething на DownloadData, a someHardCalculation на "обработка следующих сообщений в очереди (GUI приложения)"... LP>>Если бы ты взял не первый пример (который как раз демонстрировал НЕПРАВИЛЬНОЕ использование актора), а последний, ты бы не написал это сообщение. _>Так а почему оно не правильное, если ты сам согласился, что получился удобный код? )
Код получился удобным не в акторе. Эдак можно каждый асинхронный обработчик называть актором.
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[12]: Об очередном антипаттерне. Модель акторов.
Здравствуйте, Mamut, Вы писали:
M>>>Я, если честно, не вижу там простого-сложного, и в чем вообще проблема
LP>>То есть для тебя нет разницы между этим:
M>Только в том, что код ужасен. Но это проистекает из убогости языка/библиотек. Это во-первых.
Так ты не показал, как удобно.
M>Во-вторых, первый код не эквивалентен второму.
Ну да, об этом написано в исходном сообщении. Но забавно, что в большинстве случаев они таки выходят эквивалентными )
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[13]: Об очередном антипаттерне. Модель акторов.
M>>Только в том, что код ужасен. Но это проистекает из убогости языка/библиотек. Это во-первых. LP>Так ты не показал, как удобно.
Я показал пример с gen_server и с использованием только примитива receive.
M>>Во-вторых, первый код не эквивалентен второму. LP>Ну да, об этом написано в исходном сообщении. Но забавно, что в большинстве случаев они таки выходят эквивалентными )
Здравствуйте, LaPerouse, Вы писали:
LP>>>Как без корутин сделать такой код BZ>>3. green threads — это stackful coroutines LP>То есть coroutines. Чтд.
и? мне кажется, ты на каких-то базвордах зациклился, тогда как мир не ограничивается C#
BZ>>с регулярным автоматическим переключением между ними, реализованным в VM. ruby/erlang делают это через определённое кол-во шагов интерпретации, ghc — при выделении очередного блока памяти (а память в single-assignment языках выделяется постоянно)
LP>Тут нужно переключать не абы когда (как в случае c green threads в общем случае), а именно после отправки асинхронного сообщения, и возвращать управление после получения ответа на запрос.
насколоько я понимаю, переключать нужно при ожидании ответа — если он ещё не готов. опять же советую тебе глядеть на green thread как разновдиность потоков вообще, просто более эффективно реализуемую. а ты похоже всё пытаешься к своему миру C# свести, отсюда трудности
Люди, я люблю вас! Будьте бдительны!!!
Re[11]: Об очередном антипаттерне. Модель акторов.
Здравствуйте, LaPerouse, Вы писали:
LP>Просто открываем любой C# проект — код будет усыпан yield return и async-ами. В С++ проектах редко можно встретить применение сопрограмм. Так что есть экзотика?
для человека, следующего ра развитием ЯП и знающего десятки языков начиная с фортрана и лиспа — stackless экзотика. для человека, знакомого только с C# — наоборот
Люди, я люблю вас! Будьте бдительны!!!
Re[13]: Об очередном антипаттерне. Модель акторов.
Здравствуйте, LaPerouse, Вы писали:
LP>Если в языке нету поддержки сопрограмм, то приходится реализовывать актор при помощи явных конечных автоматов. Если бы ты внимательно прочитал вторую часть моего соообщения, этого обсуждения не было бы.
как я уже говорил, есть во первых вариант с потоками/файберами и т.п. во вторых, для любого компилируемого языка (без VM) можно сделать крошечную ассемблерную библиотечку, которая создаёт и переключает стёки. а для языка с VM такое моджно сделать на уровне VM, а наружу выставить в виде API
так что множество языков — от С до эрланга эту проблему решают без языковой поддержки. твоя проблема в том что ты не знаешь ничего кроме своего C# и начинаешь рассуждать о других языках, думая что они должны быть устроены точно так же. а когда оказывается чсто это не так, сюбда добавляются рассуждения о том что все олстальные языки — экзотика и правильные сопрограммы у нас появились всего 5 лет назщад
Люди, я люблю вас! Будьте бдительны!!!
Re[10]: Об очередном антипаттерне. Модель акторов.
Здравствуйте, BulatZiganshin, Вы писали:
BZ>Здравствуйте, LaPerouse, Вы писали:
LP>>>>Как без корутин сделать такой код BZ>>>3. green threads — это stackful coroutines LP>>То есть coroutines. Чтд. BZ>и? мне кажется, ты на каких-то базвордах зациклился, тогда как мир не ограничивается C#
Да нет, это ты приплел совершенно не в тему зеленые потоки и сейчас юлишь, пытаясь свести весь эрланг к ним.
BZ>>>с регулярным автоматическим переключением между ними, реализованным в VM. ruby/erlang делают это через определённое кол-во шагов интерпретации, ghc — при выделении очередного блока памяти (а память в single-assignment языках выделяется постоянно) LP>>Тут нужно переключать не абы когда (как в случае c green threads в общем случае), а именно после отправки асинхронного сообщения, и возвращать управление после получения ответа на запрос. BZ>насколоько я понимаю, переключать нужно при ожидании ответа — если он ещё не готов. опять же советую тебе глядеть на green thread как разновдиность потоков вообще, просто более эффективно реализуемую.
Чем это отличается это от того, что я написал? И с чего ты взял, что в эрланге все происходит именно так? Вон Мамут, который в отличие от тебя писал на эрланге, ничего подобного не приводит.
BZ>а ты похоже всё пытаешься к своему миру C# свести, отсюда трудности
К моему? Ну-ну. Я никогда не писал и ни планирую писать на С# и ссылаюсь на него лишь потому, что именно этот язык ввел понятия сопрограмм в мейнстрим и для многим именно мс-ская реализация является референсной.
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[12]: Об очередном антипаттерне. Модель акторов.
Здравствуйте, BulatZiganshin, Вы писали:
BZ>Здравствуйте, LaPerouse, Вы писали:
LP>>Просто открываем любой C# проект — код будет усыпан yield return и async-ами. В С++ проектах редко можно встретить применение сопрограмм. Так что есть экзотика?
BZ>для человека, следующего ра развитием ЯП и знающего десятки языков начиная с фортрана и лиспа — stackless экзотика. для человека, знакомого только с C# — наоборот
Череп не жмет?
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[13]: Об очередном антипаттерне. Модель акторов.
Здравствуйте, LaPerouse, Вы писали:
BZ>>для человека, следующего ра развитием ЯП и знающего десятки языков начиная с фортрана и лиспа LP>Череп не жмет?
мы точно на rsdn? в разделе философия программирования?