{"action":"created","issue":{"url":"https://api.github.com/repos/cognitect-labs/transducers-js/issues/20","labels_url":"https://api.github.com/repos/cognitect-labs/transducers-js/issues/20/labels{/name}","comments_url":"https://api.github.com/repos/cognitect-labs/transducers-js/issues/20/comments","events_url":"https://api.github.com/repos/cognitect-labs/transducers-js/issues/20/events","html_url":"https://github.com/cognitect-labs/transducers-js/issues/20","id":60769824,"number":20,"title":"Official spec for transformer protocol","user":{"login":"tgriesser","id":154748,"avatar_url":"https://avatars.githubusercontent.com/u/154748?v=3","gravatar_id":"","url":"https://api.github.com/users/tgriesser","html_url":"https://github.com/tgriesser","followers_url":"https://api.github.com/users/tgriesser/followers","following_url":"https://api.github.com/users/tgriesser/following{/other_user}","gists_url":"https://api.github.com/users/tgriesser/gists{/gist_id}","starred_url":"https://api.github.com/users/tgriesser/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tgriesser/subscriptions","organizations_url":"https://api.github.com/users/tgriesser/orgs","repos_url":"https://api.github.com/users/tgriesser/repos","events_url":"https://api.github.com/users/tgriesser/events{/privacy}","received_events_url":"https://api.github.com/users/tgriesser/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":20,"created_at":"2015-03-12T04:30:23Z","updated_at":"2015-03-19T20:30:59Z","closed_at":null,"body":"@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.\r\n\r\nI'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.\r\n\r\nAs more libraries in JavaScript begin implementing this protocol (this was prompted by @kevinbeaty's [excellent transducer PR](https://github.com/ramda/ramda/pull/878) 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.\r\n\r\nThis is the implementation kicked off by @jlongster\r\n\r\n```js\r\nvar t = require('./transducers');\r\nImmutable.Vector.prototype[t.protocols.transformer] = {\r\n  init: function() {\r\n    return Immutable.Vector().asMutable();\r\n  },\r\n  result: function(vec) {\r\n    return vec.asImmutable();\r\n  },\r\n  step: function(vec, x) {\r\n    return vec.push(x);\r\n  }\r\n};\r\n```\r\n\r\nFor 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.\r\n\r\nI'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](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-well-known-symbols).\r\n\r\nI'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:\r\n\r\n```js\r\nImmutable.Vector.prototype['@@transformer'] = function() {\r\n  return {\r\n    init: function() {\r\n      return new Immutable.Vector().asMutable();\r\n    },\r\n    result: function(vec) {\r\n      return vec.asImmutable();\r\n    },\r\n    step: function(vec, x) {\r\n      return vec.push(x);\r\n    }\r\n  };\r\n}\r\n```\r\n\r\nThis 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:\r\n\r\n```js\r\nSomeObject.prototype['@@transformer'] = function() {\r\n  var obj = this;\r\n  return {\r\n    init: function() {\r\n      return new obj.constructor()\r\n    },\r\n    step: function(result, arr) {\r\n      return result.set(arr[0], arr[1]);\r\n    },\r\n    result: function(obj) {\r\n      return obj;\r\n    }    \r\n  };\r\n}\r\n```"},"comment":{"url":"https://api.github.com/repos/cognitect-labs/transducers-js/issues/comments/83753064","html_url":"https://github.com/cognitect-labs/transducers-js/issues/20#issuecomment-83753064","issue_url":"https://api.github.com/repos/cognitect-labs/transducers-js/issues/20","id":83753064,"user":{"login":"swannodette","id":13516,"avatar_url":"https://avatars.githubusercontent.com/u/13516?v=3","gravatar_id":"","url":"https://api.github.com/users/swannodette","html_url":"https://github.com/swannodette","followers_url":"https://api.github.com/users/swannodette/followers","following_url":"https://api.github.com/users/swannodette/following{/other_user}","gists_url":"https://api.github.com/users/swannodette/gists{/gist_id}","starred_url":"https://api.github.com/users/swannodette/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/swannodette/subscriptions","organizations_url":"https://api.github.com/users/swannodette/orgs","repos_url":"https://api.github.com/users/swannodette/repos","events_url":"https://api.github.com/users/swannodette/events{/privacy}","received_events_url":"https://api.github.com/users/swannodette/received_events","type":"User","site_admin":false},"created_at":"2015-03-19T20:30:59Z","updated_at":"2015-03-19T20:30:59Z","body":"@jlongster but that's obviously broken right if not handled carefully? If you wrap your value in your own Reduced how can a different transducer from a different library detect it and extract the value?"}}