aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Julian2022-08-22 20:45:33 -0400
committerEduardo Julian2022-08-22 20:45:33 -0400
commit9671484b6cb3f3c56d6a3053a4a55b4634c14a89 (patch)
tree565634861f857f9fb2ea191c627554303333e53e
parentc00d94fa5c9e6b3b8d25f49d0f2d341ff61fa35b (diff)
Added support for the agent model.
-rw-r--r--documentation/book/the_lux_programming_language/appendix_a.md2
-rw-r--r--documentation/book/the_lux_programming_language/appendix_c.md2
-rw-r--r--documentation/bookmark/business/productivity.md1
-rw-r--r--documentation/bookmark/compilation/target/wasm__WebAssembly.md (renamed from documentation/bookmark/compilation/target/wasm.md)1
-rw-r--r--documentation/bookmark/css.md1
-rw-r--r--documentation/bookmark/end_user_programming.md5
-rw-r--r--documentation/bookmark/open_source.md1
-rw-r--r--documentation/bookmark/parallelism.md1
-rw-r--r--documentation/bookmark/propagator.md6
-rw-r--r--documentation/bookmark/transducer_stream_pipe.md2
-rw-r--r--documentation/bookmark/web_browser.md93
-rw-r--r--stdlib/source/library/lux/control/concurrency/actor.lux54
-rw-r--r--stdlib/source/library/lux/control/concurrency/agent.lux25
-rw-r--r--stdlib/source/test/lux/control.lux2
-rw-r--r--stdlib/source/test/lux/control/concurrency/actor.lux60
-rw-r--r--stdlib/source/test/lux/control/concurrency/agent.lux49
16 files changed, 252 insertions, 53 deletions
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__WebAssembly.md
index e90bcd654..dd496d03e 100644
--- a/documentation/bookmark/compilation/target/wasm.md
+++ b/documentation/bookmark/compilation/target/wasm__WebAssembly.md
@@ -27,6 +27,7 @@
# 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/)
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))))
+ ))))