Skip to content

Instantly share code, notes, and snippets.

@telekid
Last active October 16, 2023 15:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save telekid/5dc697553adad1f0251a7b2439a39f12 to your computer and use it in GitHub Desktop.
Save telekid/5dc697553adad1f0251a7b2439a39f12 to your computer and use it in GitHub Desktop.
rama koans
(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