{"action":"created","issue":{"url":"https://api.github.com/repos/GWTReact/gwt-interop-utils/issues/1","repository_url":"https://api.github.com/repos/GWTReact/gwt-interop-utils","labels_url":"https://api.github.com/repos/GWTReact/gwt-interop-utils/issues/1/labels{/name}","comments_url":"https://api.github.com/repos/GWTReact/gwt-interop-utils/issues/1/comments","events_url":"https://api.github.com/repos/GWTReact/gwt-interop-utils/issues/1/events","html_url":"https://github.com/GWTReact/gwt-interop-utils/issues/1","id":158332559,"number":1,"title":"What you call “Object literals” aren't, this is misleading; find another name.","user":{"login":"tbroyer","id":173813,"avatar_url":"https://avatars.githubusercontent.com/u/173813?v=3","gravatar_id":"","url":"https://api.github.com/users/tbroyer","html_url":"https://github.com/tbroyer","followers_url":"https://api.github.com/users/tbroyer/followers","following_url":"https://api.github.com/users/tbroyer/following{/other_user}","gists_url":"https://api.github.com/users/tbroyer/gists{/gist_id}","starred_url":"https://api.github.com/users/tbroyer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tbroyer/subscriptions","organizations_url":"https://api.github.com/users/tbroyer/orgs","repos_url":"https://api.github.com/users/tbroyer/repos","events_url":"https://api.github.com/users/tbroyer/events{/privacy}","received_events_url":"https://api.github.com/users/tbroyer/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2016-06-03T09:59:25Z","updated_at":"2016-06-03T19:17:48Z","closed_at":null,"body":"“Literals” are a syntactic construct, with few if any impact at runtime. Actually, even the ECMAScript spec doesn't call them “literals”, but “initializers”:\r\n\r\n> An object initializer is an expression describing the initialization of an Object, written in a form resembling a literal.\r\n\r\n— Source: http://www.ecma-international.org/ecma-262/5.1/index.html#sec-11.1.5 & http://www.ecma-international.org/ecma-262/6.0/index.html#sec-object-initializer\r\n\r\nFrom the gwt-interop-utils documentation:\r\n\r\n> Many javascript libraries make extensive use of object literals (`{a : 10, b : \"Some value\"}`) to pass parameters and return results.\r\n\r\nLibraries themselves don't make use of object literals (_object initializers_); developers using them make use of object initializers. Libraries take objects as method parameters, and developers choose to use object initializers to fulfill them.  \r\n(I'm obviously not talking about the usage _inside_ the library, which is irrelevant to this discussion)\r\n\r\nFrom the library's side, the method receives an object; and the library cannot really tell (possibly even can't actually tell at all, I haven't studied the ECMAScript spec enough, but anyway it'd be through “hacks”) whether the received object has been constructed using an “object initializer” construct or not.  \r\nI.e., inside the library, the following two snippets cannot be distinguished:\r\n\r\n```js\r\nlibrary.fn({a: 10, b: \"Some value\"});\r\n// vs.\r\nlibrary.fn((function() { var o = new Object(); o.a = 10; o.b = \"Some value\"; return o; })());\r\n```\r\n\r\nActually, you specifically rely this to construct objects the latter way rather than the former.\r\n\r\nSo please use another name than “object literal”. The only thing `ObjLiteral` (or the recommended `@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = \"Object\")` on custom types) does is to make sure the object is of the \"raw `Object` type\", or in other words, that its `constructor` is `$wnd.Object` (and that in turns it has an undefined `prototype`).  \r\nAnd even this should be the exception rather than the norm: libraries should in most cases accept any object, whichever its constructor, as long as it's not an `Array.isArray()`. Your use case is driven by some obscure React/Redux limitation (could you point me to the actual methods failing when passing objects whose constructor is not `Object`?) that aren't the “norm” (to my knowledge) in the JS ecosystem.\r\n\r\nMay I suggest using _raw object_ or _simple object_ instead?\r\n\r\nAlso, BTW, `ObjLiteral` is not much different from `StringMap`, the main exception being that it's not typed; similar to the `com.google.gwt.core.client.JsArray` flavors vs. `com.google.gwt.core.client.JsArrayMixed`.\r\n\r\nThere *is* a way to make real object initializers with GWT 2.8 (pending support in GWT proper) using JSNI and without the need for any helper library:\r\n\r\n```java\r\npublic native WhateverTheFunctionExpects create(int a, String b) /*-{\r\n  return { a: a, b: b };\r\n}-*/;\r\n```\r\n\r\nand you could possibly make it easier to write through an annotation processor to generate the JSNI code (e.g., for each `@JsType(isNative = true)`, generate a `<TypeName>_Factory` class with static factory methods for each “property-presence” permutation (so I could have a `create(int a)` and `create(String b)` in addition to `create(int a, String b)`; and when there are multiple parameters of the same type, use specific method names to disambiguate them, e.g. `createWithA(int a)` and `createWithA(int a, String b)` vs. `createWithC(int c)` and `createWithC(String b, int c)` vs. `create(int a, String b, int c)`)."},"comment":{"url":"https://api.github.com/repos/GWTReact/gwt-interop-utils/issues/comments/223669081","html_url":"https://github.com/GWTReact/gwt-interop-utils/issues/1#issuecomment-223669081","issue_url":"https://api.github.com/repos/GWTReact/gwt-interop-utils/issues/1","id":223669081,"user":{"login":"hrstoyanov","id":5327044,"avatar_url":"https://avatars.githubusercontent.com/u/5327044?v=3","gravatar_id":"","url":"https://api.github.com/users/hrstoyanov","html_url":"https://github.com/hrstoyanov","followers_url":"https://api.github.com/users/hrstoyanov/followers","following_url":"https://api.github.com/users/hrstoyanov/following{/other_user}","gists_url":"https://api.github.com/users/hrstoyanov/gists{/gist_id}","starred_url":"https://api.github.com/users/hrstoyanov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hrstoyanov/subscriptions","organizations_url":"https://api.github.com/users/hrstoyanov/orgs","repos_url":"https://api.github.com/users/hrstoyanov/repos","events_url":"https://api.github.com/users/hrstoyanov/events{/privacy}","received_events_url":"https://api.github.com/users/hrstoyanov/received_events","type":"User","site_admin":false},"created_at":"2016-06-03T19:17:48Z","updated_at":"2016-06-03T19:17:48Z","body":"@tbroyer \r\n\r\nGood points!\r\n\r\nMay I suggest to avoid the [telescoping arguments anti-pattern](http://stackoverflow.com/questions/328496/when-would-you-use-the-builder-pattern), so widely used and encouraged in the  JS community for constructing objects, and use [Builders ](https://en.wikipedia.org/wiki/Builder_pattern) instead. Here is an example from wrapping Google Analytics (I will publish it soon):\r\n[Google Analytics](https://developers.google.com/analytics/devguides/collection/analyticsjs/social-interactions) JS API: \r\n```javascript\r\nga('send', 'social', [socialNetwork], [socialAction], [socialTarget], [fieldsObject]);\r\n```\r\nJsInterop API user would be able to do this (very readable, less error prone, well typed):\r\n```java\r\n// Rgeister social network event in google analytics and construct complex object with builders\r\nnew SocialInteraction.Builder()\r\n           .withSocialNetwork(\"facebook\")\r\n           .withSocialAction(\"liked\")\r\n           .withSocialTarget(\"whatever\")\r\n.register();\r\n```\r\n\r\n\r\nJsInterop code wrapper:\r\n```java\r\n@JsType(isNative = true, namespace = JsPackage.GLOBAL)\r\npublic class SocialInteraction extends GoogleAnalyticsCommand{\r\n\r\n    @JsProperty\r\n    public String socialNetwork;\r\n\r\n    @JsProperty\r\n    public String socialAction;\r\n\r\n    @JsProperty\r\n    public String socialTarget;\r\n\r\n    public static class Builder extends BaseBuilder<Builder>{\r\n\r\n       final  private SocialInteraction socialInteraction = new SocialInteraction();\r\n\r\n        public Builder withSocialNetwork(String socialNetwork) {\r\n            socialInteraction.socialNetwork = socialNetwork;\r\n            return this;\r\n        }\r\n\r\n        public Builder withSocialAction(String socialAction) {\r\n            socialInteraction.socialAction = socialAction;\r\n            return this;\r\n        }\r\n\r\n        public Builder withSocialTarget(String socialTarget) {\r\n            socialInteraction.socialTarget = socialTarget;\r\n            return this;\r\n        }\r\n\r\n        @Override\r\n        public void register() {\r\n            Objects.requireNonNull(socialInteraction.socialNetwork, \"socialNetwork cannot be empty\");\r\n            Objects.requireNonNull(socialInteraction.socialAction,  \"socialAction cannot be empty\");\r\n            Objects.requireNonNull(socialInteraction.socialAction,  \"socialTarget cannot be empty\");\r\n            if (Variables.isFunctionDefined(\"ga\")) {\r\n                socialInteraction.hitType = \"social\";\r\n                GoogleAnalytics.ga(buildSendCommand(), socialInteraction);\r\n            }\r\n        }\r\n    }\r\n\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n"}}
{"actor":{"display_login":"hrstoyanov"}}