-
Notifications
You must be signed in to change notification settings - Fork 0
Channels for communicating sequential processes #10
base: master
Are you sure you want to change the base?
Conversation
I feel this needs some expansion:
What I mean by this, is that something like Essentially this means the |
@@ -0,0 +1,4 @@ | |||
module.exports = chan | |||
|
|||
function chan() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looking forward to this one :)
It might be tricky to implement take/put/filter/map etc in such a way that they are seq/chan agnostic (which is to say, they are sync/async agnostic) but it's worth researching how that can be done. |
@sammyt what should happen when you do this? Seq = defprotocol({
first : []
, rest : []
})
const nums = [1, 2, 3]
Seq(nums, { // Notice the first argument is the `nums` array, not a "type"
first: function(arr) { return arr[0] }
, rest: function(arr) { return arr.slice(1) }
})
Seq.first(nums) // 1
Seq.rest(nums) // [2, 3]
Seq.first([3, 2, 1]) // ??? Should |
Or should |
I also would say the object itself, else to much magic |
How would I define the protocol implementation for the following "data structure" var Node = function(data, left, right){
this.data = data
this.left = left
this.right = right
} Such that any |
Presumably, it'd be something like this: Seq(Node, {
first: function(n) { return n.data }
, rest: function(n) { return n.right }
})
var someNode = new Node(1)
Seq.first(someNode) // 1
Seq.rest(someNode) // undefined When invoking, we'd do an Not sure about using the protocol itself as the implementation mechanism... If you wanted a tree view out of your node, you could have some syntax like this: var tree = Seq(someNode)
tree.first() // 1
tree.rest() // undefined Basically, any protocol given two arguments means implementation; given just the one argument would mean a wrapped instance which is just sugar for |
That's a nice and presumptuous implementation that'll let you traverse any tree in any direction, so long as it's right. :o) |
a182851
to
ff805e8
Compare
d68c398
to
4709d45
Compare
Coverage decreased (-6.82%) when pulling 4709d455fc58450691f075cbbe30a570f1b05cdc on chan into 2dc3288 on master. |
`defprop` is used to define properties on objects, and is the king of mutability. It's useful though for low level mechanics in implementing abstractions, and provides a cleaner API than `Object.defineProperties`.
`is(x, x)` could return false if `x` is an object
N.b.: If you do `Object.create(function() {}, {})`, the resulting object will have a constructor set, but not to the prototype function and I have no idea what indeed it gets set to. Might be worth investigating.
Hint: there is no coverage of `defprotocol`. Write some tests, man.
Damn gamification makes me want to achieve 100% coverage. I'm so easy..
This should probably change to something better, such as a **/*.api.js or something such that it's possible to have files explicitly marked public and others that would be considered private.
This probably needs tests.
Build fails because travis-ci/travis-ci#3108. Change config to use iojs whenever that gets sorted, or change to Wercker or something. |
Travis added support for iojs finally, and so all is suddenly well. :o) |
Starting this PR as a WIP on channels. This work will likely also include – or depend on – protocols, multiple/predicate dispatch, and futures.
Channels are a nice way to provide an abstraction for processes communicating with one another. They act a lot like sequences, with the exception that values may not be immediately available. As such, there's a need to find a useful abstraction for future values. Promises as they are specified in ES6 are an over engineered mess, and while they may well be supported as return values for non-blocking channels, they probably shouldn't be the recommended mechanism.
One thing I'd like to accomplish with channels is to make them act largely the same as sequences – that is, they are a view on to a data structure. The main difference however, is that sequences are blocking and immediate, so when realizing a value (i.e. calling
rest
orfirst
) that value is immediately available. Of course, the value may be a future, meaning the consumer will have to add a function to be called once the future value is available. (Which may be immediately, in which case the future is effectively the same asconstantly
.) The benefit of this is that function such astake
,map
, etc. works regardless of what, where, or when the structure is available. To make for nice syntax, something similar to Clojure'sgo
blocks make sense. Here's a contrived mockup:In this example,
tick
andlog
are channels that are used ingo
block which takes care of the boilerplate of dealing with futures returned fromyield take(1, tick)
. Using sequences like this implies that the sequence is fully realized before the execution is resumed. This may be magical, and some care might be required to deal with it. Here's another example, where an infinite channel is used:The imaginary
draw
function is used to output pixels on to a canvas (this, as it were, could also be a channel, but I'm choosing to not go the shiny-hammer route just yet) by virtue of taking 4 points and making a Bézier curve out of them.In both of these mockups, generators are used to suspend execution. Since funkis is largely a research project, I don't think there's much need to limit it to ES5 environments. Should that be the case however, it may be worth looking into something like degenerate.
A benefit to using something like
go
blocks is that routines can be made into values to pass around and compose. Here's an expansion of the drawing mockup above:This is a mockup, so there are a bunch of assumptions made (like, what's
random
,draw
etc.?) but it ought to show the general direction in which I hope this work will go. The idea is to have a simple abstraction of a sequence of values, where not only is the underlying data structure not important but neither is the point in time when values are available.Work in progress, so things are bound to change, but this marks a start.