tur/arrow
arrow combinators over the (->) function arrow, in two surfaces.
Since: Phase CA0
arr
(arr [^fat f])
lift a function to an arrow (identity for function arrows).
| f | the function to lift |
The function itself.
(arr (fn [x] (+ x 1))) ; => identity for functions
>>>
(>>> [A B C])
compose two function arrows sequentially (register-class-correct).
| f | first arrow (A -> B) | |
| g | second arrow (B -> C) |
A ptr<void> closure (A -> C) that applies f then g.
((>>> (fn [x : float] : float (+ x 1.0))
(fn [x : float] : float (* x 2.0))) 3.0) ; => 8.0
Since: Phase CA1
arrow-first
(arrow-first [^fat f])
apply a function to the first component of a Tuple2.
| f | function to apply |
A function on Tuple2 that applies f to the first field.
((arrow-first (fn [x] (+ x 1))) <heap Tuple2 (5, 10)>) ; => Tuple2(6, 10)
arrow-second
(arrow-second [^fat f])
apply a function to the second component of a Tuple2.
| f | function to apply |
A function on Tuple2 that applies f to the second field.
((arrow-second (fn [x] (+ x 1))) <heap Tuple2 (5, 10)>) ; => Tuple2(5, 11)
par-comp
(par-comp [a b c d ^fat f ^fat g])
parallel composition of two functions on Tuple2 types.
| f | function a -> b | |
| g | function c -> d |
A function on Tuple2 a c -> Tuple2 b d: (par-comp f g)(tuple2 x y) = tuple2(f x, g y).
((par-comp inc double) (tuple2 1 2)) ; => Tuple2(2, 4)
arrow-split
(arrow-split [a b c ^fat f ^fat g])
duplicate input and apply two functions, returning a Tuple2.
| f | function a -> b | |
| g | function a -> c |
A function a -> Tuple2 b c: (arrow-split f g)(x) = tuple2(f x, g x).
((arrow-split inc double) 3) ; => Tuple2(4, 6)
arrow-const
(arrow-const [v])
arrow that ignores its input and always returns v.
| v | the constant value to return |
An arrow (any -> v).
((arrow-const 42) 999) ; => 42
Since: Phase B2
arrow-dup
(arrow-dup [x] :)
arrow that duplicates its input into a Tuple2.
| x | the value to duplicate |
A Tuple2 of x with itself: Tuple2(x, x).
(tuple2-1st (arrow-dup 7)) ; => 7
Since: Phase B2
LoopCell
(LoopCell)
the fed-back `d` slot of an ArrowLoop, as a handle.
Since: arrowloop-lazy-feedback
loop-cell-of
(loop-cell-of [slot : int] :)
read slot 1 of an ArrowLoop input pair as a LoopCell.
| slot | the erased slot-1 value handed to the looped arrow |
The same handle, typed as a LoopCell.
(loop-cell-force (loop-cell-of d)) ; => the fed-back value
Since: arrowloop-lazy-feedback
loop-cell-ready?
(loop-cell-ready? [c : LoopCell] :)
has the fed-back value been written yet?
| c | the feedback cell |
true when loop-cell-force would succeed, false when it would black-hole.
(if (loop-cell-ready? c) (loop-cell-force c) 0)
Since: arrowloop-lazy-feedback
loop-cell-force
(loop-cell-force [c : LoopCell] :)
read the fed-back value out of a feedback cell.
| c | the feedback cell |
The fed-back d value, in the erased arrow carrier.
(let [lp (arrow-loop step)]
(loop-cell-force (loop-cell-of (lp 7))))
Since: arrowloop-lazy-feedback
Arrow[]
(definstance Arrow [])
the function arrow: arr is the identity (a plain function
ArrowChoice[]
(definstance ArrowChoice [])
map an arrow over one arm of an Either, passing the
ArrowLoop[f]
(definstance ArrowLoop [f])
lazy (knot-tying) feedback: run the arrow on
arrow-loop-lazy
(arrow-loop-lazy [^fat f] :)
the bare-surface twin of the ArrowLoop [(->)] instance.
| f | the looped arrow, a (b, LoopCell) -> (c, d) over the heap-pair layout |
A ptr<void> closure b -> c.
;; f parks the cell in c, so forcing c after the loop yields d = b * 10.
(let [lp (arrow-loop-lazy park-cell-step)]
(loop-cell-force (loop-cell-of (lp 7)))) ; => 70
Since: arrowloop-lazy-feedback
arrow-loop-fix
(arrow-loop-fix [^fat f d0 : int fuel : int] :)
feedback by iteration to a fixpoint.
| f | the looped arrow, a (b, LoopCell) -> (c, d) | |
| d0 | the seed for the fed-back component | |
| fuel | maximum iterations; anything below 1 runs exactly one pass |
A ptr<void> closure b -> c.
;; newton-step: d' = (d + b/d)/2, c = d -- integer sqrt by fixpoint. ((arrow-loop-fix newton-step 1 32) 144) ; => 12
Since: arrowloop-lazy-feedback
arrow-loop-delay
(arrow-loop-delay [^fat f d0 : int] :)
feedback through a unit delay (step-indexed).
| f | the looped arrow, a (b, LoopCell) -> (c, d) | |
| d0 | the value the first call sees fed back |
A ptr<void> closure b -> c, carrying its own feedback state.
;; sum-step: d' = d + b, c = d + b -- a running total.
(let [acc (arrow-loop-delay sum-step 0)]
(acc 1) (acc 2) (acc 3)) ; => 1, 3, 6
Since: arrowloop-lazy-feedback
ArrowApply[p]
(definstance ArrowApply [p])
the apply arrow: run the arrow in slot 0 on slot 1.
Category[]
(definstance Category [])
the function arrow: `ident` is the plain identity
Internal definitions
__arrow_pair_first-- inline-C: apply fv to e1 of a heap pair *p,__arrow_pair_second-- inline-C: apply fv to e2 of a heap pair *p,__arrow_pair_par-- inline-C: apply fv to e1 and gv to e2 of *p.__arrow_pair_split-- inline-C: produce a heap pair from (fv x, gv x).__arrow_pair_dup-- inline-C: produce a heap pair with both fields = x.__ac_pair_first-- inline-C: apply fv to slot 0 of a heap pair, copy slot 1.__ac_pair_second-- inline-C: copy slot 0 of a heap pair, apply fv to slot 1.__ac_cell_new-- inline-C: allocate a feedback cell, filled or empty.__ac_loop_step-- inline-C: the lazy (knot-tying) ArrowLoop step. Allocate__ac_loop_fix_step-- inline-C: the strict fixpoint ArrowLoop step. Seed a__ac_loop_delay_step-- inline-C: one step of the unit-delay ArrowLoop. The__ac_app-- inline-C: ArrowApply for (->). The input pair carries an arrow