Last active
October 16, 2023 15:55
-
-
Save telekid/5dc697553adad1f0251a7b2439a39f12 to your computer and use it in GitHub Desktop.
rama koans
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns hypo.server.reg | |
(:use [com.rpl.rama] | |
[com.rpl.rama.path]) | |
(:require [com.rpl.rama :as r] | |
[com.rpl.rama.test :as rtest] | |
[hyperfiddle.rcf :as rcf])) | |
(rcf/tests | |
"operations output to streams" | |
(deframaop one [] | |
(:> "foo")) | |
(?<- (one :> *a) | |
(tap *a)) | |
% := "foo" | |
"an operation can emit to the same stream more than once" | |
(deframaop two [] | |
(:> "foo") | |
(:> "bar")) | |
(?<- (two :> *a) | |
(tap ["a" *a])) | |
% := ["a" "foo"] | |
% := ["a" "bar"] | |
"a stream can accept multiple values, analagous to an n-ary function" | |
(deframaop three [] | |
(:> "foo" "bar")) | |
(?<- (three :> *a *b) | |
(tap ["a" *a]) | |
(tap ["b" *b])) | |
% := ["a" "foo"] | |
% := ["b" "bar"] | |
"the above two properties can be combined – here, the :> stream is invoked twice, each time with two values" | |
(deframaop four [] | |
(:> "foo" "bar") | |
(:> "foo" "bar")) | |
(?<- (four :> *a *b) | |
(tap ["a" *a]) | |
(tap ["b" *b])) | |
% := ["a" "foo"] | |
% := ["b" "bar"] | |
% := ["a" "foo"] | |
% := ["b" "bar"] | |
"an operation can emit to multiple streams, which can be named whatever you'd like as long as they are in the form :foo>" | |
(deframaop five [] | |
(:one> "foo") | |
(:two> "bar")) | |
"nodes can be labeled with anchors" | |
;; For ops that define multiple output streams, the hook> expression | |
;; says "for the following forms, variables should be bound in the context | |
;; of the anchor specified as the argument to hook>" | |
(?<- (five :one> <a> *x :two> <b> *x) | |
(hook> <a>) | |
(tap ["first" *x]) | |
(hook> <b>) | |
(tap ["second" *x])) | |
% := ["first" "foo"] | |
% := ["second" "bar"] | |
"there exists a notion of a current node" | |
(?<- (five :one> <a> *x | |
;; Note that the following output stream is not currently labeled | |
;; by an anchor. I think of this as an anonymous node. Every time | |
;; a node is created, it becomes the "current" node. When a context | |
;; is not specified by <hook>, it defaults to the current node, | |
;; which explains why "first" will print at all. | |
:two> *x) | |
(tap ["first" *x]) | |
(hook> <a>) | |
(tap ["second" *x])) | |
;; Question: Why is the order reversed here? | |
;; Answer: because `five` emits to `:one>` before it emits to `:two>` | |
% := ["second" "foo"] | |
% := ["first" "bar"] | |
"use `anchor>` to name a node" | |
(?<- (five :one> <a> *x | |
:two> *x) | |
;; :two> is being redirected to an unnamed node. Let's | |
;; name that node <moo> | |
(anchor> <moo>) | |
(hook> <a>) | |
(tap ["first" *x]) | |
(hook> <moo>) | |
(tap ["second" *x])) | |
% := ["first" "foo"] | |
% := ["second" "bar"] | |
;; However, I'm not sure why you would do this instead of just labeling | |
;; the anchor during invocation. | |
"`unify>` joins nodes together" | |
(?<- (five :one> <a> *x | |
:two> <b> *x) | |
(unify> <a> <b>) | |
(tap ["together" *x])) | |
% := ["together" "foo"] | |
% := ["together" "bar"]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment