{"action":"created","issue":{"url":"https://api.github.com/repos/HaxeFoundation/haxe/issues/5897","repository_url":"https://api.github.com/repos/HaxeFoundation/haxe","labels_url":"https://api.github.com/repos/HaxeFoundation/haxe/issues/5897/labels{/name}","comments_url":"https://api.github.com/repos/HaxeFoundation/haxe/issues/5897/comments","events_url":"https://api.github.com/repos/HaxeFoundation/haxe/issues/5897/events","html_url":"https://github.com/HaxeFoundation/haxe/issues/5897","id":196784188,"number":5897,"title":"static member initialized to null compiles to undefined on JavaScript target","user":{"login":"binki","id":82626,"avatar_url":"https://avatars.githubusercontent.com/u/82626?v=3","gravatar_id":"","url":"https://api.github.com/users/binki","html_url":"https://github.com/binki","followers_url":"https://api.github.com/users/binki/followers","following_url":"https://api.github.com/users/binki/following{/other_user}","gists_url":"https://api.github.com/users/binki/gists{/gist_id}","starred_url":"https://api.github.com/users/binki/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/binki/subscriptions","organizations_url":"https://api.github.com/users/binki/orgs","repos_url":"https://api.github.com/users/binki/repos","events_url":"https://api.github.com/users/binki/events{/privacy}","received_events_url":"https://api.github.com/users/binki/received_events","type":"User","site_admin":false},"labels":[{"id":41272315,"url":"https://api.github.com/repos/HaxeFoundation/haxe/labels/platform-javascript","name":"platform-javascript","color":"eb6420","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":5,"created_at":"2016-12-20T21:20:58Z","updated_at":"2016-12-23T15:30:06Z","closed_at":null,"body":"This might be like #3877.\r\n\r\nIn this http://try.haxe.org/#A9e66\r\n\r\n```haxe\r\nimport haxe.Json;\r\n\r\nclass Test {\r\n    static var nullStaticMember = null;\r\n\r\n    static function main() {\r\n        var x = {z: {}};\r\n        trace(Json.stringify(x));\r\n        x.z = null;\r\n        trace(Json.stringify(x));\r\n        x.z = nullStaticMember;\r\n        trace(Json.stringify(x));\r\n        \r\n        // Exceptional?\r\n        trace(Json.parse(Json.stringify(null)));\r\n        trace(Json.parse(Json.stringify(nullStaticMember)));\r\n    }\r\n}\r\n```\r\n\r\n\r\nthe `nullStaticMember` compiles to `undefined` instead of `null` when targeting JavaScript. Inside of most of Haxe, Haxe doesn’t distinguish between `undefined` and `null`. However, JSON does distinguish these. I think in this case `null` should compile to `null` instead of `undefined` (actually, it’s omitting the initialization for `nullStaticMember` altogether). I.e., the following statements should be equivalent:\r\n\r\n```haxe\r\nx.z = null; // Assign null directly, compiled to null\r\nx.z = nullStaticMember; // Assign a class variable of the same type initialized to null, compiled (wrongly?) to undefined\r\n```\r\n\r\nIt is unintuitive that those statements behave differently. This matters more when using a format such as JSON which is often an interchange format. It is conceivable that services which validate JSON might even require you to provide a key explicitly set to `null` instead of omitting the key. Or if you expect to be able to pass the results of `Json.stringify()` to `Json.parse()` you’ll find that `null` can be round-tripped while `undefined` cannot. JavaScript runtimes even throw a `SyntaxError` if you try to parse the result of stringifying `undefined`.\r\n\r\nI see this in both haxe-3.3 (try website) and haxe-3.4rc1/3.4.0 (local CLI)."},"comment":{"url":"https://api.github.com/repos/HaxeFoundation/haxe/issues/comments/269005812","html_url":"https://github.com/HaxeFoundation/haxe/issues/5897#issuecomment-269005812","issue_url":"https://api.github.com/repos/HaxeFoundation/haxe/issues/5897","id":269005812,"user":{"login":"binki","id":82626,"avatar_url":"https://avatars.githubusercontent.com/u/82626?v=3","gravatar_id":"","url":"https://api.github.com/users/binki","html_url":"https://github.com/binki","followers_url":"https://api.github.com/users/binki/followers","following_url":"https://api.github.com/users/binki/following{/other_user}","gists_url":"https://api.github.com/users/binki/gists{/gist_id}","starred_url":"https://api.github.com/users/binki/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/binki/subscriptions","organizations_url":"https://api.github.com/users/binki/orgs","repos_url":"https://api.github.com/users/binki/repos","events_url":"https://api.github.com/users/binki/events{/privacy}","received_events_url":"https://api.github.com/users/binki/received_events","type":"User","site_admin":false},"created_at":"2016-12-23T15:30:06Z","updated_at":"2016-12-23T15:30:06Z","body":"But if `null` and `undefined` are really the same for haxe, shouldn’t its [`Json.stringify()`](http://api.haxe.org/haxe/Json.html#stringify) behavior reflect that? Depending on where I get `null` from, it outputs something different—even though haxe has compile-time type information that says that my object should have a key, it is omitted from JSON if I get a runtime `undefined`:\r\n\r\nhttp://try.haxe.org/#8c488\r\n\r\n```haxe\r\nimport haxe.Json;\r\n\r\nclass Test {\r\n    static var uninitializedVar:String = null;\r\n    \r\n    static function main() {\r\n        var x:{id:String,} = {\r\n            id: null,\r\n        };\r\n        trace(Json.stringify(x)); // {\"id\":null}\r\n\r\n        x = {\r\n            id: ['a' => 'b',].get('c'),\r\n        };\r\n        trace(Json.stringify(x)); // {}\r\n                 \r\n        x = {\r\n            id: uninitializedVar,\r\n        };\r\n        trace(Json.stringify(x)); // {}\r\n    }\r\n}\r\n```\r\n\r\nIn my observations so far, `undefined` and `null` behave differently, even in specified situations (though right now the only specified situation I can think of is `Json.stringify()`)."}}
{"actor":{"display_login":"binki"}}