3 ms·
Haskell's rough to learn because it hits you with purity, category theory inspired typeclasses, and laziness all at once. It's natural that people struggle with
by seagreen 9y ago
Haskell's rough to learn because it hits you with purity, category theory inspired typeclasses, and laziness all at once. It's natural that people struggle with this (I sure did).
If you feel like trying a pure language again someday you could consider PureScript (which just has the first 2 things above) or Elm (which just has the 1st). If you do try I'd like to hear how it goes, email in profile.
- krylon 9y agoMy main problem with Haskell was not the pure, funcational part. It was the side-effect-laden part. If I were ever to go there again, I would probably give OCaml a try. It seems to offer many of the benefits of Haskell, while also offering "a way out" into the familiar world of objects and side effects. But don't hold your breath, I don't think I will get there this year.
- hardwaresofton 9y agoWhat do you mean by the "side-effect-laden" part? Did you find yourself writing lots of side effecting code because of Haskell (which seems weird)? Or Haskell just wasn't a good fit for a project that was full of side-effecting code? If it's the latter, I can definitely tell you that part of the zen of Haskell is firming up the boundaries between side-effecting code and pure code -- for example, IMHO the better you get at Haskell, the less `do` statements show up in your code (for better or for worse, because >>=, <*>, and co make it harder for newcomers to enter a codebase)
- krylon 9y agoWriting a purely functional function like, say, factorial, or the Ackermann function, was no problem at all. Writing a "purely" side effect-based one, say, read a string from stdin, parse an age, and say, "What, you are %d years old?!?! Wow, you're old!" completely eluded me. Maybe it was just that all the tutorials I encountered sucked. Maybe I am just too dumb for Haskell. Given that I currently really love Go, I kind of suspect the latter. But who knows? I'll find out next year, I guess. ;-)
- hardwaresofton 9y agoSo yeah, I definitely get that. I'm no Haskell master, but I found that my code progressed this way (assuming I was trying to do what you mentioned": main :: IO () main = do putStrLn "Please input your age:" age <- getLine when (age < 10) (putStrLn "..." ++ (show age)) when (10 =< age < 40) (putStrLn "..." ++ (show age)) when (age >= 40) (putStrLn "..." ++ (show age)) But as you get more comfortable, you get something like: type Age = Int -- Imagine there are constants here for youngAgeMessage, middleAgeMessage, and oldAgeMessage, -- for simplicity they're just strings, though you could add even more descriptive aliases -- like "OldMessage" with a quick union type like AgeMesssage = YoungAgeMessage | MiddleAgeMessage | OldAgeMessage, etc etc makeAgeMessage :: Age -> String makeAgeMessage age | age < 10 = youngAgeMessage ++ show age | 10 =< age < 40 = middleAgeMessage ++ show age | age >= 40 = oldAgeMessage ++ show age main :: IO () main = putStrLn "Please enter your age:" >> getLine >>= putStrLn . makeAgeMessage . read This isn't even the final form of this code either, there are some more things you could do to make this code more axiomatic haskell. This code is approximate (like you probably can't copy and paste it, probably won't compile) but should at least show what I mean. It's similar to early clojure and the use (and eventual love, usually, of the threading macro "->") and the unix philosophy -- once you start writing those clean functions that pass whatever they need right along, it starts getting easier (and more desirable) to pluck out the parts that don't have to be side-effecting. Also, the type system expresiveness is just amazing -- it's what Java should have been but never got the chance to be: data Thing = OneThing | AnotherThing | ThirdThing Guess what a `Thing` can be? literally just those things, not even a null or anything. A lot of people say they really love/need/only use "strongly typed" languages (which means a ton of things to a ton of people), but the biggest slap in the face to me is how a language like Java (that people will reach for when they want to compare some usually weaker language to a "strongly typed" one), is a literal minefield of Null Pointer Exceptions (NPEs). "Anything can be anything or sometimes nil" is a hard pill to swallow once you've used Haskell. Also, trying to use Option<> everywhere feels wrong if you do it in Java, because it starts to bleed everywhere, but actually... it's absolutely right (IMO) -- imagine how much better java code could be if the default was to Option.map over things, and the second you decided to try and pull a value out, you knew you were opening yourself up to something bad, instead of just passing things around and hoping they're there or writing repetitive checks. Now, if you see a `Maybe Thing`, you instantly know that that thing is either JUST the thing, or it's Nothing, and maybe's type is: data Maybe a = Just a | Nothing Type classes are also amazing, they're basically just as ergonomic as Go's interfaces, without some of the weird hangups and interface{} All that said, I definitely get the hangup, Haskell is difficult to get started with, even to this day, but man, that hurdle is so worth. Maybe I'm just addicted to high-learning-curve things but Haskell feels good.