This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-09-07
Channels
- # announcements (1)
- # babashka (28)
- # beginners (212)
- # calva (13)
- # clara (3)
- # clj-kondo (39)
- # cljsrn (1)
- # clojure (16)
- # clojure-australia (1)
- # clojure-europe (11)
- # clojure-nl (2)
- # clojure-spec (9)
- # clojure-uk (8)
- # clojurescript (66)
- # cloverage (3)
- # code-reviews (16)
- # cursive (12)
- # data-science (2)
- # datomic (118)
- # events (1)
- # garden (2)
- # improve-getting-started (1)
- # introduce-yourself (1)
- # jobs (4)
- # missionary (5)
- # numerical-computing (1)
- # off-topic (5)
- # pathom (3)
- # polylith (71)
- # re-frame (99)
- # reagent (17)
- # remote-jobs (5)
- # shadow-cljs (35)
- # tools-deps (5)
- # xtdb (4)
on the JVM where there is no real stack storage of data, "store the state of the function" would mean reifying the stack pointer (entrypoint) and call stack (what you return to) into something you can execute later by interpreting it, and storing all scoped heap references in a way you can later restore.
this is expensive, because as far as I know the only way to have a resumable continuation on the jvm is to use an interpreter (IOW use a reified stack for your code, and put an interpreter in the actual stack)
I'm basing what I'm saying on my understanding of the jvm - it can't do goto past method boundaries which is a pre-requisite for non-interpreted continuations
I'd be interested in being proved wrong actually
oh! you mean loom the jvm project
yes, that's awesome and up and coming, it totally changes what the jvm can do
I was thinking of loom the graph library lol
right, so continuations are coming... eventually
I'm a "Rust person" building a company on nightly. I wish I wasn't, but there's some embedded stuff that just can't be done on stable yet.
(import java.lang.Continuation)
=> java.lang.Continuation
(import java.lang.ContinuationScope)
=> java.lang.ContinuationScope
(ContinuationScope. "scope")
=> #object[java.lang.ContinuationScope 0x4356af7c "scope"]
(def default-scope (ContinuationScope. "scope"))
=> #'user/default-scope
(Continuation. default-scope (fn []
(println "A")
(Continuation/yield default-scope)
(println "B")))
=> #object[java.lang.Continuation 0x3a99c9b2 "java.lang.Continuation@3a99c9b2 scope: scope"]
(def cont (Continuation. default-scope (fn []
(println "A")
(Continuation/yield default-scope)
(println "B"))))
=> #'user/cont
(.run cont)
A
=> nil
(.run cont)
B
=> nil
(.run cont)
Execution error (IllegalStateException) at java.lang.Continuation/run (Continuation.java:286).
Continuation terminated
(defn generator [f]
(let [last-val (volatile! nil)
scope (ContinuationScope. "generator")
continuation (Continuation. scope (fn []
(f (fn [v]
(vreset! last-val v)
(Continuation/yield scope)))))]
(reify Iterator
(hasNext [_]
(not (.isDone continuation)))
(next [_]
(.run continuation)
@last-val))))
=> #'user/generator
(def gen (generator
(fn [yield]
(doseq [x (range 10)]
(yield x)))))
=> #'user/gen
(iterator-seq gen)
=> (0 1 2 3 4 5 6 7 8 9 9)
(defn generator [f]
(let [no-yield (Object.)
last-val (volatile! no-yield)
scope (ContinuationScope. "generator")
continuation (Continuation. scope (fn []
(f (fn [v]
(vreset! last-val v)
(Continuation/yield scope)))))]
(reify Iterator
(hasNext [_]
(and (not (.isDone continuation))
(do (.run continuation)
(not= @last-val no-yield))))
(next [_]
(when (and (not (.isDone continuation)) (= @last-val no-yield))
(.run continuation))
(let [val @last-val]
(vreset! last-val no-yield)
val)))))
=> #'user/generator
(def gen (generator
(fn [yield]
(doseq [x (range 10)]
(yield x)))))
=> #'user/gen
(iterator-seq gen)
=> (1 2 3 4 5 6 7 8 9)