Fork me on GitHub
#hyperfiddle
<
2022-05-11
>
kennytilton22:05:42

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.

Dustin Getz22:05:34

This is a missionary layer question, but regardless show me a concrete test and i'll port it to photon

kennytilton22:05:57

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? 🙂

Dustin Getz22:05:57

https://github.com/leonoel/missionary , Photon's DAG compile target (which has a design goal of being glitch free)

kennytilton22:05:09

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?

Dustin Getz22:05:55

> Does missionary guarantee that any and all dependencies experience only one new arrival of data? Yes, glitches are unacceptable in our opinion

Dustin Getz22:05:21

As you pointed out, events often drive external side effects, so there cannot be glitches

Dustin Getz23:05:44

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]))

Dustin Getz23:05:54

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

Dustin Getz23:05:36

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))

kennytilton08:05:22

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.

kennytilton08:05:07

Oh, wait, they say "Correct incremental maintenance of dynamic DAGs without inconsistent states (aka FRP glitches)". There ya go!

kennytilton08:05:20

Checking anyway... 🙂

leonoel08:05:14

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! etc

leonoel09:05:00

if you want to try it at home, build latest missionary locally, cp is not released yet

kennytilton09:05:33

Damn, you all are fast! What does "build locally" look like, @U053XQP4S? All I know is lein install. Thx for this!

leonoel09:05:28

mvn clean && mvn compile && mvn install

leonoel09:05:39

then use maven version b.27-SNAPSHOT

Dustin Getz10:05:06

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

Panel13:05:52

Photon looks like a wrapper on top of missionary with nicer syntax, is that right ?

yes 1
kennytilton13:05:22

Thx, @U053XQP4S, install went smoothly. I have worked through the two tutorials, will check out your Pentagram shortly.

kennytilton13:05:38

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.

clojure-spin 1
kennytilton13:05:20

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!

kennytilton13:05:14

btw, I am running Intellij/Cursive evaluating all expressions via the repl.

leonoel13:05:00

(import missionary.Cancelled)

Panel14:05:47

open-sourcing photon is part of the plan ?

Dustin Getz14:05:25

Yes of course, our business model is cloud low-code stuff

Dustin Getz14:05:01

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!

Noah Bogart20:05:57

that looks great

🙂 1