Skip to content

Instantly share code, notes, and snippets.

@desaperados
Created December 8, 2016 23:01
Show Gist options
  • Save desaperados/70570ed6d0786a6faf0ace92913a5c90 to your computer and use it in GitHub Desktop.
Save desaperados/70570ed6d0786a6faf0ace92913a5c90 to your computer and use it in GitHub Desktop.
(defActor RHOPattern)
(defOprn match?)
(defOprn miss?)
(defActor NameSpace)
(defOprn chart)
(defOprn consume)
(defOprn subscribe)
(defOprn read)
(defOprn fetch)
(defOprn produce)
(defOprn publish)
(defOprn production?)
(defOprn consumer?)
(defRMethod NameSpace (consume ctxt & location)
(letrec [[[channel ptrn] location]
[subspace (tbl-get chart channel)]
[candidates (names subspace)]
[[extractions remainder]
(fold [e acc k]
(let [[[hits misses] acc]
[binding (match? ptrn e)]]
(if (miss? binding)
(k [hits [e & misses]])
(k [[[e binding] & hits] misses]))))]
[[productions consummation]
(fold extractions
(proc [[e binding] acc k]
(let [[[productions consumers] acc]
[hit (tbl-get subspace e)]]
(if (production? hit)
(k [[[[e binding] hit] & productions] consumers])
(k [productions [[e hit] & consumers]])))))]]
(map productions
(proc [[[ptrn binding] product]]
(delete subspace ptrn)))
(map consummation
(proc [[ptrn consumers]]
(tbl-add subspace
ptrn (reverse [ctxt & (reverse consumers)]))))
(update!)
(ctxt-rtn ctxt productions)))
(defRMethod NameSpace (produce ctxt & production)
(letrec [[[channel ptrn product] production]
[subspace (tbl-get chart channel)]
[candidates (names subspace)]
[[extractions remainder]
(fold [e acc k]
(let [[[hits misses] acc]
[binding (match? ptrn e)]]
(if (miss? binding)
(k [[e & hits] misses])
(k [hits [e & misses]]))))]
[[productions consummation]
(fold extractions
(proc [[e binding] acc k]
(let [[[productions consumers] acc]
[hit (tbl-get subspace e)]]
(if (production? hit)
(k [[[e hit] & productions] consumers])
(k [productions [[[e binding] hit] & consumers]])))))]]
(map productions
(proc [[ptrn prod]] (tbl-add subspace ptrn product)))
(map consummation
(proc [[[ptrn binding] consumers]]
(delete subspace ptrn)
(map proc [consumer] (send ctxt-rtn consumer [product binding]))))
(update!)
(ctxt-rtn ctxt #niv)))
(defActor LocalNameSpace
(extends& NameSpace)
(slots& space (new RblTable)))
(defMethod LocalNameSpace (chart & selector)
(if (null? selector)
space
(tbl-get space (hd selector))))
@desaperados
Copy link
Author

desaperados commented Dec 8, 2016

Here's how to read the code above:

There's an actor, called a NameSpace, supporting a protocol for storing and retrieving data from abstract locations made from channels and patterns. The retrieval mechanism uses a reflective method, meaning that it has direct access to the current thread of computation represented as an actor. When a consume request containing a channel and a pattern comes into a NameSpace actor, it checks its local store for channels and patterns that match. A match hit produces a binding for the incoming pattern with the pattern in the local store acting as the access key. All such hits are returned by invoking the continuation to resume computation. If there are no hits, the continuation will be stored at the matching channel/pattern locations in the store for the moment when data arrives. Dually, when a client makes a request to store data in the NameSpace a similar check for matching locations is made. This time if there are any awaiting consumer continuations, then they are invoked with data supplied by the storage request. Alternatively, the locations defined by the storage requests channel and pattern are updated with the data to be store. Notice that for the operations consume and produce, when a storage request meets up with a consumption request the data and continuation are both removed. To get the other verb semantics simply vary either the persisted/ephemeral quality of the continuation and/or that data. Again, the difference between the local-only implementation (roughly equivalent to 'colocated' mode for GLoSEval in the SpecialK stack) and the distributed implementation is that the implementation of chart LocalNameSpace is replaced with a map from patterns to AMQP queues.

The difference between that and one with persisted storage is that the implementation of chart in LocalNameSpace is replaced with a map from patterns to pairs, consisting of local "tables" (i.e. relational table, nosql document, etc) and queues.

Also, it is worth reiterating how much going through Rosette makes expressing these semantics much, much more compact.

It's much easier to see and understand the logic. This is why it is much, much more cost effective to address the technical debt of SpecialK by replacing the older, buggy libraries in Scala with older libraries in Rosette.

To get the byte code for the VM, just (code-dump (compile )) where is taken from the code above.

As mentioned above, this code is the "trampoline" to create the compiler from rholang to the RosetteVM. It's the core piece of runtime target that must be present in addition to the Rosette VM to facilitate a correct translation from the rho-calculus semantics to the actor-model semantics of the Rosette VM.

The remainder of the compiler follows directly from the image at the end of the rholang spec

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment