From 9671484b6cb3f3c56d6a3053a4a55b4634c14a89 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Mon, 22 Aug 2022 20:45:33 -0400 Subject: Added support for the agent model. --- .../the_lux_programming_language/appendix_a.md | 2 +- .../the_lux_programming_language/appendix_c.md | 2 +- documentation/bookmark/business/productivity.md | 1 + documentation/bookmark/compilation/target/wasm.md | 58 -------------- .../compilation/target/wasm__WebAssembly.md | 59 ++++++++++++++ documentation/bookmark/css.md | 1 + documentation/bookmark/end_user_programming.md | 5 ++ documentation/bookmark/open_source.md | 1 + documentation/bookmark/parallelism.md | 1 + documentation/bookmark/propagator.md | 6 ++ documentation/bookmark/transducer_stream_pipe.md | 2 + documentation/bookmark/web_browser.md | 93 ++++++++++++---------- .../library/lux/control/concurrency/actor.lux | 54 +++++++++++-- .../library/lux/control/concurrency/agent.lux | 25 ++++++ stdlib/source/test/lux/control.lux | 2 + .../source/test/lux/control/concurrency/actor.lux | 60 ++++++++++++++ .../source/test/lux/control/concurrency/agent.lux | 49 ++++++++++++ 17 files changed, 310 insertions(+), 111 deletions(-) delete mode 100644 documentation/bookmark/compilation/target/wasm.md create mode 100644 documentation/bookmark/compilation/target/wasm__WebAssembly.md create mode 100644 documentation/bookmark/end_user_programming.md create mode 100644 documentation/bookmark/propagator.md create mode 100644 stdlib/source/library/lux/control/concurrency/agent.lux create mode 100644 stdlib/source/test/lux/control/concurrency/agent.lux diff --git a/documentation/book/the_lux_programming_language/appendix_a.md b/documentation/book/the_lux_programming_language/appendix_a.md index d0b4fe8b1..4b77e10df 100644 --- a/documentation/book/the_lux_programming_language/appendix_a.md +++ b/documentation/book/the_lux_programming_language/appendix_a.md @@ -16,7 +16,7 @@ If you recall [Chapter 1](chapter_1.md), there was this example code: Here, we're importing the `library/lux` module. -The `(.except)` option means _locally import every definition exported by the `library/lux` module_. +The `(.except)` option means _locally_ import every definition exported by the `library/lux` module. This allows usage of those definitions without having to give them the `library/lux.` prefix, or even the `.` shortcut prefix. diff --git a/documentation/book/the_lux_programming_language/appendix_c.md b/documentation/book/the_lux_programming_language/appendix_c.md index 5bfb731ea..0ca109331 100644 --- a/documentation/book/the_lux_programming_language/appendix_c.md +++ b/documentation/book/the_lux_programming_language/appendix_c.md @@ -66,7 +66,7 @@ The possibilities are endless when it comes to the refinement you can do, and wh ... Allows you to simultaneously bind and de-structure a value. (def (hash (^.let set [element_hash _])) (list#mix (function (_ elem acc) - (n.+ (# element_hash hash elem) acc)) + (n.+ (at element_hash hash elem) acc)) 0 (set.list set))) ``` diff --git a/documentation/bookmark/business/productivity.md b/documentation/bookmark/business/productivity.md index 98d8ac064..76c8acb01 100644 --- a/documentation/bookmark/business/productivity.md +++ b/documentation/bookmark/business/productivity.md @@ -1,6 +1,7 @@ # Reference 0. []() +0. [Let it slide](https://world.hey.com/dhh/let-it-slide-9e40f11a) 0. [Tips for effective engineering](https://budelewski.com/effective-engineering/) 0. [1. Unfolding the interrelationship diagram](https://world.hey.com/rjs/1-unfolding-the-interrelationship-diagram-5a79e3fc) 0. [2. Shaping on the demand side](https://world.hey.com/rjs/2-shaping-on-the-demand-side-f2e6a00d) diff --git a/documentation/bookmark/compilation/target/wasm.md b/documentation/bookmark/compilation/target/wasm.md deleted file mode 100644 index e90bcd654..000000000 --- a/documentation/bookmark/compilation/target/wasm.md +++ /dev/null @@ -1,58 +0,0 @@ -# Interoperability - -0. []() -0. [How to Extend WebAssembly with Host Functions](https://www.secondstate.io/articles/extend-webassembly/) -0. [js-wasm: JavaScript and WebAssembly should be a joy to use together.](https://wasm.js.org/) - -# Concurrency - -0. []() -0. [Wasm threads are now available in all browsers](https://old.reddit.com/r/WebAssembly/comments/rk83mr/wasm_threads_are_now_available_in_all_browsers/) - -# Platform - -0. []() -0. [Wasmer Java](https://github.com/wasmerio/wasmer-java) -0. [WAVM: WAVM is a WebAssembly virtual machine, designed for use in non-web applications.](https://wavm.github.io/) - -# Exemplar - -0. []() -0. [Announcing GraalWasm — a WebAssembly engine in GraalVM](https://medium.com/graalvm/announcing-graalwasm-a-webassembly-engine-in-graalvm-25cd0400a7f2) -0. [Towards a WebAssembly standalone runtime on GraalVM](https://dl.acm.org/citation.cfm?id=3362780) -0. https://github.com/vvanders/wasm_lua -0. https://github.com/AppCypher/webassemblylanguages -0. https://medium.com/perlin-network/life-a-secure-blazing-fast-cross-platform-webassembly-vm-in-go-ea3b31fa6e09 - -# Reference - -0. []() -0. [TeaVM: Build Fast, Modern Web Apps in Java](https://teavm.org/) -0. [Recommendations when publishing a Wasm library](https://nickb.dev/blog/recommendations-when-publishing-a-wasm-library) -0. [Building host implementations for WebAssembly interfaces](https://radu-matei.com/blog/wasm-components-host-implementations/) -0. [WebAssembly Techniques to Speed Up Matrix Multiplication by 120x](https://jott.live/markdown/mm_wasm) -0. [Chasing Memory Bugs through V8 and WebAssembly](https://blog.stackblitz.com/posts/debugging-v8-webassembly/) -0. [Wasm needs a better memory management story](https://github.com/WebAssembly/design/issues/1397) -0. https://bytecodealliance.org/ -0. [Faster Fractals with Multi-Threaded WebAssembly](https://blog.scottlogic.com/2019/07/15/multithreaded-webassembly.html) -0. https://blog.scottlogic.com/2018/07/20/wasm-future.html -0. http://fitzgeraldnick.com/2018/04/26/how-does-dynamic-dispatch-work-in-wasm.html -0. https://hacks.mozilla.org/2018/03/making-webassembly-better-for-rust-for-all-languages/ -0. https://webassembly.github.io/ -0. https://github.com/WebAssembly/spec/blob/md-proto/md-proto/WebAssembly.md -0. https://github.com/WebAssembly/binaryen -0. [NYLUG Presents: Luke Wagner -on- WebAssembly: A New Compiler Target For The Web](https://www.youtube.com/watch?v=RByPdCN1RQ4) -0. https://binji.github.io/2017/03/05/webassembly-type-checking.html -0. https://github.com/WebAssembly/spec/tree/master/interpreter -0. https://mbebenita.github.io//WasmExplorer/ -0. http://thecodebarbarian.com/getting-started-with-webassembly-in-node.js.html -0. http://blog.seraum.com/compiling-javascript-to-webassembly-wasm-or-asm-js-with-nectarjs -0. https://hacks.mozilla.org/2017/07/memory-in-webassembly-and-why-its-safer-than-you-think/ -0. [Using WebAssembly and Threads (Chrome Dev Summit 2018)](https://www.youtube.com/watch?v=zgOGZgAPUjQ) -0. https://github.com/wasmerio/wasmer -0. https://www.fastly.com/blog/announcing-lucet-fastly-native-webassembly-compiler-runtime -0. https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/ -0. https://cybernetist.com/2019/04/25/wasm-universal-application-runtime/ -0. https://github.com/intel/wasm-micro-runtime -0. https://medium.com/wasmer/running-webassembly-on-the-kernel-8e04761f1d8e - diff --git a/documentation/bookmark/compilation/target/wasm__WebAssembly.md b/documentation/bookmark/compilation/target/wasm__WebAssembly.md new file mode 100644 index 000000000..dd496d03e --- /dev/null +++ b/documentation/bookmark/compilation/target/wasm__WebAssembly.md @@ -0,0 +1,59 @@ +# Interoperability + +0. []() +0. [How to Extend WebAssembly with Host Functions](https://www.secondstate.io/articles/extend-webassembly/) +0. [js-wasm: JavaScript and WebAssembly should be a joy to use together.](https://wasm.js.org/) + +# Concurrency + +0. []() +0. [Wasm threads are now available in all browsers](https://old.reddit.com/r/WebAssembly/comments/rk83mr/wasm_threads_are_now_available_in_all_browsers/) + +# Platform + +0. []() +0. [Wasmer Java](https://github.com/wasmerio/wasmer-java) +0. [WAVM: WAVM is a WebAssembly virtual machine, designed for use in non-web applications.](https://wavm.github.io/) + +# Exemplar + +0. []() +0. [Announcing GraalWasm — a WebAssembly engine in GraalVM](https://medium.com/graalvm/announcing-graalwasm-a-webassembly-engine-in-graalvm-25cd0400a7f2) +0. [Towards a WebAssembly standalone runtime on GraalVM](https://dl.acm.org/citation.cfm?id=3362780) +0. https://github.com/vvanders/wasm_lua +0. https://github.com/AppCypher/webassemblylanguages +0. https://medium.com/perlin-network/life-a-secure-blazing-fast-cross-platform-webassembly-vm-in-go-ea3b31fa6e09 + +# Reference + +0. []() +0. [just-in-time code generation within webassembly](https://wingolog.org/archives/2022/08/18/just-in-time-code-generation-within-webassembly) +0. [TeaVM: Build Fast, Modern Web Apps in Java](https://teavm.org/) +0. [Recommendations when publishing a Wasm library](https://nickb.dev/blog/recommendations-when-publishing-a-wasm-library) +0. [Building host implementations for WebAssembly interfaces](https://radu-matei.com/blog/wasm-components-host-implementations/) +0. [WebAssembly Techniques to Speed Up Matrix Multiplication by 120x](https://jott.live/markdown/mm_wasm) +0. [Chasing Memory Bugs through V8 and WebAssembly](https://blog.stackblitz.com/posts/debugging-v8-webassembly/) +0. [Wasm needs a better memory management story](https://github.com/WebAssembly/design/issues/1397) +0. https://bytecodealliance.org/ +0. [Faster Fractals with Multi-Threaded WebAssembly](https://blog.scottlogic.com/2019/07/15/multithreaded-webassembly.html) +0. https://blog.scottlogic.com/2018/07/20/wasm-future.html +0. http://fitzgeraldnick.com/2018/04/26/how-does-dynamic-dispatch-work-in-wasm.html +0. https://hacks.mozilla.org/2018/03/making-webassembly-better-for-rust-for-all-languages/ +0. https://webassembly.github.io/ +0. https://github.com/WebAssembly/spec/blob/md-proto/md-proto/WebAssembly.md +0. https://github.com/WebAssembly/binaryen +0. [NYLUG Presents: Luke Wagner -on- WebAssembly: A New Compiler Target For The Web](https://www.youtube.com/watch?v=RByPdCN1RQ4) +0. https://binji.github.io/2017/03/05/webassembly-type-checking.html +0. https://github.com/WebAssembly/spec/tree/master/interpreter +0. https://mbebenita.github.io//WasmExplorer/ +0. http://thecodebarbarian.com/getting-started-with-webassembly-in-node.js.html +0. http://blog.seraum.com/compiling-javascript-to-webassembly-wasm-or-asm-js-with-nectarjs +0. https://hacks.mozilla.org/2017/07/memory-in-webassembly-and-why-its-safer-than-you-think/ +0. [Using WebAssembly and Threads (Chrome Dev Summit 2018)](https://www.youtube.com/watch?v=zgOGZgAPUjQ) +0. https://github.com/wasmerio/wasmer +0. https://www.fastly.com/blog/announcing-lucet-fastly-native-webassembly-compiler-runtime +0. https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/ +0. https://cybernetist.com/2019/04/25/wasm-universal-application-runtime/ +0. https://github.com/intel/wasm-micro-runtime +0. https://medium.com/wasmer/running-webassembly-on-the-kernel-8e04761f1d8e + diff --git a/documentation/bookmark/css.md b/documentation/bookmark/css.md index c1231143a..cf49d95ba 100644 --- a/documentation/bookmark/css.md +++ b/documentation/bookmark/css.md @@ -6,6 +6,7 @@ # Reference 0. []() +0. [Meet the top layer: a solution to z-index:10000](https://developer.chrome.com/blog/what-is-the-top-layer/) 0. [Not All Zeros are Equal: And every ‘best practice’ comes with caveats](https://www.oddbird.net/2022/08/04/zero-units/) 0. [Style scoping versus shadow DOM: which is fastest?](https://nolanlawson.com/2022/06/22/style-scoping-versus-shadow-dom-which-is-fastest/) 0. [Got Spaghetti Stylesheets? 4 Techniques for Managing CSS Complexity](https://blog.shimin.io/4-techniques-for-managing-css-complexity/) diff --git a/documentation/bookmark/end_user_programming.md b/documentation/bookmark/end_user_programming.md new file mode 100644 index 000000000..ef39bbed3 --- /dev/null +++ b/documentation/bookmark/end_user_programming.md @@ -0,0 +1,5 @@ +# Reference + +0. []() +0. [End-user Programming](https://www.inkandswitch.com/end-user-programming/) + diff --git a/documentation/bookmark/open_source.md b/documentation/bookmark/open_source.md index db237a9f8..2a8c67a86 100644 --- a/documentation/bookmark/open_source.md +++ b/documentation/bookmark/open_source.md @@ -1,6 +1,7 @@ # Reference 0. []() +0. [The Myth of Mass Collaboration](https://staltz.com/the-myth-of-mass-collaboration.html) 0. [Open Source Explained](https://blog.erlend.sh/open-source-explained) 0. [Trust Signals in Open Source Projects](https://hackernoon.com/the-signs-of-a-great-open-source-project) 0. [Awesome OSS Monetization](https://paydevs.github.io/awesome-oss-monetization/) diff --git a/documentation/bookmark/parallelism.md b/documentation/bookmark/parallelism.md index d2a927171..e7fc2dae2 100644 --- a/documentation/bookmark/parallelism.md +++ b/documentation/bookmark/parallelism.md @@ -1,6 +1,7 @@ # Reference 0. []() +0. [Regent: Regent is a language for implicit task-based parallelism.](https://regent-lang.org/) 0. [The Taichi Programming Language](https://www.taichi-lang.org/) 0. [C++ Standard Parallelism - Bryce Adelstein Lelbach - CppCon 2021](https://www.youtube.com/watch?v=LW_T2RGXego) 0. [Arachne: Towards Core-Aware Scheduling](https://github.com/PlatformLab/Arachne) diff --git a/documentation/bookmark/propagator.md b/documentation/bookmark/propagator.md new file mode 100644 index 000000000..ab0cd9dd1 --- /dev/null +++ b/documentation/bookmark/propagator.md @@ -0,0 +1,6 @@ +# Reference + +0. []() +0. [Propagators, Brainy, and Spritely - MetaFox Talks](https://www.youtube.com/watch?v=jI8gA68OXLM) +0. [Revised Report on the Propagator Model](https://groups.csail.mit.edu/mac/users/gjs/propagators/) + diff --git a/documentation/bookmark/transducer_stream_pipe.md b/documentation/bookmark/transducer_stream_pipe.md index cb8aae481..3b3cd84a8 100644 --- a/documentation/bookmark/transducer_stream_pipe.md +++ b/documentation/bookmark/transducer_stream_pipe.md @@ -1,5 +1,7 @@ # Reference +0. []() +0. [Understanding transducers](https://andreyorst.gitlab.io/posts/2022-08-13-understanding-transducers/) 0. [Complete Guide to Transducers](https://nwcalvank.dev/transducers/) 0. [zug](https://sinusoid.es/zug/) 0. https://dev.to/greencoder/build-your-own-transducer-and-impress-your-cat---part-1-mhp diff --git a/documentation/bookmark/web_browser.md b/documentation/bookmark/web_browser.md index 7c12f5de2..80ee46027 100644 --- a/documentation/bookmark/web_browser.md +++ b/documentation/bookmark/web_browser.md @@ -1,56 +1,61 @@ # Exemplar -1. [Nyxt](https://nyxt.atlas.engineer/) -1. [Stack](https://stackbrowser.com/) -1. [Flow: The super fast, multithreaded HTML5 browser from Ekioh](https://www.ekioh.com/flow-browser/) -1. https://refresh.study/ -1. https://github.com/breach/breach_core -1. https://github.com/browserhtml/browserhtml -1. https://depolium.com/ -1. https://vivaldi.com/ -1. https://www.nidium.com/ -1. https://github.com/trevorlinton/webkit.js -1. https://www.epicbrowser.com/ -1. https://minbrowser.github.io/min/ -1. https://www.palemoon.org/ -1. https://github.com/beakerbrowser/webdb -1. https://github.com/beakerbrowser -1. https://github.com/nEXT-Browser/nEXT -1. https://techcrunch.com/2018/02/23/veil-is-private-browsing-for-the-ultra-paranoid/ -1. https://github.com/wexond/wexond -1. http://next.atlas.engineer -1. https://workona.com/ -1. https://luakit.github.io/ -1. https://www.thurrott.com/cloud/web-browsers/204669/opera-web-browser-is-reborn +0. []() +0. [Nyxt](https://nyxt.atlas.engineer/) +0. [Stack](https://stackbrowser.com/) +0. [Flow: The super fast, multithreaded HTML5 browser from Ekioh](https://www.ekioh.com/flow-browser/) +0. https://refresh.study/ +0. https://github.com/breach/breach_core +0. https://github.com/browserhtml/browserhtml +0. https://depolium.com/ +0. https://vivaldi.com/ +0. https://www.nidium.com/ +0. https://github.com/trevorlinton/webkit.js +0. https://www.epicbrowser.com/ +0. https://minbrowser.github.io/min/ +0. https://www.palemoon.org/ +0. https://github.com/beakerbrowser/webdb +0. https://github.com/beakerbrowser +0. https://github.com/nEXT-Browser/nEXT +0. https://techcrunch.com/2018/02/23/veil-is-private-browsing-for-the-ultra-paranoid/ +0. https://github.com/wexond/wexond +0. http://next.atlas.engineer +0. https://workona.com/ +0. https://luakit.github.io/ +0. https://www.thurrott.com/cloud/web-browsers/204669/opera-web-browser-is-reborn # Security -1. https://developers.google.com/web/updates/2018/06/feature-policy -1. https://cure53.de/#browser-security-whitepaper -1. https://anon.cosheaf.com/ -1. [Secure Browser Architecture Based on Hardware Virtualization](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.664.9527&rep=rep1&type=pdf) -1. https://medium.com/personal-capital-tech-blog/why-we-write-post-only-apis-f15108fb6558 +0. []() +0. https://developers.google.com/web/updates/2018/06/feature-policy +0. https://cure53.de/#browser-security-whitepaper +0. https://anon.cosheaf.com/ +0. [Secure Browser Architecture Based on Hardware Virtualization](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.664.9527&rep=rep1&type=pdf) +0. https://medium.com/personal-capital-tech-blog/why-we-write-post-only-apis-f15108fb6558 # Performance -1. https://github.com/slightlyoff/never_slow_mode +0. []() +0. https://github.com/slightlyoff/never_slow_mode # Reference -1. [Emacs with Nyxt: extend your editor with the power of a Lisp browser](https://nyxt.atlas.engineer/article/emacs-conf.org) -1. [Web Browser Engineering](https://browser.engineering/) -1. [Public Suffix List](https://publicsuffix.org/) -1. [Public Suffix List Problems](https://github.com/sleevi/psl-problems) -1. https://www.opera.com/gx -1. https://evertpot.com/tabs-are-the-wrong-abstraction/ -1. http://news.mit.edu/2018/system-patches-private-browsing-0223 -1. https://vivaldi.com/blog/vivaldi-makes-history/?hl=en-us&version=1.8.770.56&os=W10.0.14393 -1. https://hacks.mozilla.org/2017/08/inside-a-super-fast-css-engine-quantum-css-aka-stylo/ -1. https://mozillagfx.wordpress.com/2017/09/21/introduction-to-webrender-part-1-browsers-today/ -1. https://noncombatant.org/2017/11/07/problems-of-urls/ -1. https://stoyannk.wordpress.com/2017/11/13/rendering-html-at-1000-fps-part-2/ -1. https://v8project.blogspot.com/2018/08/embedded-builtins.html -1. https://developers.google.com/web/updates/2018/09/inside-browser-part1 -1. https://addons.mozilla.org/en-US/firefox/addon/tree-style-tab/ -1. [Web Browser Engineering](https://browser.engineering/index.html) +0. []() +0. [V8 Torque user manual](https://v8.dev/docs/torque) +0. [Emacs with Nyxt: extend your editor with the power of a Lisp browser](https://nyxt.atlas.engineer/article/emacs-conf.org) +0. [Web Browser Engineering](https://browser.engineering/) +0. [Public Suffix List](https://publicsuffix.org/) +0. [Public Suffix List Problems](https://github.com/sleevi/psl-problems) +0. https://www.opera.com/gx +0. https://evertpot.com/tabs-are-the-wrong-abstraction/ +0. http://news.mit.edu/2018/system-patches-private-browsing-0223 +0. https://vivaldi.com/blog/vivaldi-makes-history/?hl=en-us&version=1.8.770.56&os=W10.0.14393 +0. https://hacks.mozilla.org/2017/08/inside-a-super-fast-css-engine-quantum-css-aka-stylo/ +0. https://mozillagfx.wordpress.com/2017/09/21/introduction-to-webrender-part-1-browsers-today/ +0. https://noncombatant.org/2017/11/07/problems-of-urls/ +0. https://stoyannk.wordpress.com/2017/11/13/rendering-html-at-1000-fps-part-2/ +0. https://v8project.blogspot.com/2018/08/embedded-builtins.html +0. https://developers.google.com/web/updates/2018/09/inside-browser-part1 +0. https://addons.mozilla.org/en-US/firefox/addon/tree-style-tab/ +0. [Web Browser Engineering](https://browser.engineering/index.html) diff --git a/stdlib/source/library/lux/control/concurrency/actor.lux b/stdlib/source/library/lux/control/concurrency/actor.lux index d4c50b896..7b430da17 100644 --- a/stdlib/source/library/lux/control/concurrency/actor.lux +++ b/stdlib/source/library/lux/control/concurrency/actor.lux @@ -7,7 +7,9 @@ ["[0]" pipe] ["[0]" try (.only Try)] ["[0]" exception] - ["[0]" io (.only IO io)]] + ["[0]" io (.only IO io)] + [function + [predicate (.only Predicate)]]] [data ["[0]" bit] ["[0]" product]] @@ -18,7 +20,7 @@ [primitive (.only primitive representation abstraction)]]]]] [// ["[0]" atom (.only Atom atom)] - ["[0]" async (.only Async Resolver)] + ["[0]" async (.only Async Resolver) (.use "[1]#[0]" monad)] ["[0]" frp (.only Channel Channel')]]) (exception.def .public poisoned) @@ -79,10 +81,11 @@ (when ?state' {try.#Failure error} (let [[_ resolve] (the #obituary (representation self))] - (exec (io.run! - (do io.monad - [pending (..pending tail)] - (resolve [error state {.#Item head pending}]))) + (exec + (io.run! + (do io.monad + [pending (..pending tail)] + (resolve [error state {.#Item head pending}]))) (in []))) {try.#Success state'} @@ -170,7 +173,7 @@ (do async.monad [outcome (async.future (..mail! mail actor))] (when outcome - {try.#Success} + {try.#Success _} async {try.#Failure error} @@ -209,3 +212,40 @@ (at ! each try.maybe)) (in {.#None})))) channel))) + +... The following behavior and messages allow Lux's actors to behave like Clojure's agents. +... https://clojure.org/reference/agents + +(exception.def .public invalid) + +(def .public (validated ? it) + (All (_ state) + (-> (Predicate state) (Behavior state) + (Behavior state))) + (function (_ mail before actor) + (do (try.with async.monad) + [after (mail before actor)] + (if (? after) + (in after) + (async#in (exception.except ..invalid [])))))) + +(def .public state + (All (_ state) + (Message state state)) + (function (_ state self) + (async#in {try.#Success [state state]}))) + +(def .public (update $) + (All (_ state) + (-> (-> state state) + (Message state [state state]))) + (function (_ before self) + (let [after ($ before)] + (async#in {try.#Success [after [before after]]})))) + +(def .public (reset after) + (All (_ state) + (-> state + (Message state state))) + (function (_ before self) + (async#in {try.#Success [after before]}))) diff --git a/stdlib/source/library/lux/control/concurrency/agent.lux b/stdlib/source/library/lux/control/concurrency/agent.lux new file mode 100644 index 000000000..bf9608cb7 --- /dev/null +++ b/stdlib/source/library/lux/control/concurrency/agent.lux @@ -0,0 +1,25 @@ +(.require + [library + [lux (.except) + [control + ["[0]" try (.only Try)] + ["[0]" io (.only IO)]]]] + [// + ["[0]" async (.only Async)] + ["[0]" actor (.only Actor)] + ["[0]" frp (.only Channel')]]) + +(def .public Agent + Actor) + +(def .public (react! events handler agent) + (All (_ eventR eventW state) + (-> (Channel' eventR eventW) + (-> eventR state (Async (Try state))) + (Agent state) + (IO Any))) + (frp.subscribe! (function (_ event) + (actor.mail! (function (_ state self) + (handler event state)) + agent)) + events)) diff --git a/stdlib/source/test/lux/control.lux b/stdlib/source/test/lux/control.lux index c51399523..4eba3a2a7 100644 --- a/stdlib/source/test/lux/control.lux +++ b/stdlib/source/test/lux/control.lux @@ -7,6 +7,7 @@ ["[1][0]" concatenative] ["[1][0]" concurrency ["[1]/[0]" actor] + ["[1]/[0]" agent] ["[1]/[0]" atom] ["[1]/[0]" frp] ["[1]/[0]" thread] @@ -39,6 +40,7 @@ Test (all _.and /concurrency/actor.test + /concurrency/agent.test /concurrency/atom.test /concurrency/frp.test /concurrency/thread.test diff --git a/stdlib/source/test/lux/control/concurrency/actor.lux b/stdlib/source/test/lux/control/concurrency/actor.lux index e8d3568fd..8353b2e8a 100644 --- a/stdlib/source/test/lux/control/concurrency/actor.lux +++ b/stdlib/source/test/lux/control/concurrency/actor.lux @@ -200,4 +200,64 @@ actual (async.future (atom.read! sink))] (unit.coverage [/.Stop /.observe! /.obituary] (at (list.equivalence n.equivalence) = expected (sequence.list actual)))))) + (in (do async.monad + [actor (async.future (/.spawn! /.default initial_state)) + actual (/.tell! /.state actor)] + (unit.coverage [/.state] + (<| (try.else false) + (do try.monad + [actual actual] + (in (same? initial_state actual))))))) + (in (do async.monad + [actor (async.future (/.spawn! /.default initial_state)) + before,after (/.tell! (/.update ++) actor) + actual (/.tell! /.state actor)] + (unit.coverage [/.update] + (<| (try.else false) + (do try.monad + [[before after] before,after + actual actual] + (in (and (n.= (++ before) after) + (same? after actual)))))))) + (in (do async.monad + [actor (async.future (/.spawn! /.default initial_state)) + before,after (/.tell! (/.update ++) actor) + _ (/.tell! (/.reset initial_state) actor) + actual (/.tell! /.state actor)] + (unit.coverage [/.reset] + (<| (try.else false) + (do try.monad + [[before after] before,after + actual actual] + (in (and (n.= (++ before) after) + (same? initial_state before) + (same? initial_state actual)))))))) + (in (do async.monad + [actor (async.future (/.spawn! (/.validated (n.< initial_state) /.default) + initial_state)) + before,after (/.tell! (/.update --) actor) + actual (/.tell! /.state actor)] + (unit.coverage [/.validated] + (<| (try.else false) + (do try.monad + [[before after] before,after + actual actual] + (in (and (n.= (-- before) after) + (same? after actual)))))))) + (in (do async.monad + [actor (async.future (/.spawn! (/.validated (n.< initial_state) /.default) + initial_state)) + before,after (/.tell! (/.update ++) actor) + [cause_of_death state pending] (/.obituary actor) + actual (/.tell! /.state actor)] + (unit.coverage [/.invalid] + (when [before,after actual] + [{try.#Success [before after]} + {try.#Failure afterwards}] + (and (n.= (++ before) after) + (exception.match? /.invalid cause_of_death) + (exception.match? /.dead afterwards)) + + _ + false)))) )))) diff --git a/stdlib/source/test/lux/control/concurrency/agent.lux b/stdlib/source/test/lux/control/concurrency/agent.lux new file mode 100644 index 000000000..9627da9f9 --- /dev/null +++ b/stdlib/source/test/lux/control/concurrency/agent.lux @@ -0,0 +1,49 @@ +(.require + [library + [lux (.except) + [abstract + [monad (.only do)]] + [control + ["[0]" try]] + [math + ["[0]" random] + [number + ["n" nat]]] + [test + ["_" property (.only Test)] + ["[0]" unit]]]] + [\\library + ["[0]" / (.only) + [// + ["[0]" atom (.only Atom)] + ["[0]" async (.only Async Resolver) (.use "[1]#[0]" monad)] + ["[0]" frp] + ["[0]" actor]]]]) + +(def .public test + Test + (do [! random.monad] + [left random.nat + right random.nat] + (<| (_.covering /._) + (_.for [/.Agent]) + (all _.and + (in (do async.monad + [agent (async.future + (actor.spawn! actor.default 0)) + _ (async.future + (/.react! (frp.sequential 0 (list left right)) + (function (_ next current) + (async#in {try.#Success (n.+ next current)})) + agent)) + _ (async.delay 1) + ?state (actor.tell! actor.state agent)] + (unit.coverage [/.react!] + (when ?state + {try.#Success actual} + (n.= (n.+ left right) + actual) + + failure + false)))) + )))) -- cgit v1.2.3