6 ms·
> Haskell is hard. More accurately: Haskell is particularly hard for a procedural programmer to learn in comparison to a new procedural language and the time
by aranchelk 4y ago
> Haskell is hard.
More accurately: Haskell is particularly hard for a procedural programmer to learn in comparison to a new procedural language and the time spent learning prior to being as productive may be (from my experience) 30x.
IMO, once learned, the type checking is so helpful, everything else seems hard.
Also, learning the language is only half the battle as it’s much more difficult to establish for yourself good practices for common use cases like app development. You’ll find plenty of people using FP for specialized stuff that’s not relevant to the average working programmer. In looking for advice you may stumble across the promotion of peoples’ impractical pet projects, and without experience you won’t know it.
If you can budget the time to learn the language and then build a couple poorly structured apps that you’ll come to hate, expect very smooth sailing after.
- eterps 4y agoTo be honest, after having learned other FP languages like OCaml/ReScript, F#, Elixir, Gleam and Elm, I still find Haskell baffling. Not necessarily writing it, but I find reading someone else's Haskell code insanely difficult. It will take many more years before I get comfortable with that.
- yodsanklai 4y agoI agree. I'm quite experienced with FP, but I find Haskell hard, or at least impractical. Not necessarily because of abstractions, but some design choices make programs hard to read for no good reasons. > but I find reading someone else's Haskell code insanely difficult. It's true for expert Haskellers as well.
- jpittis 4y agoNot to mention large parts of the community using a pointfree, single character variable naming style that's hard to read. If Haskell could consistently be written in a more predictable style, that would be much more suited to collaboration IMO.
- ParetoOptimal 4y ago> Not to mention large parts of the community using a pointfree, single character variable naming style that's hard to read. Actually most of the community calls point-free "pointless". I know because I actually like point-free and noticed that became a minority opinion over the years. My experience with real world Haskell has been it is more often too verbose in the style of Java to avoid confirming the "Haskellers use single letter variables everywhere" misconception.
- ParetoOptimal 4y ago> but some design choices make programs hard to read for no good reasons. Can you give some examples? I may be able to use it in future Haskell writings or teaching new hires.
- marcosdumay 4y agoHaskell is hard. It doesn't need modifiers. It is harder for people that are used to program in incompatible ways, but it's hard for people without a lot of experience too, and for people with previous knowledge of different paradigms, and for people used to the functional paradigm but not to its level of purity. And learning the language is no half the battle. Maybe some 10% if you want to stick with very simply idioms, maybe less. And if you won't learn the hard idioms at all (instead of just not using them 99% of the time like most people do) is there even a point on learning the language? At most your code will be a bit easier to modify, but you will never get most of the value.
- pyrale 4y ago> you will never get most of the value. Counterpoint: a lot of the value is in a small subset of the language that most people learn first. You don't need to use every feature of the language to really benefit from it, and I haven't met any professional haskell codebase that uses everything. It is fine to just use what you need, and leave the rest.
- marcosdumay 4y agoWhat you need is never the bare minimum. It's always the minimum, plus one or two details that make your code usable. And those one or two details are different every time.
- fn-mote 4y agoAll of my sibling posts: please be specific!! Somebody not at your level (and there's more for Haskell than more mainstream languages)... like me... isn't going to get what you're talking about. > And if you won't learn the hard idioms at all ... you will never get most of the value. Ok... mention a hard idiom? Even if you don't want to go into detail. We'll look it up. > [...] reading someone else's Haskell code insanely difficult. I'm wondering if that's because they used a ton of operators like (.)(.)(.) or :=-=: (just made that up, i hope), or was it because of some deeper reason like too much magic hidden in the monad transformers. Anything concrete you're willing to say will clear some of this haze of non-understanding.
- spion 4y agoOk, lets be specific. Lets write a comment to explain this function: https://github.com/dhall-lang/dhall-haskell/blob/master/dhall-json/src/Dhall/JSONToDhall.hs#L802-L809 https://github.com/dhall-lang/dhall-haskell/blob/master/dhal...
- rowanG077 4y agoThere is already a comment there? And the implementation doesn't look too hard. I don't feel like this is an example of a hard to understand Haskell function.
- spion 4y agoHow about you try your best to explain all of it? What exactly is that you understand here? What does Optics.rewriteOf do? What's the purpose of Lint.useToMap? How about D.subExpressions ? How does that composition work with the loop function? Even better. How would you go about finding the source code containing the definition of the function `D.subExpressions` ?
- rowanG077 4y agoNo I didn't understand every sub-function in this function. That isn't necessary to get an idea of what a function does. All of your questions can be answered incredible quickly though using https://hoogle.haskell.org/ https://hoogle.haskell.org/ > What does Optics.rewriteOf do? Hoogling show this is an alias of https://hackage.haskell.org/package/lens-5.1.1/docs/Control-Lens-Combinators.html#v:rewriteOf https://hackage.haskell.org/package/lens-5.1.1/docs/Control-.... > What's the purpose of Lint.useToMap? Hoogle again shows https://hackage.haskell.org/package/dhall-1.41.1/docs/Dhall-Lint.html#v:useToMap https://hackage.haskell.org/package/dhall-1.41.1/docs/Dhall-.... If your function is not indexed you can look at what is qualified as `Lint` and look it up that way. > How about D.subExpressions ? How does that composition work with the loop function? https://hackage.haskell.org/package/dhall-1.41.1/docs/Dhall-Core.html#v:subExpressions https://hackage.haskell.org/package/dhall-1.41.1/docs/Dhall-... All nicely documented... I'm not sure what you mean by composition with the loop function. First the loop function is executed and then afterwards over the result the expression in the first argument to fmap is applied. There is no weird interaction going on here. It's just run this over the result of the loop function if it didn't produce an error. > Even better. How would you go about finding the source code containing the definition of the function `D.subExpressions` ? Use hoogle or just look at the imports at the top of the file. Just like any other programming language. Or even better, use the language server to find it for you. For example there is an import here: `import qualified Dhall.Core as D` Now you know that function is in the `Dhal.Core` module. Going to that module you see the function is not actually there but is exported from the `Dhal.Syntax` module. It took me literally 5 seconds to find it: https://github.com/dhall-lang/dhall-haskell/blob/master/dhall/src/Dhall/Syntax.hs#L786 https://github.com/dhall-lang/dhall-haskell/blob/master/dhal...
- astrange 4y ago> IMO, once learned, the type checking is so helpful, everything else seems hard. I've noticed this claim, that Haskell's type system prevents all bugs, eg at: https://www.costarastrology.com/why-haskell/ https://www.costarastrology.com/why-haskell/ And when they say it prevents all bugs and has no illegal states they seem to mostly mean it has ADTs. But who is keeping me from having bugs in my numeric code? Not Haskell, making you type "fromIntegral" doesn't prevent bugs. Idris or Ada, maybe.
- jose_zap 4y agoYou can use the LiquidHaskell plugin to perform extra compile time checks to numeric code.
- aranchelk 4y agoWas that my claim? It certainly doesn’t prevent all bugs. The refrain I generally see (which I did not write here) is “if a Haskell program compiles, it probably works" Note that “probably” doesn’t mean “always” and “works” isn’t a synonym for “is absent of any and all bugs”. Yes algebraic data types and compiler options that force you to handle all cases are a big part of it. Additionally, verifying correct record field names, needed type class instances exist, a total absence of nulls (and the forced handling of Nothing cases). It’s also the type inference, I want the above features and I don’t want to write out type signatures before I’m ready. The dependently typed stuff (e.g. Idris) is compelling but you do lose the inference.