Skip to content

Commit

Permalink
Remove reflection.
Browse files Browse the repository at this point in the history
  • Loading branch information
Pauli Jaakkola committed Aug 6, 2020
1 parent 41dc235 commit 1c36b58
Show file tree
Hide file tree
Showing 9 changed files with 56 additions and 40 deletions.
10 changes: 6 additions & 4 deletions src/fell/core.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

(defn request-eff
"Wrap the effect `request` into an Eff."
[request]
^Impure [request]
(Impure. request (singleton-queue pure)))

;; TODO: Improve `weave` nomenclature:
Expand All @@ -34,7 +34,8 @@
[tag ret handle eff]
(condp instance? eff
Pure (ret (extract eff))
Impure (let [request (.-request eff)
Impure (let [^Impure eff eff
request (.-request eff)
cont (.-cont eff)
cont (append-handler cont (partial handle-relay tag ret handle))]
(if (= (first request) tag)
Expand All @@ -46,5 +47,6 @@
[eff]
(condp instance? eff
Pure (extract eff)
Impure (throw (#?(:clj RuntimeException., :cljs js/Error.)
(str "unhandled effect " (pr-str (.-request eff)))))))
Impure (let [^Impure eff eff]
(throw (#?(:clj RuntimeException., :cljs js/Error.)
(str "unhandled effect " (pr-str (.-request eff))))))))
8 changes: 5 additions & 3 deletions src/fell/error.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@
(defn run-error [eff]
(condp instance? eff
Pure (pure (right (extract eff)))
Impure (let [request (.-request eff)
Impure (let [^Impure eff eff
request (.-request eff)
k (partial q/apply-queue (.-cont eff))]
(condp instance? request
Raise (pure (left (.-error request)))
Handle (mlet [status (run-error (.-body request))]
Raise (pure (left (.-error ^Raise request)))
Handle (mlet [^Handle request request
status (run-error (.-body request))]
(condp instance? status
Left (mlet [status (run-error ((.-on_error request) (extract status)))]
(condp instance? status
Expand Down
12 changes: 7 additions & 5 deletions src/fell/lift.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
It is impossible to have more than one lifted monad, so there is no `make` function here."
(:require [cats.core :refer [return bind extract]]
[cats.data :refer [pair]]
[cats.data :refer [pair #?(:cljs Pair)]]
[fell.eff :refer [Effect #?@(:cljs [Pure Impure])]]
[fell.queue :as q]
[fell.core :refer [request-eff]])
#?(:clj (:import [fell.eff Pure Impure])))
#?(:clj (:import [cats.data Pair]
[fell.eff Pure Impure])))

(defrecord Lift [lifted-mv]
Effect
Expand All @@ -17,14 +18,15 @@

(declare run-lift)

(defn- resume-lift [suspension] (run-lift (.-fst suspension) (.-snd suspension)))
(defn- resume-lift [^Pair suspension] (run-lift (.-fst suspension) (.-snd suspension)))

(defn run-lift [ctx eff]
(condp instance? eff
Pure (return ctx (extract eff))
Impure (let [request (.-request eff)
Impure (let [^Impure eff eff
request (.-request eff)
k (partial q/apply-queue (.-cont eff))]
(condp instance? request
Lift (bind (.-lifted_mv request) (q/weave-fn k (pair ctx nil) resume-lift))
Lift (bind (.-lifted_mv ^Lift request) (q/weave-fn k (pair ctx nil) resume-lift))
(throw (#?(:clj RuntimeException., :cljs js/Error.)
(str "unhandled effect " (pr-str (.-request eff)))))))))
3 changes: 2 additions & 1 deletion src/fell/queue.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
(if (seq queue*)
(condp instance? eff
Pure (recur queue* (extract eff))
Impure (Impure. (.-request eff) (into (.-cont eff) queue*)))
Impure (let [^Impure eff eff]
(Impure. (.-request eff) (into (.-cont eff) queue*))))
eff)))

(defn append-handler
Expand Down
15 changes: 9 additions & 6 deletions src/fell/reader.cljc
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
(ns fell.reader
"Reader effect."
(:require [cats.core :refer [mlet fmap]]
[cats.data :refer [pair]]
[cats.data :refer [pair #?(:cljs Pair)]]
[fell.core :refer [request-eff]]
[fell.eff :refer [Effect #?@(:cljs [Pure Impure])]]
[fell.queue :as q])
#?(:clj (:import [fell.eff Pure Impure])))
#?(:clj (:import [cats.data Pair]
[fell.eff Pure Impure])))

(defrecord Ask []
Effect
Expand All @@ -22,16 +23,18 @@

(declare run-reader)

(defn- resume-reader [suspension] (run-reader (.-snd suspension) (.-fst suspension)))
(defn- resume-reader [^Pair suspension] (run-reader (.-snd suspension) (.-fst suspension)))

(defn run-reader [eff env]
(loop [eff eff]
(condp instance? eff
Pure eff
Impure (let [request (.-request eff)
Impure (let [^Impure eff eff
request (.-request eff)
k (partial q/apply-queue (.-cont eff))]
(condp instance? request
Ask (recur (k env))
Local (mlet [v (run-reader (.-body request) ((.-f request) env))]
(run-reader (qk v) env))
Local (mlet [:let [^Local request request]
v (run-reader (.-body request) ((.-f request) env))]
(run-reader (k v) env))
(fell.core/weave eff (pair env nil) resume-reader))))))
12 changes: 7 additions & 5 deletions src/fell/state.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
"State effect."
(:refer-clojure :exclude [get set])
(:require [cats.core :refer [extract]]
[cats.data :refer [pair]]
[cats.data :refer [pair #?(:cljs Pair)]]
[fell.eff :refer [Effect weave #?@(:cljs [Pure Impure])]]
[fell.queue :as q]
[fell.core :refer [pure impure request-eff #?@(:cljs [Pure Impure])]])
#?(:clj (:import [fell.eff Pure Impure])))
#?(:clj (:import [cats.data Pair]
[fell.eff Pure Impure])))

(declare run-state)

Expand All @@ -27,17 +28,18 @@
[value*]
(request-eff (Set. value*)))

(defn- resume-state [suspension] (run-state (.-snd suspension) (.-fst suspension)))
(defn- resume-state [^Pair suspension] (run-state (.-snd suspension) (.-fst suspension)))

(defn run-state
"`(run-state eff state)` runs the State effect in Eff `eff` using `state` as the initial state value."
[eff state]
(loop [state state, eff eff]
(condp instance? eff
Pure (pure (pair state (extract eff)))
Impure (let [request (.-request eff)
Impure (let [^Impure eff eff
request (.-request eff)
k (partial q/apply-queue (.-cont eff))]
(condp instance? request
Get (recur state (k state))
Set (recur (.-new_value request) (k nil))
Set (recur (.-new_value ^Set request) (k nil))
(fell.core/weave eff (pair state nil) resume-state))))))
21 changes: 12 additions & 9 deletions src/fell/writer.cljc
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
(ns fell.writer
(:require [cats.core :refer [mlet fmap mempty mappend extract]]
[cats.context :as ctx]
[cats.data :refer [pair]]
[cats.data :refer [pair #?(:cljs Pair)]]
[fell.core :refer [pure request-eff]]
[fell.eff :refer [Effect #?@(:cljs [Pure Impure])]]
[fell.queue :as q])
#?(:clj (:import [fell.eff Pure Impure])))
#?(:clj (:import [cats.data Pair]
[fell.eff Pure Impure])))

(defrecord Tell [message]
Effect
Expand All @@ -32,20 +33,22 @@
(defn- resume* [output eff]
(condp instance? eff
Pure (pure (pair output (extract eff)))
Impure (let [request (.-request eff)
Impure (let [^Impure eff eff
request (.-request eff)
k (partial q/apply-queue (.-cont eff))]
(condp instance? request
Tell (recur (mappend output (.-message request)) (k nil))
Listen (mlet [result (run (ctx/infer output) (.-body request))
Tell (recur (mappend output (.-message ^Tell request)) (k nil))
Listen (mlet [^Pair result (run (ctx/infer output) (.-body ^Listen request))
:let [output* (.-fst result)]]
(resume* (mappend output output*) (k result)))
Pass (mlet [result (run (ctx/infer output) (.-body request))
Pass (mlet [^Pair result (run (ctx/infer output) (.-body ^Pass request))
:let [output* (.-fst result)
f (.-fst (.-snd result))
v (.-snd (.-snd result))]]
^Pair vs (.-snd result)
f (.-fst vs)
v (.-snd vs)]]
(resume* (mappend output (f output*)) (k v)))
(fell.core/weave eff (pair output nil) resume)))))

(defn- resume [suspension] (resume* (.-fst suspension) (.-snd suspension)))
(defn- resume [^Pair suspension] (resume* (.-fst suspension) (.-snd suspension)))

(defn run [ctx eff] (resume* (mempty ctx) eff))
8 changes: 4 additions & 4 deletions test/fell/core_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@
[cats.core :refer [return bind]]
[fell.eff :refer [context]]
[fell.core :refer :all])
(:import [fell.eff Pure]))
(:import [fell.eff Pure Impure]))

(deftest monad-test
(testing "return"
(let [eff (return context 23)]
(is (instance? Pure eff))
(is (= (.-v eff) 23))))
(is (= (.-v ^Pure eff) 23))))

(testing "bind"
(testing "pure"
(let [eff (bind (pure 23) return)]
(is (= (.-v eff) 23))))
(is (= (.-v ^Pure eff) 23))))

(testing "impure"
(let [eff (bind (request-eff [::foo 23]) return)]
(is (= (.-request eff) [::foo 23]))))))
(is (= (.-request ^Impure eff) [::foo 23]))))))

(deftest request-eff-test
(let [eff (request-eff [::foo 23])]
Expand Down
7 changes: 4 additions & 3 deletions test/fell/eff_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
[cats.core :refer [extract]]
[cats.protocols :refer [-get-context]]
[fell.queue :refer [empty-queue]]
[fell.eff :refer :all]))
[fell.eff :refer :all])
#?(:clj (:import [fell.eff Pure Impure])))

(deftest get-context-test
(are [eff] (= (-get-context eff) context)
Expand All @@ -16,10 +17,10 @@

(deftest flat-map-test
(testing "->Pure"
(let [eff (-flat-map (->Pure 23) ->Pure)]
(let [^Pure eff (-flat-map (->Pure 23) ->Pure)]
(is (= (.-v eff) 23))))

(testing "->Impure"
(let [eff (-flat-map (->Impure [::foo 23] empty-queue) ->Pure)]
(let [^Impure eff (-flat-map (->Impure [::foo 23] empty-queue) ->Pure)]
(is (= (.-request eff) [::foo 23]))
(is (= (.-cont eff) (conj empty-queue ->Pure))))))

0 comments on commit 1c36b58

Please sign in to comment.