We employ the combination of multiple messages in a receive pattern and non-linear patterns to test for a matching seller and a buyer. Non-linear patterns are in fact a short-hand for guards. That is, the above is equivalent to
receive
Seller x, Buyer y when x == y -> "match found"
Получается своего рода ассоциативная память, позволяющая делать весьма разветвлённые dataflow сети.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Сама по себе идея акторов весьма кривая ибо нарушает SRP.
Тк актор совмещает в себе поток исполнения и почтовый ящик.
А нарушение SRP до добра никогда не доводило.
Но если отделить мух от котлет то данный способ доставания сообщений из почтового ящика может быть полезен.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Это же можно сделать и с доставанием сообщений последовательно, но с одновременным получится лучше.
В общем и целом, есть способ формального преобразования программ в вот такие вот multiheaded сравнения с посылками. Он позволяет сделать из программы полностью параллельную, так, что даже придётся сдерживать параллелизм.
Идея давнишняя, времён Id90. Просто про неё мало, кто знает.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Here's a simple example of a market-place actor
T>
T>receive
T> Seller x, Buyer x -> "match found"
T>
T>We employ the combination of multiple messages in a receive pattern and non-linear patterns to test for a matching seller and a buyer. Non-linear patterns are in fact a short-hand for guards. That is, the above is equivalent to
T>
T>receive
T> Seller x, Buyer y when x == y -> "match found"
T>
T>Получается своего рода ассоциативная память, позволяющая делать весьма разветвлённые dataflow сети.
Штука интересная и наверное может упростить код в некоторых случаях, но:
1. Даже с простым ящиком и без pattern-matching есть масса тонких моментов, без учета которых можно нарваться на проблемы.
2. В случае с паттерн-матчингом проблем становится больше: не всегда ясно, покрывает ли такой матчинг все случаи, сложность матчинга может из константной легко стать линейной или даже хуже.
3. Неочевидно, в каких реальных случаях это действительно можно выгодно использовать(приведенный выше пример, несмотря на свою красоту, слишком далек от суровой реальности, где простым сравнением не обойтись )
Кстати, предположим что есть два процесаа. Один из них генерит данные а другой — обрабатывет. И надо просто передать их из одного процесса в другой. Можно было бы использовать Chan. Но есть тонкость: если первый процесс работает быстрее второго, то Chan раздуется и порвет на куски heap. В не-Haskell мире это решается использованием очереди с фиксированной длинной, так что быстрый генератор данных будет приторможен пока очередь не разгрузится. Chan же, к сожалению, такое не поддерживает. Есть ли идиоматический подход в Haskell для борьбы с раздувающимися очередями? Пока вижу только один вариант — сделать свою bounded queue, возможно на основе Chan.
T>>Получается своего рода ассоциативная память, позволяющая делать весьма разветвлённые dataflow сети. RD>Штука интересная и наверное может упростить код в некоторых случаях, но: RD>1. Даже с простым ящиком и без pattern-matching есть масса тонких моментов, без учета которых можно нарваться на проблемы. RD>2. В случае с паттерн-матчингом проблем становится больше: не всегда ясно, покрывает ли такой матчинг все случаи, сложность матчинга может из константной легко стать линейной или даже хуже. RD>3. Неочевидно, в каких реальных случаях это действительно можно выгодно использовать(приведенный выше пример, несмотря на свою красоту, слишком далек от суровой реальности, где простым сравнением не обойтись )
Выше я привёл ссылку на мой пост в ЖЖ насчёт применения этой штуки.
Моя точка зрения такова — желательно создавать такой код автоматически из последовательного кода. Мы получим только то, что нужно для выполнения программы, не более и не менее, все создания событий будут покрыты их получением. При этом мы можем сэкономить на некоторых пересылках.
Если пишем вручную, то можно статически проверять код верификацией моделей. Это сложнее, но всё ещё возможно.
RD>Кстати, предположим что есть два процесаа. Один из них генерит данные а другой — обрабатывет. И надо просто передать их из одного процесса в другой. Можно было бы использовать Chan. Но есть тонкость: если первый процесс работает быстрее второго, то Chan раздуется и порвет на куски heap. В не-Haskell мире это решается использованием очереди с фиксированной длинной, так что быстрый генератор данных будет приторможен пока очередь не разгрузится. Chan же, к сожалению, такое не поддерживает. Есть ли идиоматический подход в Haskell для борьбы с раздувающимися очередями? Пока вижу только один вариант — сделать свою bounded queue, возможно на основе Chan.
RD>>Кстати, предположим что есть два процесаа. Один из них генерит данные а другой — обрабатывет. И надо просто передать их из одного процесса в другой. Можно было бы использовать Chan. Но есть тонкость: если первый процесс работает быстрее второго, то Chan раздуется и порвет на куски heap. В не-Haskell мире это решается использованием очереди с фиксированной длинной, так что быстрый генератор данных будет приторможен пока очередь не разгрузится. Chan же, к сожалению, такое не поддерживает. Есть ли идиоматический подход в Haskell для борьбы с раздувающимися очередями? Пока вижу только один вариант — сделать свою bounded queue, возможно на основе Chan.
T>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/BoundedChan
T>Я открыл для себя hackage. Hackage оказался отличной штукой!
Спасибо. Похоже этот BoundedChan появился практически сразу же после того, как я его там искал (в апреле). А еще говорят, что мысли не могут материализоваться...