Hacker News new | past | comments | ask | show | jobs | submit login
Learn You a Haskell for Great Good (2008) (learnyouahaskell.com)
189 points by kmooney on Feb 19, 2015 | hide | past | favorite | 120 comments



I think the current 'definitive' resource for learning Haskell is https://github.com/bitemyapp/learnhaskell, which has well-curated, comprehensive links.


I won't read that one on principle alone. The author (coolsunglasses on HN) runs around all the various forums (, threads, and subreddits) for other languages, trolling other users and making fun of their languages. He's a complete asshole. Besides, Real World Haskell and Learn You a Haskell are both extremely competent books/tutorials.


Haskell is such a great language. I've been recommending this book for a while now. If you are in doubt whether you should start learning it, read this post by Jeff Bone:

http://www.xent.com/pipermail/fork/Week-of-Mon-20070219/0441...

After I read it, I immediately began learning Haskell. Since then, Haskell made my brain melt multiple times. But it has also enabled me to build an expression parser and analytic differentiator that I use every day (among other things, but that's what I'm most proud of). Such a program would be a lot harder to create, if it weren't for Haskell's ridiculously powerful type system and pattern matching.

Also, after learning the Haskell way of things, I recognized the reasons for many issues I had with code written in another programming language. Don't just go out there and do object-oriented programming because everybody else seems to do it, often it is imperative (pun intended) to use the declarative (functional) programming paradigm to keep you out of debugging hell.

edit: clarification


The true ending to that story is when you come back to your old gal and start convincing her to get monad imports. "You'll feel just like your old self, only more functional! " You tell her. The next day you hear even your neighbor Facebook got his girl PHP to try out lambdas and type annotations.

Then you realize that Haskell has been sleeping around. A lot.

It's time to get tested.


I'm not sure if that link is NSFW or not :)


Certainly doesn't help with the perception of the tech industry as a boys club. I mean I know it may have been written in jest but I was personally cringing while reading it and figured it'd be at the very least a little alienating (at worst outright offensive) for any women who'd happen to read it. Maybe I'm being oversensitive, I just know I wouldn't write anything like that.


Are you serious? From your description, I was expecting some kind of gross pornography. I think that these 'rolling in the aisles' displays of public piety in the service of political correctness are getting a little out of hand these days.


I think you are exaggerating somewhat, I was just saying I didn't like it and even caveated that this could be just me being oversensitive.

However if you can't see why someone may feel a bit weird reading "You'd be there, banging away at your regular girl" then I'm not sure what I can say. It's not rolling-in-the-aisles piety, it's just that our community already has a bad image and stuff like this isn't helping.


It certainly wasn't my intention to alienate or offend anyone by posting this link. I do not share his intimate feelings on programming languages but I found it amusing that someone would compare a programming language to an on/off-relationship.


Heh it's not your fault, my ire/confusion was directed at the article not at you. This is all subjective anyway and as a sister comment indicates I may have been unique in my feelings towards it


It's about programming languages! :D

Although, I think, if someone reads it who's not familiar with programming languages, the reactions, when you tell them what Haskell and Python are, might range from hilarious to WTF.


We'd be remiss not to mention the Erlang counterpart...

http://learnyousomeerlang.com/


What is a good online reference to learn about "Monads" for beginners? Someone posted a reference here on HN sometime ago but I lost it.

Edit: The book was enjoyable and a delight to read, but I started struggling to keep up from Chapter 8. as it went into Monoids and Monads, I feel like I need to read other tutorials before coming back to it.


They don't teach you number theory before they teach you addition and subtraction in primary school.

Don't read the "Monad tutorials" and especially do not stop programming in Haskell until you "learn monads". Find one of the respected books, read it and do the exercises.

You do not need to thoroughly understand monads in order to do some IO programming just like a violinist does not have to understand the physics of vibrating strings or you don't need to be an auto mechanic to drive to the grocery store.

Write the "Guess the Number" game in Haskell using IO and you should understand the basics and that gets you far. Reading and writing to/from files and network sockets, etc works pretty much the same as you're used to from imperative programming languages. "Guess the number" contains just enough control flow (repetition, conditionals) to get you started.

I've written tens of thousands of lines of Haskell code, including production code at work, and I still don't know what a Monoid is. I have only a faint theoretical understanding of monads, but I am fluent writing IO code and applying monads to other problems like parsing and error handling.

You should only study monads when you're fluent doing some basic imperative programming in Haskell or if you are a math student and have a keen interest in category theory.


"I still don't know what a Monoid is."

That is surprising. They show up all over in fairly common libraries - for instance, Writer collects a monoidal value. The very simplest notion is "monoid is for things you can combine". Taken from math, a monoid is a set of things (a type) for which you have an operation (called mappend in Haskell) which you can combine associatively, where the set contains an element (mempty in Haskell) that is an identity with respect to that operation.

Some common monoids are:

    Anything list-like:
        mappend appends two lists
        mempty is the empty list

    Integers over addition (newtype Sum)
        mappend adds two integers
        mempty is zero

    Tuple of monoids:
        mappend is componentwise mappend
        mempty is (mempty, mempty)

    Functions where the domain and range are the same:
        mappend is function composition
        mempty is id


> Reading and writing to/from files and network sockets, etc works pretty much the same as you're used to from imperative programming languages.

I agree completely that it's not necessary (and maybe even detrimental) to learn monads to use Haskell's IO, but I think this claim is dubious. Not too many imperative languages have lazy IO and this feature can be a surprising hurdle for the Haskell beginner who is versed in other languages.


There was quite a long discussion about this on the Haskell subreddit this past week[1], and indeed this topic seems to always be something newcomers get caught up with.

My advice is to use the language until you gain an intuition for them. Despite being rather simple, I found it was difficult to fully appreciate them without a decent amount of exposure. Really though, monads aren't what Haskell is all about, and don't let an incomplete understanding of them stop you from diving in.

[1] http://www.reddit.com/r/haskell/comments/2vm0ed/is_there_a_g...


The original monad papers, by Philip Wadler. Accept no substitutes.

http://homepages.inf.ed.ac.uk/wadler/topics/monads.html

http://homepages.inf.ed.ac.uk/wadler/

Alternatively, if you really are allergic to LaTeX, or beards, the recently Oscared sigfpe’s “You Could Have Invented Monads! (And Maybe You Already Have.)”

http://blog.sigfpe.com/2006/08/you-could-have-invented-monad...

There are no other monad tutorials. Just forget about them.


I highly recommend "You could have invented Monads", it helped me a lot. I also recommend the Haskell Wikibook:

http://en.wikibooks.org/wiki/Haskell/Understanding_monads


Yes there are. What made monads eventually "click" for me was the incredibly detailed, eight-part Mike Vanier's tutorial on monads in general and in Haskell in particular. First part: http://mvanier.livejournal.com/3917.html


You Could Have Invented Monads is what really made monads "click" for me. There are better tutorials for how to use monads in the real world, but I've never read a better description of why you would want to, if you don't know what they are.


I highly recommend watching Tom Stuart's talk "Refactoring Ruby with Monads":

https://www.youtube.com/watch?v=J1jYlPtkrqQ


Thanks! There’s a transcript at http://codon.com/refactoring-ruby-with-monads.


I have seen a few monad tutorials and found this series far more comprehensible than others-- it starts with the real-world monads many programmers use unknowingly and works back to the definition. http://ericlippert.com/2013/02/21/monads-part-one/


I recommend this to anybody who wants to learn about Haskell's important data types:

https://wiki.haskell.org/Typeclassopedia


I found the typeclassopedia to be really helpful after I'd been programming in Haskell for a few years. It really helped tie all of the types together, but a part of me thinks that it might be a bit overkill for someone who's just dipping their toes in for the first time.


I like that it builds up to monads by introducing functor and applicative first, as those are far easier stones to leap to.


You don't need to really understand monads to use them. Not at first anyway. They're basically just containers that allow you to use side effects, hold state, etc... https://acm.wustl.edu/functional/io-monad.jpg


I'm going to make an attempt to succinctly explain monads:

A monadic data type is a container that can be mapped and flattened.

- It's a container, because it stores has an inner type, which refers to the data it contains. For example, think of the type parameter that describes the elements of a list.

- It is "mappable" in the sense that its contained type can be converted to another type by providing an operation from the first type to the second type. Imagine converting a list of strings to a list of integers, where each integer is the length of the corresponding string.

- It can be "flattened" in the sense that if its inner type is an extra nesting of the container type, it can be flattened to a just one level of the container type. For example, a list of lists of integers can be flattened to just a list of integers by concatenating the sublists.

- It seems kind of trivial to say, but there has to be a way to construct a container given one of the elements it's supposed to contain.

There are also a couple of rule these operations have to fulfill. They're kind of abstract when stated on their own, but make intuitive sense when you consider examples.

Pretty simple, huh? What's cool about it is that you can assign all sorts of metadata to the container type and semantics to the flatten operation, and you get a nice representation of a pipeline of operations, where each one depends on the all the previous steps. This is basically just imperative programming -- each step depends on the current context and can optionally mutate that context, affecting subsequent steps.

You might ask, "but isn't imperative programming what we're trying not to do?" In the most general sense with mutable state everywhere, yes. But monads give you a way to describe imperative logic in very tightly controlled contexts.


>They're basically just containers that allow you to use side effects, hold state, etc...

No, that is one use for Monads. A Monad is just something that has a bind (>>=) function and a return function.


> A Monad is just something that has a bind (>>=) function and a return function.

You realise that this is the most useless description ever? While I'm sure it's right, it doesn't actually mean anything. Why's it a good abstraction for doing <X>, better than any other abstraction? If it abstracts over a gazillion different things, why not have special-purpose abstractions like other languages (and thus probably make the language a lot simpler to use)?

Your description is on the same level as "programming languages are structured text".


The point, I think, is that the original description leaves out the easiest monads, which makes learning about them a lot more difficult. See: List, Maybe, etc.


Fully agreed that those are the easiest monads, far easier than IO, state and side-effects. But the post is still unhelpful, because how do List and Maybe relate to this:

> A Monad is just something that has a bind (>>=) function and a return function.

?

(I know how they relate, but the above assertion is not a particularly helpful description of List and Maybe)


>but the above assertion is not a particularly helpful description of List and Maybe

Good. If my description of a Monad was a good description of List or Maybe, then I described Monads wrong.

Your complaint is like saying "Your description of a shape was not a helpful description of a dodecahedron." Indeed, a dodecahedron is a very specific instance of a shape.


Exactly. However, note I wasn't disagreeing with you; I was disagreeing with user thedufer that "the point" was that "the original description leaves out the easiest monads, which makes learning about them a lot more difficult. See: List, Maybe, etc." (That's why I replied to him and not to you)

List and Maybe are indeed the easiest monads, but thinking about them in terms of (>>=) and return doesn't give a good intuition about monads, Lists or Maybe. So I think that wasn't "the point".

"The point" was actually that state and IO aren't the only monads, and that the definition is way more general than that. List and Maybe being the easiest monads is irrelevant.


Gotcha. Then I am in absolute agreement.


>You realise that this is the most useless description ever?

Which is perhaps why many people have a hard time understanding it. That is, however, the true definition.

>Why's it a good abstraction for doing <X>

That depends on <X>. I can't answer that question unless you tell me what <X> is.

> If it abstracts over a gazillion different things, why not have special-purpose abstractions like other languages (and thus probably make the language a lot simpler to use)?

Why would a special-purpose abstraction be easier to use? If you only understand monads in terms of state, you can just use them that way.


> That depends on <X>. I can't answer that question unless you tell me what <X> is.

Isn't that kind of the problem? I have no idea why it's a good abstraction for anything or what sorts of things it's a good abstraction for. Is it a good abstraction for adding numbers together? God knows, nobody can explain it.

> Why would a special-purpose abstraction be easier to use?

Because it says what it does on the tin, rather than being buried under several abstraction layers. My for loop is a lot more obvious than your "lifting functions into the list monad" or whatever it is you do with them, and is quite obviously doing an entirely different thing from, say, dealing with the contents of a Maybe, or storing state, or executing IO operations.

We can play with abstractions upon abstractions all day, but unless they actually mean something solid, how are they useful in explaining or solving a problem?


>Isn't that kind of the problem?

Maybe. Leaving things in the abstract can certainly be confusing sometimes.

>I have no idea why it's a good abstraction for anything or what sorts of things it's a good abstraction for.

I think once you understand Monads for what they are (i.e. accept that it's just something with bind and return), you start seeing where it makes sense to use Monads. Until then, you can just use whatever concrete Monad implementations you're aware of. It seems like you know perfectly well that there exist Monad implementations for Lists, for example.

> Because it says what it does on the tin, rather than being buried under several abstraction layers.

IO, List, and most other Monads do what they say on the tin, even if you're not aware that they're Monads.

You don't have to know if something is a Monad or not to use it. For example, I've been using Lists my entire programming career without it occurring to me that I could use them with bind to model nondeterminism or the ZipList Monad.

>but unless they actually mean something solid, how are they useful in explaining or solving a problem?

They are useful because they are examples of http://en.wikipedia.org/wiki/Algebraic_structure .

You can use the definition of an algebraic structure to prove things about all instances of that structure.

Monads are, in fact, quite useful even in their most general definition.


ZipList isn't a monad, is it?


You're right. I think I mis-remembered reading the Applicative instance for ZipList.


The something has to be a single argument type constructor, and bind and return need to abide by some laws.

I don't mean that as any sort of "gotcha", just some additional clarification - especially if people read your "just" too strong.


New abstractions are generally better introduced to new audiences via concrete examples that can later be generalized rather than formal abstractions that float high above our heads.

The GP's explanation of the concrete features (with simple examples!) is one of the most useful explanations of monads I've seen. It isn't complete, but as a gateway to a complete explanation it is extremely good.


If you want to start right at the concept level before jumping into code, this is a great intro to functors, applicatives, and monads.

http://adit.io/posts/2013-04-17-functors,_applicatives,_and_...


First, you are not alone. I also "hit the wall" when the discussion turned to functors, monoids, and monads. Now, let me be the token heretic here. I took an online Haskell course where the instructor said, "Now that you have learned about monads, please don't write yet another monad tutorial!" Perhaps the reason that there are so many tutorials about them is because the really are NOT easy to grasp.


Stephan Boyer teaches about them in a peculiarly pragmatic way. Haskell programmers often abstract application-specific computations into monads and use them as a sort of interface—a functional API.

http://www.stephanboyer.com/post/9/monads-part-1-a-design-pa...


Theory is generally wasted on me until I bang my head against the code for a while. If you're like me, you'll probably find it easiest to try to use monads in real code over and over, mostly based on existing examples, and then it will finally click and you'll be able to go back and grok the underlying theory.


If you don't mind abstract mathematics, the category theory lectures from https://www.youtube.com/playlist?list=PL8Ky8lYL8-Oh7awp0sqa8... were what made monads finally click for me.


The best explanation I ever had was, "It is just a type class." In other words, don't worry about some deep metaphor. A Monad will have a type constructor, bind and the badly named return. There are laws that say how they'll work. The intuitions can come later.


Both monads and monoids: The only thing you need to learn about them is practice. Screw tutorials and books. Read LYAH's intro chapter once (you won't understand everything, but that's fine) and then write code.



Well, Learn You a Haskell's explanation of Monads in Haskell seems alright.


I want to note that LYAH may not work for you if you have my kind of learning style. I need to solve concrete, realistic problems to creatively use the knowledge imparted on me. I can't just read stuff and understand. Real World Haskell [1], the course by Erik Meijer [2] and the courses referenced here [3] worked much better for me.

[1] http://book.realworldhaskell.org/

[2] https://www.edx.org/course/introduction-functional-programmi...

[3] https://github.com/bitemyapp/learnhaskell


That sun cracks me up almost every time.


My favorite is:

"If we think of a list as a monster, here's what's what."

http://s3.amazonaws.com/lyah/listmonster.png


My favorite illustration is the monoidal pirate ship:

http://s3.amazonaws.com/lyah/pirateship.png


I still can't get over the 'Girlfriend' gag.


I like Haskell for the same reasons I like VIM:

- It needs some brain melting to learn but it ultimately makes you a better coder. Time is not wasted on learning it. - A new exciting mindset !

- When you feel you're doing something repetitive, it's nearly sure there is a way to do it effortless.

- Advanced stuff


For newcomers I'd suggest this introductory course by Erik Meijer: https://www.edx.org/course/introduction-functional-programmi... . It's about FP, not strictly Haskell, but it really helped me starting with it and really stimulated my curiosity (and he really can explain hard concepts in a simple way imo). I started reading the book after I completed the course and helped giving an answer to a lot of questions I had during the course.


I'm currently working through this book. Overall it seems like a good introduction but I wish it had exercises at the end of each section. I learn best by working through specific problems.


Word.

There's Real World Haskell by Don Stewart (http://book.realworldhaskell.org/read/index.html), though the order of exposition is different and your mileage may vary with the exercises.

I did find that "Programming in Haskell" by Graham Hutton was a very clear read and had good programming exercises.


Extensive list of resources including many that have exercises: https://github.com/bitemyapp/learnhaskell


We had a Learn you a Haskell book club at work a few years ago and a friend made these very good excercises: https://github.com/noelmarkham/learn-you-a-haskell-exercises


The recently released Thinking Functionally with Haskell by Richard Bird includes exercises. I like the fact that this book is a little more rigorous than LYAH.


I suggest the Haskell Wikibook as the best overall intro to Haskell actually: http://en.wikibooks.org/wiki/Haskell

(and you can make it better if you find anything to complain about! but seriously, it's superb)


Supremely useful reference: http://dev.stephendiehl.com/hask/


[deleted]


I'd say it's pretty good. It's hard to give advice because I learned Haskell when I already had a decent college-student understanding of C++, so Haskell added diversity to my education where C wouldn't. It's good to learn languages that are different, and languages that make different things cheap -- Haskell made defining types and also made static type checking a lot cheaper than other languages in 2005. It's also easier to usefully learn than C, because I think you really need to do stuff with a language in order to be good at it, and floundering around as a noob in C isn't necessarily the best way to do that, it seems to me like you can learn ho to use it wisely, more productively, when coming from a background with some experience. You can do useful stuff with Haskell pretty quickly, which lets you go farther with it.


Nice post. I just don't get the 2005 date, given the history of ML derived languages.


Sounds to me like he was just giving the year he first learned Haskell for context. Today there are a lot more mainstream languages that similarly make static typing cheaper.


That's right, I didn't know about ML at the time, I heard of Haskell first because of some Slashdot articles.


What does "lack of applications" mean? As in, not that many apps are written in it, or that it's not applicable to many of them? It's a fairly general-purpose language, you can get most common programming tasks done in it pretty well.


If you like math (I mean stuff like set theory and abstract algebra, not arithmetic and high-school math), then Haskell is wonderful. I find programming in it to be more enjoyable than in any other language. It will also make you think differently, which is a useful feature if you're learning a language to expand your horizons. It's also a gateway language to more bleeding edge aspects of language design.

That said, I find that knowing enough C to fix build and configuration problems in open source projects has been more useful than Haskell for me.


Should I learn oCaml instead ? Looks appealing because companies like Facebook are using it create tools like Flow ( https://github.com/facebook/flow ).


Facebook is also creating tools with Haskell:

https://github.com/facebook/Haxl

My 2 cents: definitely _also_ learn OCaml down the line. But:

- my pet peeve with OCaml is the lack of a builtin type for Unicode strings (the only other language still commonly used with this shortcoming is PHP), and this could be an issue if you plan to write some web app code that needs to be internationalized

- OCaml is strict, Haskell is one of the very few languages that is non-strict: aside from the didactic purpose of exposing yoursefl to something different, that's a feature that can help reasoning about what your code is doing:

http://augustss.blogspot.co.uk/2011/05/more-points-for-lazy-...

(then again, there're obviously downsides to non-strictness, and you might decide down the line that you prefer to write strict code in production... but it's good to know the alternatives)


Is there a free, light tutorial book like "For Great Good" for OCaml?


Not as lighthearted as LYAH, but (as suggested by ufo) I think this might be useful:

https://realworldocaml.org/


Why do people choose programming languages based upon which big companies are using them? Learn a programming language because it is interesting, not because Facebook uses it.


Facebook is huge influencer in the open-source world. I don't see anything wrong with learning the tools/languages that it adopts. There are far smarter people working there.

In context of this question, It seems that learning both Haskell and oCaml is what people recommend.


Because I like getting paid?

If I'm learning a language for my own enjoyment, I'll learn whatever I want. If I'm learning a language to try to develop my career, I'll learn something that people want to pay for.


If you want to dive onto ocaml, I would highly recommend the "Real World Ocaml" book.

That said, I agree with berdario that you should learn both languages instead of only one of them. There is lots of terminology that is shared between FP languages too so it shouldn't be very hard either.


Learn the one you prefer but don't choose for this reason : Haskell is also very present at Facebook.


This is what I used to learn Haskell a while back. It's a pretty darn good intro. I'm very glad I did it.


I really like this book, but I think it may be teaching some bad habits by ignoring performance concerns.


It's not a problem until it's a problem.

That is: At least 90% of code is not CPU-limited. It's fast enough. So, as an initial approach, ignoring performance is fine.

The problem is that, if and when you run into real performance issues, you need to know some tools for dealing with them. If this book doesn't teach you those, well... it's a language introduction. It's not an advanced text. Maybe it would be the better for a warning or two, a paragraph here or there, but performance is (quite properly) not the point for the book.


Fair enough.

I guess I mean to say that I really like this book, and would enjoy more from the author teaching fast Haskell, to supplement this book about simple Haskell.


I was pleasantly surprised recently when I noticed that this book has a discussion of efficient list construction [1]. I know it's a fairly basic idea, but the author brings it up purely for performance reasons. Given the introductory nature of this book I didn't expect that.

[1]: http://learnyouahaskell.com/for-a-few-monads-more


Haskell can be very handy at solving some puzzles.


Haskell can be very handy for solving real world problems as well.


This book was excellent for helping me learn Haskell, but the gendered language and fat-shaming jokes made me feel very uncomfortable, eg:

"You're fat! Lose some weight, fatty!","You're supposedly normal. Pffft, I bet you're ugly!" and "You're a whale, congratulations!", "Sure, we could just type them all out but obviously that's not a solution for gentlemen who demand excellence from their programming languages."


You're absolutely right, as a transfat HAES advocate genderqueer, I feel extremely triggered by the author's fat-phobic and gender-normative oppression. The author needs to check his privileges and rephrase to:

"You're healthy at every size! Continue being body positive, healthy!", "You're supposed normal. Pfft, society has an unrealistic standard of beauty!" and "You're absolutely perfect with no flaws, defects, or relevant analogies that can be made, congratulations!", "Sure, we could just type them all out but obviously that's not a solution for genderfluid feministia who demand equality from all xer programming languages."


Your cunning sarcasm has swayed me. By all means, continue the fat-shaming!


Check your privilege, single-shape mortal-normative scum! Some of us have more than one body to be ashamed of!


It's a shame this got downvoted in the backlash. Almost everyone has something they'd find offensive if it were put non sequitur in some technical resource they were reading. It's very possible to be lighthearted without being needlessly offensive. Things that the majority would find offensive basically become invisible and unquestioned norms, but when the majority has to consider that other people have touchy topics too, they'd rather just fall back on the invisible norms than consider points of view they simply don't feel like considering. It's telling that you mostly have glib remarks, dismissals, and downvotes instead of any real counterargument.


Clearly the author is going for a casual, conversational, jocular attitude. That's part of what makes LYAH so approachable. If you want dry, sanitized, bowdlerized instruction, LYAH is not the place to look.


It's possible to communicate in a casual, conversational, and humorous manner without alienating minorities and delivering insults, and the author chose not to.

I think it's unlikely that he was trying to be malicious and is probably just not sensitive to what it's like to be on the receiving end of some of his examples.


Aren't you imputing motives without proof ?

While I respect your sensibility, I would have made the same kind of remarks without thinking it would hurt someone. I understand it could, but it wouldn't have been my intent. Also remember that your position is very very US-centric. But I am all for communication : explain your point to the author and propose something else that is as funny as the current text.

But saying the author chose not to is simply dishonest.


If we're talking about motives and proof, then The fact that you understand what you said is harmful and you choose to do it anyway is the legal definition of intent.


Nowadays it is impossible to be humorous without alienating someone. For any attempt at humor, I can find someone who will feel oppressed.


Its never been possible to be humorous without content that would alienate someone; nowadays, its just that communication is more ubiquitous so you're more likely to reach that person and hear back from them.


It seems as though individuals who don't want to feel bad about their weight and gender might also feel that LYAH is not the place to look.

I guess LYAH and I just aren't a good "culture fit."

It's a real shame too -- without these completely unnecessary comments that add no value, this is an excellent way to learn Haskell! I've become comfortable with my whale-like properties and I'm male, so I had the lovely privilege of learning from this particular resource. It would be great if people not in my position could too.

Maybe the author did some research and determined that the added "humor" and "casual attitude" engages more readers than it turns away. I'd still want to know the demographics of both groups involved, because I suspect one of the groups looks a lot like me and the other does not.


I feel like some time in the 90s, people got this idea in their head that their sensitivities should be everyone's problem. Since you exhibit this, can you explain why? I'm super curious.


Because for most of the cases people really care about, it's easier for you to change your language then it is for every offended person to not feel upset when you offend them.

This might not be the case if there's a downside to the alternative language, or if the feeling of offense is unreasonable, but this is a decision you should actively make, not passively dismiss as "not my problem".

In this case, I think the language could easily have been changed without significantly weakening the text.


That's a pretty common feeling, and one that I certainly had as I entered college. What finally changed my mind was four years of gender studies classes.

So let me do my best to provide something of an explanation. It isn't really a problem that there's one tutorial or one website that pokes fun at weight issues or assumes it is serving a primarily male audience. The problem comes when those tropes become universal, or at least fairly wide-spread.

Sexual harassment might be a good place to look for examples. A single sexual comment or a single locker-room butt-tap, in most cases, is not that big a deal. But these small acts don't happen in isolation! They happen in a context that has structurally disadvantaged[1] entire classes of individuals (predominately women, in this case). And no, these acts are not the only thing that created such a structure, but they work to make individuals in those classes feel uncomfortable, threatened, and generally unsafe. That's why you'll often hear such acts called "micro-oppressions." And they don't just make their victims feel bad. They also teach the privileged class that the victims belong to a class that it is OK to denigrate. No, not on their own, not in isolation, but in combination and spread over enough time.

As an upper-middle class, cis white male who dates women, I didn't really buy this argument until I had a very particular experience. I was at my university's gym using a cardio machine, and some very muscular athletes were lifting weights behind me. I had forgotten my earbuds that day, so I could hear what they were saying. Mostly, they talked about women and parties. But eventually, they started talking about how all the "non-athletes" on campus really hurt the aesthetics of the place. "Especially those CS majors with their screen-tans," I recall one saying. This turned into a myriad of jokes that I felt were absolutely directed at me personally. They commented how "tech types" only show up to the gym to do cardio and always wear "ridiculous T-shirts with company logos on them," which, at the time, I was. I tried to ignore it, to just have "tough skin," but as they kept talking it slowly wore me down. I left, took a shower, and headed to the computer lab and had a great conversation about Golang.

Now imagine you didn't have a computer lab to go to. That no matter where you went, you had to hear those comments and those jokes. Every time you went to work, you'd hear it from your boss. Every time you turned on the TV, you'd see it in ads and in sitcoms. On billboards, on the street, in movies, and even in programming language tutorials.

Further, imagine that if you were to ever speak up and talked about what was making you uncomfortable, you'd be told to "grow tougher skin" or "just learn to take a joke". Personally, I can't even imagine what it must be like to live life as one of the classes that America structurally oppresses. But I feel like it must suck. A lot.

So what can we do? Well, we start shifting the culture. We start creating safe spaces. We hold people accountable for their comments and jokes while understanding that they didn't mean any harm. We educate and explain.

But most importantly, and I cannot stress this enough, we need to listen. We need to listen to people when they tell us that we are doing something that bothers them. We need to understand how our actions transform spaces that we love -- like functional programming -- into hostile areas for so many people. Because honestly, if we don't listen, we won't know. The author of LYAH isn't a bad person. Those athletes weren't bad people. No one does this sort of thing intentionally.

Yet we have to take responsibility. We have to learn, we have to get better. And the only way to start doing that is to make everyone's sensitivities our problem.

edit -- Perhaps I'm wrong. I'm open to that possibility. I'm the product of a very liberal gender studies education from a university in Arizona, where there were plenty of examples of undeniable xenophobia and homophobia. After all, if the sum of our experiences doesn't fully constitute us, it certainly plays a big role.

[1] It is very difficult to argue that this isn't the case, considering the wealth disparity amongst men and women, especially in the tech industry. If you've got yourself deeply rooted in some sort of MRA thing, then just think about race instead. Wealth disparity between white and black men is pretty wide.


I feel like you're trying to be a dick. Since you're doing this, could you explain why? I'm super curious.


Also the author is not from the US, so you can’t sue him to terrorize him with opinionated morals.


I always have been interested on haskell.... but it doesn't look to be enough practical. For example there is almost no information about how to write a smartphone videogame in haskell, even if it possible to trasnpile it to C or to Javascript. It is possible to interoperate with the host language? Does it perform well for high performance activities? Is it possible to isolate some kind of events in a thread?

Edit: This lack of practical approach is what makes me hesitate in contrast to clojure (just to mention a language), especially if the only goal is to become again a "better developer" rediscovering functional terms and abstractions also documented in other languages.


Your fears are not warranted. Haskell is the most practical of the "research languages" out there, it's very mature and has good facilities for interfacing with the "real world".

> For example there is almost no information about how to write a smartphone videogame in haskell

This has been done before but most of the "hard stuff" here is getting your game built and deployed on a smartphone. You can find Haskell for Android articles if you look around.

There are examples of game programming in Haskell too.

> It is possible to interoperate with the host language?

There is no concept of "host" lanugage, Haskell emits native code.

You can call native code from Haskell and Haskell code from C or other native languages.

> Does it perform well for high performance activities?

Haskell is good enough for most "high performance" activities (it's one of the highest performing high level languages according to the debian shootout), but caveats may apply with long running processes and garbage collection, etc.

> Is it possible to isolate some kind of events in a thread?

Yes. Haskell has very nice threading facilities and high-level concurrency primitives, including stuff similar to "channels" from golang.


> For example there is almost no information about how to write a smartphone videogame in haskell, even if it possible to trasnpile it to C or to Javascript.

These guys are doing it pretty seriously: http://keera.co.uk/blog/all-posts/

And frankly a smartphone videogame is a pretty specialized use case; a lot of pretty mainstream languages (perl?) don't have a good story for how to do that. In fact I've never heard of anyone writing a smartphone game in Clojure - I guess you could do one for Android since it's just java bytecode, but does anyone?

"Practical" for most programmers is server-side business apps, and Haskell is very very good at those.

> Does it perform well for high performance activities?

Yes, very much so.


Regarding Clojure, yes it's done. I haven't kept up with the latest clojure on android news, but https://play.google.com/store/apps/details?id=com.friendlyvi... has been around for a while and I think the author just built off of libGDX. There's also exciting work on Unity integration: http://arcadia-unity.tumblr.com


I would not say that Haskell is currently ideal for writing native smartphone apps. It's possible and people are working on making it easier, but it's rough territory still.

Javascript is easier, ghcjs (while still a bit tricky to install) is 1.0 and lets you compile arbitrary GHC Haskell (including all extensions, lightweight threads and STM) to JS for both Node.js and the browser. Template Haskell support is on the way too.

Calling the C FFI from Haskell is fairly trivial in my experience. If you have structs you want to manipulate from inside haskell it's a bit cumbersome and confusing initially, but if you're just using primitive types and pointers it's easy.

Haskell does very well for high-performance when it comes to IO, as-of GHC 7.8's new IO manager the fastest Software-Defined Networking (SDN) application is written in Haskell [1]. In terms of pure computation bound performance Haskell, does well enough, optimising truly high-performance Haskell is as much arcane art as optimising C (we're talking "I want microsecond inner-loops" level of optimising). In general I would say that you should expect Haskell to be around JIT Java levels of speed for most cases where the code is not blatantly inefficient. So certainly an order of magnitude faster than python/ruby.

Lots of people complain about performance reasoning in Haskell being hard, which is partially true. But mostly, IMO it is simply different from doing so in C, so you need to unlearn/relearn all your performance tweaking skills.

As for Haskell vs Clojure and becoming a better developer. I think Clojure looks like an interesting language, but I would recommend learning Haskell anyway. Why? Because Haskell is one of the "most different" languages in which people are still writing lots of real world code. Which means that it will expose you to the largest number of new concepts while still having decent practical library support. Key features, IMO are: Purity, type system, laziness, and type classes.

Incidentally, I would urge everyone to please stop using this silly "transpile" word. Compile is already source-to-source and introducing a new silly sounding word for it isn't helping anyone.

[1] - http://haskell.cs.yale.edu/wp-content/uploads/2013/08/hask03...


Lots of people complain about performance reasoning in Haskell being hard, which is partially true. But mostly, IMO it is simply different from doing so in C, so you need to unlearn/relearn all your performance tweaking skills.

I don't agree. First, of all, the naive solution in C is often pretty fast, while the naive solution in Haskell often has obnoxious runtime properties.

Then, most C optimization performance reasoning applies to Haskell as well: keep your data small, in contiguous memory, etc. The first thing that complicates optimization in Haskell is that defacto Haskell data structures are the opposite: pointer/thunk-rich. So, you usually end up with libraries such as 'vector', doing the heavy lifting in the ST monad.

Then, laziness adds even more complications, both in that it adds a new class of bugs (of course, Haskell removes buffer overflows et al.) which tend to be relatively hard to debug (the heap explodes in less expected places).

When you write production code, you usually accumulate some monads. Unfortunately, the relatively obvious way to use multiple monads (monad transformers) is slow. So, you have to roll your own monad stacks:

https://wiki.haskell.org/Performance/Monads

---

In the end, even something as simple as reading a list integers in the IO monad can be an exercise in frustration:

http://www.joachim-breitner.de/blog/620-Constructing_a_list_...

The same can't be claimed for C. Even a newcomer could do it.


> In the end, even something as simple as reading a list integers in the IO monad can be an exercise in frustration

Only if you need it to do it in less than 164616 bytes, otherwise I'd just use:

    replicateM 1000 (return 42)


I enjoyed working through this book. Actually it helped me learn enough Haskell to realize that I wasn't that interested in it. I found that it wasn't as safe as it claimed to be and that the tooling was not very good. There are some refreshing and interesting ideas, but overall I'm not sure it was worth my time.


> I found that it wasn't as safe as it claimed to be and that the tooling was not very good.

How was Haskell not "as safe as it claimed to be"? What tooling was not very good? What tooling was missing for you?


* Non-exhaustive patterns error was disappointing after being told that "if it compiles it will run". It seems to be the Haskell equivalent of NullPointerException (I'm told OCaml doesn't have this problem).

* Cabal Hell: https://news.ycombinator.com/item?id=8011267

* Installing libraries is slow

* The Haskell platform is not batteries included

* JSON parsing seem to be more complicated than it needs to be

* Also got confused by keywords naming: https://news.ycombinator.com/item?id=5689951

* I found Yesod API to be inelegant. I found it odd that it needs so many non-standard compiler extensions, which might be a sign that the language is not expressive enough.

* One-letter variables seem to be idiomatic. This is unappealing to me because I try to make my code readable.

* For the same reason, frequent use of special characters in operators (, <>, ///, etc.) in the standard library and in third-party libraries was not appealing.

I was disappointed because I was attracted by referential integrity, strong compiler checks, pattern matching and function composition but overall I was left with the impression that the Haskell environment was not very well polished from a software engineering point of view.


> Non-exhaustive patterns error was disappointing after being told that "if it compiles it will run".

Yes, it's somewhat strange this is only a compiler warning rather than a compiler error.


I agree, I would prefer that it was an error as well. For my personal projects I use -WError, but sane defaults count for a lot.


> * Non-exhaustive patterns error was disappointing after being told that "if it compiles it will run". It seems to be the Haskell equivalent of NullPointerException (I'm told OCaml doesn't have this problem).

I agree that this should be an error by default, however -Wall would fix this issue for you now.

> * Installing libraries is slow

It is slow, but can be made much faster by using "cabal install -j${num_cpu_cores}". I also use -O0 to disable optimizations during development.

There is also Halcyon, which I believe allows you to do some caching of libraries.

A little more extreme (but complete imo) solution is to use the nix package manager or if you want to go all in, NixOS.

> * The Haskell platform is not batteries included

I keep going back and forth on how I feel about this. It's harder in the beginning because you aren't sure what to use. Once you get a feeling for what libraries are best though, it's a great advantage that those libraries move forward so quickly without being tied to GHC development practices which have to move more slowly.

> * JSON parsing seem to be more complicated than it needs to be

Really? Here is some JSON parsing code I wrote the other day[0] to show how pattern matching and exhaustiveness checks in Haskell are useful:

    {"purchaseType": "Rent","price": 0.99,"title": "inception"}
Here is an implementation in Haskell:

    {-# LANGUAGE DeriveGeneric #-}
    {-# LANGUAGE OverloadedStrings #-}
    
    import Data.Aeson
    import GHC.Generics
    import qualified Data.ByteString.Lazy as BL
    
    data PurchaseType = Free | Rent | Buy | Subscriber deriving (Show, Generic)
    instance FromJSON PurchaseType
    instance ToJSON PurchaseType
    
    data Media = Media { title :: String, price :: Float, purchaseType :: PurchaseType} deriving (Show, Generic)
    
    instance FromJSON Media
    instance ToJSON Media
    
    jsonData = "{\"title\": \"inception\", \"price\": 0.99, \"purchaseType\": \"Rent\"}"
   
    main = print $ (decode jsonData :: Maybe Media)
    -- running main gets:
    -- λ> main
    -- Just (Media {title = "inception", price = 0.99, purchaseType = Rent})
> * Also got confused by keywords naming: https://news.ycombinator.com/item?id=5689951

Those are just things you have to get used to and imo don't really seem like a big deal. Every language has these kinds of things, but Haskell has less than most. To qualify that last statement, once you've learned their very different set of abstractions you know everything you need to know. It is less work in general dealing with programmer defined abstractions built on top of functor, monoid, etc because those custom abstractions more closely resemble them, which is an effect of them having to follow laws.

> * I found Yesod API to be inelegant. I found it odd that it needs so many non-standard compiler extensions, which might be a sign that the language is not expressive enough.

Looking at a Yesod example[1], the most language extensions I saw were:

    {-# LANGUAGE MultiParamTypeClasses #-}
    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE TemplateHaskell #-}
    {-# LANGUAGE TypeFamilies #-}

TemplateHaskell and OverloadedStrings are both just conveniences, I suppose there could be an argument that MutliParamTypeClasses and TypeFamilies mean the language is not expressive enough. One of the reasons for use of language extensions so much in Haskell is that it is designed by committee, it's quite possible that other languages might have already deprecated these language extensions and moved them into the core language.

> * One-letter variables seem to be idiomatic. This is unappealing to me because I try to make my code readable.

The only place I usually see one letter variable names is where it's quite obvious what they are. I don't think anyone would argue it's better to use something besides x and y in this function definition for instance:

    add x y = x + y
To check out your claims, let's grab a few random snippets of code (I'm hitting the spacebar randomly then choosing first function I see) from the most popular[2] Haskell libraries:

containers[3]:

    isSubmapOf :: (Ord k,Eq a) => Map k a -> Map k a -> Bool
    isSubmapOf m1 m2 = isSubmapOfBy (==) m1 m2

bytestring[4]:

    -- | Add a list of non-negative numbers.  Errors out on overflow.
    checkedSum :: String -> [Int] -> Int
    checkedSum fun = go 0
      where go !a (x:xs)
                | ax >= 0   = go ax xs
                | otherwise = overflowError fun
              where ax = a + x
    go a  _         = a
directory[5]:

    setOwnerReadable :: Bool -> Permissions -> Permissions
    setOwnerReadable b p = p { readable = b }
What I personally take from above is that while Haskell does use single letter variables, the types make it obvious what those variables are. As a test, I'll go to the next popular library and look for a longer function to see if this line of thought breaks down.

text[6]:

    fromString :: String -> Builder
    fromString str = Builder $ \k (Buffer p0 o0 u0 l0) ->
        let loop !marr !o !u !l [] = k (Buffer marr o u l)
            loop marr o u l s@(c:cs)
                | l <= 1 = do
                    arr <- A.unsafeFreeze marr
                    let !t = Text arr o u
                    marr' <- A.new chunkSize
                    ts <- inlineInterleaveST (loop marr' 0 0 chunkSize s)
                    return $ t : ts
                | otherwise = do
                    n <- unsafeWrite marr (o+u) c
                    loop marr o (u+n) (l-n) cs
        in loop p0 o0 u0 l0 str
      where
        chunkSize = smallChunkSize
Alright... str is obviously string, marr is mutable array.. o, u, and l... what could those be? Well it's getting set from the Buffer type, so it looks like I'll have to see what the type of that is.

    Prelude GHC.IO.Buffer> :i Buffer
    type role Buffer phantom
    data Buffer e
      = Buffer {bufRaw :: {-# UNPACK #-} !RawBuffer e,
                bufState :: BufferState,
                bufSize :: {-# UNPACK #-} !Int,
                bufL :: {-# UNPACK #-} !Int,
                bufR :: {-# UNPACK #-} !Int}
             -- Defined in ‘GHC.IO.Buffer’

    Prelude GHC.IO.Buffer> :t Buffer
    Buffer
      :: RawBuffer e -> BufferState -> Int -> Int -> Int -> Buffer e
I'll concede that names other than o, u, l, and k would have helped here. Perhaps even renaming ts as texts would have been more clear.

> * For the same reason, frequent use of special characters in operators (, <>, ///, etc.) in the standard library and in third-party libraries was not appealing.

"Special characters" in operators? When most people say special characters they mean unicode. <> and /// look to be normal characters to me. With that said I go back and forth between finding operators appealing/unappealing. For instance I find this to be understandable and a good choice:

    "home" </> "cody" </> "Downloads"
I also think that making users learn a few symbols isn't so bad, as long as you don't go to far. The main symbols I'd say you need to know are >>=, <$>, <>, and maybe <> and >=>. >>= doesn't have a non-symbol alternative I don't believe, <$> is fmap, <> is ap, <> is mappend, and I'm not sure if >=> has a non-symbol alternative.

> I was disappointed because I was attracted by referential integrity, strong compiler checks, pattern matching and function composition

Those are many of the reasons I was attracted to Haskell and still use it today, are you claiming Haskell doesn't have those things? If you are making that claim just because exhaustiveness checking isn't an error by default, I'd say that seems disingenious.

> but overall I was left with the impression that the Haskell environment was not very well polished from a software engineering point of view.

Was it just the above that left you with that impression, or was it other things as well? Can you give an example of a language that is well polished from a software engineering point of view and what makes it "polished"?

0: https://news.ycombinator.com/item?id=9037452

1: https://www.fpcomplete.com/school/project-templates/file-ser...

2: http://kwangyulseo.com/2014/02/03/top-30-haskell-pakcages-wi...

3: http://hackage.haskell.org/package/containers-0.5.6.3/docs/s...

4: http://hackage.haskell.org/package/bytestring-0.10.4.1/docs/...

5: http://hackage.haskell.org/package/directory-1.2.1.0/docs/sr...

6: http://hackage.haskell.org/package/text-1.2.0.4/docs/src/Dat...


Cheers for the long and thoughtful reply :-)

In fact of all the points I was raising, only the first was about the core language. It's more the ecosystem and some cultural aspects that bothered me. To take a symmetrical example, JavaScript has great tooling and community despite being a language with countless flaws. Over the years, Python and Ruby ecosystem have gotten pretty OK. Go, Clojure and Elixir are younger and have learned from previous languages, their tooling is not as extensive but they're starting on firmer ground. I'm not sure how to define what makes a well polished software development environment, it's a good question really. I suppose one could write books about subject. But Haskell gave me a fuzzy feeling that things were cumbersome and sometimes buggy. Package management was the show stopper for me. I'm glad Haskell exists and people enjoy coding in it but for me after a while it wasn't that fun so I went to do other things. My arguments are shallow and are more like opinions, but if you care to spread Haskell usage, maybe you can hear them nonetheless.

>> I was disappointed because I was attracted by referential integrity, strong compiler checks, pattern matching and function composition > Those are many of the reasons I was attracted to Haskell and still use it today, are you claiming Haskell doesn't have those things?

No sorry I phrased that bad. It think Haskell has those things.


> Cheers for the long and thoughtful reply :-)

I just want to help myself and everyone to have the right information so we can all make the best decisions for ourselves ;)

I get the feeling and I've had it before as well, mostly due to cabal hell. I've found it to be the biggest culprit of making the entire language buggy, but now that I'm using nixos for example I don't feel it anymore.

I can't expect everyone that wants to use haskell to switch to using a different package manager I guess, but I also hear that Halcyon and Haskell LTS (from stackage) solve this problem.

As for the future, I believe this will be the solution until other (partial?) solutions in the works such as backpack (ML like module system) are finished.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: