Official spec for transformer protocol
See original GitHub issueIssue Description
@swannodette if you recall, this was something I had asked about and while I don’t recall the exact reason for not having a transformer protocol implemented in transducers-js, I do remember there was a reason.
I’ve been thinking about it a bit lately, and I do think it’s worthwhile to be able to define, particularly for JavaScript where it’s much simpler to bake this into the prototype rather than defining as a lookup map of handlers as in transit-js.
As more libraries in JavaScript begin implementing this protocol (this was prompted by @kevinbeaty’s excellent transducer PR on the ramda.js project), I wanted to see if there could be an agreed upon spec for the transformer
before things get too far along.
This is the implementation kicked off by @jlongster
var t = require('./transducers');
Immutable.Vector.prototype[t.protocols.transformer] = {
init: function() {
return Immutable.Vector().asMutable();
},
result: function(vec) {
return vec.asImmutable();
},
step: function(vec, x) {
return vec.push(x);
}
};
For starters - the use of a Symbol('transformer')
is problematic as Symbol()
creates a unique value (Symbol('transformer') !== Symbol('transformer')
), and so you lose any interop when defined independently in multiple libraries.
I’d propose all transformer protocols be implemented as a @@transformer
string (similar to @@iterator
) until if/when the transformer is officially recognized in the well known symbols list.
I’d also propose that the spec behave similarly to an iterator
, in that it is a function which returns the transformer
, rather than as just an object proposed above:
Immutable.Vector.prototype['@@transformer'] = function() {
return {
init: function() {
return new Immutable.Vector().asMutable();
},
result: function(vec) {
return vec.asImmutable();
},
step: function(vec, x) {
return vec.push(x);
}
};
}
This makes the implementation more useful, as it can refer to the current object in the init
to know what value makes to init
, should the object be subclassed:
SomeObject.prototype['@@transformer'] = function() {
var obj = this;
return {
init: function() {
return new obj.constructor()
},
step: function(result, arr) {
return result.set(arr[0], arr[1]);
},
result: function(obj) {
return obj;
}
};
}
Issue Analytics
- State:
- Created 8 years ago
- Comments:38 (14 by maintainers)
@tgriesser @kevinbeaty
Seems to me the logic should be more like the following:
Globally stealing names seems like a really bad idea.
https://github.com/gozala/transducers also uses this interface 😉