Live data from Hacker News

Elm in Production: 25K Lines Later

charukiewi.cz

211–220 of 278 posts

Re: Elm in Production: 25K Lines Later

#211
post #13
post #8

First: > Elm has an incredibly powerful type system Near the end of the article: >Want to decode some JSON? Hard, especially if the JSON is heavily nested and it must be decoded to custom types defined in your application. IMHO the lack of typeclasses/traits is really hurting Elm. Take haskell f.e. {-# LANGUAGE DeriveGeneric #-} import GHC.Generics data Person = Person { name :: Text , age :: Int } deriving (Generic,…

That doesn't handle custom JSON schemas at all. I don't know much about Elm but at work in Haskell we mostly write FromJSON instances manually. It's probably the same amount of code as the data type definition.

Do you have examples of things that don't fit the vanilla FromJSON ? From the top of my head, there's lensed things (which can easily be done once with a LensJSON typeclass), and things which use a different serialization (e.g. no "tag" field, etc) for which there is little you can do, if each of your data types has its own standard. If they do, though, you could easily define a typeclass for each source (e.g. StackoverflowJSON, HackernewsJSON, etc).

Re: Elm in Production: 25K Lines Later

#212

Earlier quoted context omitted.

PureScript is a rapidly moving target. When did you try?

Eh, I don't know PureScript but IMO you just added another reason why it isn't production ready. Unless they are really really good at keeping backwards compability in both language and build tools.

Nope, they break things all the time. Or at least, they did one major break earlier this year. "Production ready" is different from "should I use this ever at all though."

Doesn't really answer the question I posed though.

Re: Elm in Production: 25K Lines Later

#213
post #180

Earlier quoted context omitted.

I really wish people would stop spreading the meme that decoding JSON in Elm is "hard". Yes, Haskell allows you to automatically decode/encode datatypes, but this only works in the simplest of cases. For example, if your backend returns a JSON object with snake-cased fields, but your model has camel-cased fields, `instance ToJSON Person` won't work; you'll have to write a custom decoder. The automatic decoders/encode…

You don't need to write the decoder boilerplate manually to get all those benefits. For example, here's how you rename a JSON field while serializing/deserializing a data type in Rust: https://play.rust-lang.org/?gist=1b382bc1572858841d5e392435d... You just annotate the field with #[serde(rename = "..")]. Here is a list of such annotations https://serde.rs/field-attrs.html Serde is also generic in the serialization f…

Same for Haskell. This package provides common translations like snake_case to CamelCase:

https://www.stackage.org/haddock/lts-9.0/aeson-casing-0.1.0....

Giving you automatic encoders/decoders like so:

instance ToJSON Person where toJSON = genericToJSON $ aesonPrefix snakeCase instance FromJSON Person where parseJSON = genericParseJSON $ aesonPrefix snakeCase

And the implementation of that package is like 4 simple lines for snake case; it's totally doable on your own for whatever you need https://github.com/AndrewRademacher/aeson-casing/blob/260d18...

I haven't had to do snake_case to CamelCase with Aeson before, but I have dropped a prefix before, like "userName" -> "name", "userAge" -> "age", and it was pretty easy and well supported.

Also I would note that this isn't as big of a deal for Haskell and Rust, because they're primarily backend languages, so they're more often sending out JSON in whatever form they please, rather than consuming it. In my experience the main consumers (Javascript on the web, Objective-C on iOS and Java on Android) use CamelCase anyway, so there's a natural compatibility.

Re: Elm in Production: 25K Lines Later

#214

Earlier quoted context omitted.

> I've been programming a long time, and elm shattered my views of the relationship between a coder and his/her compiler. I love Elm as much as the next guy, but be aware that you can get many, if not most, of these same benefits while working in JS if you use Flow.js or Typescript. I prefer Flow because the community is more oriented toward functional programming vs OOP in Typescript, but they're both capable static…

Cons of using Typescript: * Lack of purity. You can unintentionally trigger side effects from a function that's a supposed to simply return a value. function add(x: number, y: number): number { fireTheMissiles() return x + y } * It's impossible to validate that external JSON data is the correct type at runtime. If a JSON API returns something weird, you're going to get a runtime error.

> Lack of purity.

I agree. Which is why I said "many if not most" benefits, not all benefits.

> It's impossible to validate that external JSON data is the correct type at runtime.

Not sure I understand what you're saying. Of course you'll get a runtime error if your external JSON is the wrong type, what else could you do? Accept the data and enter an inconsistent state?

However, similar to the Elm JSON validation, in Typescript and Flow, you can write schemas to to runtime validation of external JSON. There are multiple libraries for this.

Re: Elm in Production: 25K Lines Later

#215

Earlier quoted context omitted.

> I've been programming a long time, and elm shattered my views of the relationship between a coder and his/her compiler. I love Elm as much as the next guy, but be aware that you can get many, if not most, of these same benefits while working in JS if you use Flow.js or Typescript. I prefer Flow because the community is more oriented toward functional programming vs OOP in Typescript, but they're both capable static…

I've used both Typescript and Flow, and this breaks down in practice. At least, it did for me. Problem with both Typescript and Flow is that it requires discipline from you, your team, and those who provide third party libraries. If someone was lazy and inserted `any` at a key location, you can start having familiar bugs even if the type checker tells you everything is fine.

This is trivial to avoid with a linter (which is a good idea to use anyway with JavaScript). For Flow, there's an eslint plugin that allows you to raise an error on the use of any weak type, such as `any` [1]. I'd be very surprised if the same doesn't exist for TypeScript.

1. https://github.com/gajus/eslint-plugin-flowtype#eslint-plugi...

Re: Elm in Production: 25K Lines Later

#216

Earlier quoted context omitted.

Please read my comment again, I said "many if not most" of the benefits. And I was referring specifically to the tire system, not the language as a whole. Listen, I love pure functional languages, but the step up from JavaScript to flow in program correctness is greater than the step up from flow to elm (in my opinion). Flow even has sum types. Have you actually tried flow?

I've tried to use flow three times now, but the tooling just isn't there yet. It might be better now, but Facebook doesn't seem to invest heavily in developer UX.

What problem did you have?? I've been using Flow.js for work for several years now, to great success. I feel very uncomfortable now writing plain JS.

Re: Elm in Production: 25K Lines Later

#217
post #180
post #8

First: > Elm has an incredibly powerful type system Near the end of the article: >Want to decode some JSON? Hard, especially if the JSON is heavily nested and it must be decoded to custom types defined in your application. IMHO the lack of typeclasses/traits is really hurting Elm. Take haskell f.e. {-# LANGUAGE DeriveGeneric #-} import GHC.Generics data Person = Person { name :: Text , age :: Int } deriving (Generic,…

I really wish people would stop spreading the meme that decoding JSON in Elm is "hard". Yes, Haskell allows you to automatically decode/encode datatypes, but this only works in the simplest of cases. For example, if your backend returns a JSON object with snake-cased fields, but your model has camel-cased fields, `instance ToJSON Person` won't work; you'll have to write a custom decoder. The automatic decoders/encode…

With respect to the snake-cased fields issue, it's actually not that hard to do that with Generic in Haskell.

  data Person = Person
       { personFirstName :: Text
       , personLastName  :: Text
       } deriving (Generic)

  instance ToJSON Person where
     toJSON = genericToJSON $ aesonPrefix snakeCase
  instance FromJSON Person where
     parseJSON = genericParseJSON $ aesonPrefix snakeCase
Which produces messages like:

  {
   "first_name": "John",
   "last_name": "Doe"
  }

Re: Elm in Production: 25K Lines Later

#218

Earlier quoted context omitted.

I am more interested in the details that just this blank statement that everything is better. After trying Elm several times we failed to implement even basic things in it that we could do in React/Redux easily. For an average JS developer Elm is totally alien tech compare to React or Angular. For Haskell programmers Elm is pretty appealing because of the familiar syntax and type system, but the intersection of Haske…

For an average JS developer Elm is totally alien tech compare to React or Angular To turn your argument the other way. The JS landscape, where "trendy" libraries change every few months, is also alien to anyone that doesn't keep with the latest libraries every few months. Is that not worse? I don't have to explain "JS fatigue", it's a fact. For example, I just got into a new team, and I have to now use what they use.…

Well sure, but as an architect/CTO I do not care about trendy, I care only about properly working, easy to develop and maintain and wildly used so I can hire for. Elm is none of these at the moment, but React is.

Re: Elm in Production: 25K Lines Later

#219

Earlier quoted context omitted.

I've used both Typescript and Flow, and this breaks down in practice. At least, it did for me. Problem with both Typescript and Flow is that it requires discipline from you, your team, and those who provide third party libraries. If someone was lazy and inserted `any` at a key location, you can start having familiar bugs even if the type checker tells you everything is fine.

This is trivial to avoid with a linter (which is a good idea to use anyway with JavaScript). For Flow, there's an eslint plugin that allows you to raise an error on the use of any weak type, such as `any` [1]. I'd be very surprised if the same doesn't exist for TypeScript. 1. https://github.com/gajus/eslint-plugin-flowtype#eslint-plugi...

Cool! Does it enforce third-party libraries as well? A thing that typescript and/or flow doesn't support, is JSON. What if a JSON object doesn't match the type? This can cause sneaky bugs later :/

I'm not saying that typescript/flow is bad. Whenever I have to use node.js, I end up using typescript. But I've been bitten several times by the fact that typescript isn't as strict as Elm forces things to be.

Re: Elm in Production: 25K Lines Later

#220
post #180
post #8

First: > Elm has an incredibly powerful type system Near the end of the article: >Want to decode some JSON? Hard, especially if the JSON is heavily nested and it must be decoded to custom types defined in your application. IMHO the lack of typeclasses/traits is really hurting Elm. Take haskell f.e. {-# LANGUAGE DeriveGeneric #-} import GHC.Generics data Person = Person { name :: Text , age :: Int } deriving (Generic,…

I really wish people would stop spreading the meme that decoding JSON in Elm is "hard". Yes, Haskell allows you to automatically decode/encode datatypes, but this only works in the simplest of cases. For example, if your backend returns a JSON object with snake-cased fields, but your model has camel-cased fields, `instance ToJSON Person` won't work; you'll have to write a custom decoder. The automatic decoders/encode…

It's not so much that writing decoders is hard it's that writing robust parsers without applicative is quite laborious, once you're used to having them.
Post reply on HN