5 ms·
Or that the documentation can be improved, or the API could be improved, or a number of other things. But really, JSON encoding/decoding in Elm boils down to sp
by Skinney 9y ago
Or that the documentation can be improved, or the API could be improved, or a number of other things. But really, JSON encoding/decoding in Elm boils down to specifying what the type of an object's field is. If that is difficult, interfaces and classes must be a nightmare.
- empath75 9y agoHere is what people are comparing it to, in terms of difficulty: json.loads('foo.json') I spent 3 days about 6 months ago, off and on, trying to figure out json decoding in elm, and gave up on the language entirely. It wasn't a matter of simply specifying types. The syntax is confusing the compiler isn't any help. I had very little difficulty working with anything else in Elm, so I think there is a lot of work to be done there. If there were a more painless way to do it, there are a lot of api's I'd love to write front ends for in elm.
- Skinney 9y agojson.loads('foo.json') (what is that? python?) requires that the json matches your types exactelly. This, at least for me, is rarely the case. And yes, it is. Here is code from my own project: Json.map3 HintTemplate (Json.field "ID" Json.int) (Json.field "Text" Json.string) (Json.field "Image" Json.string) Where HintTemplate is a record type containing an integer id, a string text and a image url. What about this is difficult?
- Tarean 9y agoThat's reasonably similar to handwritten haskell json parsing: instance FromJson HintTemplate where parseJson = withObject $ \o -> HintTemplate <$> o .: "ID" <*> o .: "Text" <*> o .: "Image" I wrote <$> and <> out but there is a definition like map3: liftA3 f a b = f <$> a <*> b This works for all applicatives, though. Is it normal for elm libraries to copy paste code like the map3 definition?
- Skinney 9y agoNot sure what you mean. It's normal that different packages have their own version of a given function, like List.map3, Json.map3 etc. But the implementation is different, so it's not copy-paste. It has to be this way in cases where generic types is not enough and something like interfaces/typeclasses is required.
- fbonetti 9y agoElm's primary selling point is "no runtime exceptions". The subheader on Elm's homepage even says this[1]: Generate JavaScript with great performance and no runtime exceptions. Type safety doesn't come for free. If you want to build an application that doesn't have runtime exceptions, you have to specify what external data should look like, how to translate that data into a native datatype, and what to do if that expectation fails. With this in mind, you can't just write `JSON.parse(data)` and expect everything to work. What if your data has a different shape? What if it's missing fields? What if field "foo" is a String instead of an Int? Here's a short example in Typescript: import fetch from "node-fetch" interface Post { user_id: number, id: number, title: string, body: string } const postUrl = 'https://jsonplaceholder.typicode.com/posts/1' const show = function(post: Post) { console.log(post.user_id) console.log(post.id) console.log(post.title) console.log(post.body) } function getJSON(): Promise<Post> { return fetch(postUrl).then(x => x.json()) } getJSON().then(show) Do you see the bug? `user_id` is supposed to be `userId`, yet this example will compile without an issue. When you run it, `post.user_id` will be undefined, even though our interface clearly states that a Post most have a `user_id` field of type `number`. The compiler won't catch this even with `--strictNullChecks` enabled. Everything in programming is about tradeoffs. If you don't care about strong type correctness, use something like Typescript. If you do care, Elm is a great choice. [1]: http://elm-lang.org/ http://elm-lang.org/
- hudon 9y agoElm's type system will not catch this bug at compile time, it will still be a runtime exception, unless you're saying Elm's compiler does an HTTP call to that endpoint to verify that the interface matches the response object?? The only difference in your example probably is that Elm will force you to handle the case where your interface doesn't match the response object (missing field, in this case). But nothing in Elm forces you to handle it well, so if the programmer forgot to handle it well in TypeScript, they will do the same in Elm, and the end result will be the exact same: a runtime failure.
- fbonetti 9y ago