{"action":"opened","issue":{"url":"https://api.github.com/repos/pandastrike/fairmont-helpers/issues/13","labels_url":"https://api.github.com/repos/pandastrike/fairmont-helpers/issues/13/labels{/name}","comments_url":"https://api.github.com/repos/pandastrike/fairmont-helpers/issues/13/comments","events_url":"https://api.github.com/repos/pandastrike/fairmont-helpers/issues/13/events","html_url":"https://github.com/pandastrike/fairmont-helpers/issues/13","id":114384757,"number":13,"title":"Should Type.define and Type.create take optional objects","user":{"login":"dyoder","id":1859,"avatar_url":"https://avatars.githubusercontent.com/u/1859?v=3","gravatar_id":"","url":"https://api.github.com/users/dyoder","html_url":"https://github.com/dyoder","followers_url":"https://api.github.com/users/dyoder/followers","following_url":"https://api.github.com/users/dyoder/following{/other_user}","gists_url":"https://api.github.com/users/dyoder/gists{/gist_id}","starred_url":"https://api.github.com/users/dyoder/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dyoder/subscriptions","organizations_url":"https://api.github.com/users/dyoder/orgs","repos_url":"https://api.github.com/users/dyoder/repos","events_url":"https://api.github.com/users/dyoder/events{/privacy}","received_events_url":"https://api.github.com/users/dyoder/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-10-31T03:40:12Z","updated_at":"2015-10-31T03:40:12Z","closed_at":null,"body":"For `define`, the idea would be that you provide an object whose prototype will be set. Right now, we just return you a new object with a `prototype` property. This allows you to say “create a type based on this object.”\r\n\r\nFor `create`, the idea is to initialize a newly created object with the properties of the given object. Right now, we just create a vanilla object. This allows you to say “create a new object of this type based on this object.”\r\n\r\nA strong counter-argument for both of these is that you can already simply use `include`. Adding the additional argument is arguably (sorry!) _less_ expressive, since you're confusing the semantics a bit.\r\n\r\nFor `define`, the counter argument is that you sometimes want to refer to properties of the type from within the type's properties. For example:\r\n\r\n```\r\nBar = define Foo\r\ninclude Bar,\r\n  isBar: isType Bar\r\n```\r\n\r\nFor `create`, the counter argument is that you don't always want to allow for initialization based on an arbitrary object. This is particularly true if you're counting on resolving some values via the prototype.\r\n\r\nHere's an example where we allow for passing an initializer object, which hides a value from the prototype. Actually, it might not hide it if we use `include`, because `include` just uses assignment.\r\n\r\n```\r\nFoo = define()\r\ninclude Foo,\r\n  apples: 7\r\n\r\nBar = define Foo\r\nbar = create Bar,\r\n  apples: 3\r\n```\r\n\r\nBut the murkiness of this is sort of the point. At least with `include` we're being explicit. And, going back to the first point, since you can already do this anyway with `include`, why bother?\r\n\r\n```\r\nBar = define Foo\r\nbar = create Bar\r\ninclude bar,  apples: 3\r\n```\r\n\r\nFor the moment, I'm going to hold off on adding any further complexity to these functions. But we should revisit this."}}