This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-05-11
Channels
- # announcements (6)
- # babashka (7)
- # beginners (145)
- # biff (2)
- # calva (9)
- # cider (4)
- # circleci (9)
- # clj-commons (22)
- # clj-kondo (26)
- # cljs-dev (70)
- # cljsrn (4)
- # clojure (46)
- # clojure-australia (9)
- # clojure-europe (62)
- # clojure-nl (5)
- # clojure-norway (4)
- # clojure-spec (11)
- # clojure-uk (3)
- # clojurescript (18)
- # copenhagen-clojurians (1)
- # core-async (1)
- # cursive (13)
- # datahike (6)
- # datomic (47)
- # emacs (5)
- # events (2)
- # fulcro (13)
- # google-cloud (2)
- # gratitude (2)
- # helix (5)
- # honeysql (5)
- # hyperfiddle (31)
- # jobs (1)
- # jobs-discuss (6)
- # london-clojurians (1)
- # lsp (5)
- # off-topic (9)
- # polylith (12)
- # portal (18)
- # re-frame (5)
- # reagent (29)
- # releases (2)
- # shadow-cljs (43)
- # specter (1)
- # test-check (8)
- # vim (1)
- # xtdb (66)
Nice. Saw the Diamond test. Do you handle what Philip Eby christened "The Pentagram of Death"? I cannot find his description on The Google, but it was the use case that convinced him my Cells algorithm was the only way to ensure data integrity. The key elements are: • two dependency chains from some property P leading back to one property X; and • branching code in the derivation of P that will not travel the second dependency chain until a certain condition is met; and • by chance, propagation reaches P on the the first path before it reaches some intermediate property I on the second dependency chain. The consequence is P updating once and reading (for the first time) property I, which has not yet been updated hence is inconsistent with the new value of X. This inconsistency is temporary (hence the name "glitch") because I will be updated soon enough and P will achieve consistency with X, but if one's reactive engine dispatches side effects off state change -- possible trouble.
This is a missionary layer question, but regardless show me a concrete test and i'll port it to photon
The Google fails me on "missionary layer question", but I think I have the test in my Cells regression test. Guessing Clojure will be OK? 🙂
sure!
https://github.com/leonoel/missionary , Photon's DAG compile target (which has a design goal of being glitch free)
Ohhh, understood on "missionary layer". I forgot about that component. I am afraid my regression test will not be of much use -- it is quite unreadable, and was written by someone who was just thinking about how to trigger the glitch (me) -- and may not even translate to a streaming model: https://github.com/kennytilton/matrix/blob/73d58c985fcc87ca2d817b4c9215643acbeb4c45/cljs/matrix/test/tiltontec/cell/evaluate_test.cljc#L147 "may not even translate"? I saw Andrew Staltz conceding ReactiveX was susceptible to glitches: https://staltz.com/rx-glitches-arent-actually-a-problem.html The "solution" of coding around them was unsatisfactory, btw -- glitches arise in deep computations we really do not want to expand into the glitchy computation. MobX, btw, happens to do what Cells does: when reading a property during a computation, check that it is current and if not make it so before answering the read! JIT integrity. But that idea is what I think may conflict with a system accepting a stream of values. I wager the Missionary folks have thought this thru: a single datum arrives in a reactive system and like a particle/wave passes thru multiple slits. Does missionary guarantee that any and all dependencies experience only one new arrival of data?
> Does missionary guarantee that any and all dependencies experience only one new arrival of data? Yes, glitches are unacceptable in our opinion
As you pointed out, events often drive external side effects, so there cannot be glitches
Is this close to the test?
(tests
(def !p (atom 0))
(def !q (atom 1))
(def !control (atom :p))
(with (p/run (! (let [p (p/watch !p)
q (p/watch !q)
control (p/watch !control)
cross (case control :p p :q q)]
[p q control cross])))
% := [0 1 :p 0]
(reset! !control :q)
% := [0 1 :q 1]))
I think it's the same test as what you describe; it's the self-adjusting case where cross changes from p to q, and q has never been seen
Here it is using your letters, I think
(tests
(def !x (atom 0))
(def !control (atom :a))
(with (p/run (! (let [x (p/watch !x)
control (p/watch !control)
y (inc x)
p (case control :a x :b y)]
p)))
% := 0
(reset! !control :b)
% := 1))
Hmm, good idea! Let me fire up Missionary and get to know it for its own sake. I was able to demonstrate glitches with Reagent, I will see what I can do with Missionary.
Oh, wait, they say "Correct incremental maintenance of dynamic DAGs without inconsistent states (aka FRP glitches)". There ya go!
Checking anyway... 🙂
this is the pentagram of death in missionary
(def !aa (atom 1))
=> #'user/!aa
(def !a7 (atom 7))
=> #'user/!a7
(def cancel
((m/reactor
(let [<aa (m/signal! (m/watch !aa))
<a7 (m/signal! (m/watch !a7))
<a70 (m/signal! (m/latest (partial * 10) <a7))
<bb (m/signal! <aa)
<cc (m/signal! (m/latest (partial * 10) <aa))
<dd (m/signal! (m/cp
(try
(if (even? (m/?< <bb))
(* 10 (m/?< <cc)) 42)
(catch Cancelled _))))
<ee (m/signal! (m/latest + <a70 <bb (m/latest (partial * 10000) <dd)))]
(m/stream!
(m/ap
(m/amb=
(prn 'aa (m/?< <aa))
(prn 'a7 (m/?< <a7))
(prn 'a70 (m/?< <a70))
(prn 'bb (m/?< <bb))
(prn 'cc (m/?< <cc))
(prn 'dd (m/?< <dd))
(prn 'ee (m/?< <ee)))))))
prn prn))
ee 420071
dd 42
cc 10
bb 1
a70 70
a7 7
aa 1
=> #'user/cancel
(swap! !aa inc)
aa 2
bb 2
cc 20
dd 200
ee 2000072
=> 2
(swap! !aa inc)
aa 3
bb 3
cc 30
dd 42
ee 420073
=> 3
It is pretty much what the photon version would desugar to :
(p/run
(let [aa (p/Watch. !aa)
a7 (p/Watch. !a7)
a70 (* 10 a7)
bb aa
cc (* 10 aa)
dd (if (even? bb)
(* 10 cc)
42)
ee (+ a70 bb (* 10000 dd))]
(prn 'aa aa)
(prn 'a7 a7)
(prn 'a70 a70)
(prn 'bb bb)
(prn 'cc cc)
(prn 'dd dd)
(prn 'ee ee)))
function calls are turned into m/latest
, let bindings to m/signal!
etcif you want to try it at home, build latest missionary locally, cp
is not released yet
Damn, you all are fast! What does "build locally" look like, @U053XQP4S? All I know is lein install
. Thx for this!
Kenny I'll onboard you to Photon if you want to try it out, we're in private tech alpha, there are several good tutorials and growing fast, including some missionary tutorials
Thx, @U053XQP4S, install went smoothly. I have worked through the two tutorials, will check out your Pentagram shortly.
Thx, @U09K620SG. Is there a sign-up thingy you use? Right now I am wrapping #clojuredart in Matrix, but I would like to keep up with Photon. I have visions of a specialty consulting gig.
Getting close, @U053XQP4S :
Starting nREPL server...
/Users/kennethtilton/jdks/zulu11.35.15-ca-fx-jdk11.0.5-macosx_x64/bin/java -Dfile.encoding=UTF-8 -XX:-OmitStackTraceInFastThrow -Dclojure.compile.path=/Users/kennethtilton/dev/words/target/default/classes -Dwords.version=0.1.0-SNAPSHOT -Dclojure.debug=false "-javaagent:/Applications/IntelliJ IDEA IDEA " -classpath /Users/kennethtilton/dev/words/test:/Users/kennethtilton/dev/words/src:/Users/kennethtilton/dev/words/dev-resources:/Users/kennethtilton/dev/words/resources:/Users/kennethtilton/dev/words/target/default/classes:/Users/kennethtilton/.m2/repository/nrepl/nrepl/0.6.0/nrepl-0.6.0.jar:/Users/kennethtilton/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.8.7/jackson-core-2.8.7.jar:/Users/kennethtilton/.m2/repository/org/clojure/clojurescript/1.10.879/clojurescript-1.10.879.jar:/Users/kennethtilton/.m2/repository/clojure-complete/clojure-complete/0.2.5/clojure-complete-0.2.5.jar:/Users/kennethtilton/.m2/repository/org/msgpack/msgpack/0.6.12/msgpack-0.6.12.jar:/Users/kennethtilton/.m2/repository/org/clojure/tools.reader/1.3.3/tools.reader-1.3.3.jar:/Users/kennethtilton/.m2/repository/org/clojure/tools.analyzer/0.6.9/tools.analyzer-0.6.9.jar:/Users/kennethtilton/.m2/repository/org/clojure/google-closure-library/0.0-20201211-3e6c510d/google-closure-library-0.0-20201211-3e6c510d.jar:/Users/kennethtilton/.m2/repository/org/clojure/core.memoize/0.5.9/core.memoize-0.5.9.jar:/Users/kennethtilton/.m2/repository/org/clojure/google-closure-library-third-party/0.0-20201211-3e6c510d/google-closure-library-third-party-0.0-20201211-3e6c510d.jar:/Users/kennethtilton/.m2/repository/missionary/missionary/b.27-SNAPSHOT/missionary-b.27-SNAPSHOT.jar:/Users/kennethtilton/.m2/repository/com/google/javascript/closure-compiler-unshaded/v20210505/closure-compiler-unshaded-v20210505.jar:/Users/kennethtilton/.m2/repository/com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1.jar:/Users/kennethtilton/.m2/repository/org/reactivestreams/reactive-streams/1.0.3/reactive-streams-1.0.3.jar:/Users/kennethtilton/.m2/repository/cloroutine/cloroutine/10/cloroutine-10.jar:/Users/kennethtilton/.m2/repository/org/ow2/asm/asm-all/4.2/asm-all-4.2.jar:/Users/kennethtilton/.m2/repository/org/clojure/data.json/0.2.6/data.json-0.2.6.jar:/Users/kennethtilton/.m2/repository/com/cognitect/transit-java/0.8.332/transit-java-0.8.332.jar:/Users/kennethtilton/.m2/repository/org/clojure/data.priority-map/0.0.7/data.priority-map-0.0.7.jar:/Users/kennethtilton/.m2/repository/com/cognitect/transit-clj/0.8.309/transit-clj-0.8.309.jar:/Users/kennethtilton/.m2/repository/org/clojure/clojure/1.10.1/clojure-1.10.1.jar:/Users/kennethtilton/.m2/repository/org/clojure/core.specs.alpha/0.2.44/core.specs.alpha-0.2.44.jar:/Users/kennethtilton/.m2/repository/org/javassist/javassist/3.18.1-GA/javassist-3.18.1-GA.jar:/Users/kennethtilton/.m2/repository/org/clojure/core.cache/0.6.5/core.cache-0.6.5.jar:/Users/kennethtilton/.m2/repository/commons-codec/commons-codec/1.10/commons-codec-1.10.jar:/Users/kennethtilton/.m2/repository/org/clojure/spec.alpha/0.2.176/spec.alpha-0.2.176.jar:/Users/kennethtilton/.m2/repository/org/clojure/tools.analyzer.jvm/0.7.2/tools.analyzer.jvm-0.7.2.jar clojure.main -i /private/var/folders/zl/tyjfph_92ws1z65_7mbtbdxc0000gn/T/form-init8951147573957717648.clj
:user-loaded!!!!!!!!!!!!!!!
Connecting to local nREPL server...
Clojure 1.10.1
nREPL server started on port 49534 on host 127.0.0.1 -
Loading test/missionary/glitch_test.clj... done
(def !aa (atom 1))
=> #'missionary.glitch-test/!aa
(def !a7 (atom 7))
=> #'missionary.glitch-test/!a7
(def cancel
((m/reactor
(let [<aa (m/signal! (m/watch !aa))
<a7 (m/signal! (m/watch !a7))
<a70 (m/signal! (m/latest (partial * 10) <a7))
<bb (m/signal! <aa)
<cc (m/signal! (m/latest (partial * 10) <aa))
<dd (m/signal! (m/cp
(try
(if (even? (m/?< <bb))
(* 10 (m/?< <cc)) 42)
(catch Cancelled _))))
<ee (m/signal! (m/latest + <a70 <bb (m/latest (partial * 10000) <dd)))]
(m/stream!
(m/ap
(m/amb=
(prn 'aa (m/?< <aa))
(prn 'a7 (m/?< <a7))
(prn 'a70 (m/?< <a70))
(prn 'bb (m/?< <bb))
(prn 'cc (m/?< <cc))
(prn 'dd (m/?< <dd))
(prn 'ee (m/?< <ee)))))))
prn prn))
Syntax error macroexpanding cloroutine.core/cr at (test/missionary/glitch_test.clj:8:29).
Could not resolve var: Cancelled
My NS:
(ns missionary.glitch-test
(:require [clojure.test :refer :all]
[missionary.core :refer [?] :as m]))
My leiningen project.clj:
(defproject words "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url ""
:license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
:url " "}
:dependencies [[org.clojure/clojure "1.10.1"]
[missionary "b.27-SNAPSHOT"]]
:main ^:skip-aot words.core
:target-path "target/%s"
:profiles {:uberjar {:aot :all
:jvm-opts ["-Dclojure.compiler.direct-linking=true"]}})
The relevant build output:
-----------------------< missionary:missionary >------------------------
[INFO] Building missionary b.27-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ missionary ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 17 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ missionary ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ missionary ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /Users/kennethtilton/dev/missionary/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ missionary ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ missionary ---
[INFO] No tests to run.
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ missionary ---
[INFO] Building jar: /Users/kennethtilton/dev/missionary/target/missionary-b.27-SNAPSHOT.jar
[INFO]
[INFO] --- maven-install-plugin:2.4:install (default-install) @ missionary ---
[INFO] Installing /Users/kennethtilton/dev/missionary/target/missionary-b.27-SNAPSHOT.jar to /Users/kennethtilton/.m2/repository/missionary/missionary/b.27-SNAPSHOT/missionary-b.27-SNAPSHOT.jar
[INFO] Installing /Users/kennethtilton/dev/missionary/pom.xml to /Users/kennethtilton/.m2/repository/missionary/missionary/b.27-SNAPSHOT/missionary-b.27-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.507 s
[INFO] Finished at: 2022-05-12T09:21:02-04:00
[INFO] ------------------------------------------------------------------------
Any suggestions? Thx for the extra effort, btw!btw, I am running Intellij/Cursive evaluating all expressions via the repl.
Yes of course, our business model is cloud low-code stuff
It is only private today because we want to iron out the rough edges and make sure initial trials are successful. Been onboarding people this week, so far so good!