I can sympathize with this preference. When I first started learning Haskell, figuring out how to make something point-free was extremely satisfying. And it also increases DRY, which is generally a good thing.
But over time I realized I was overusing point-free style. It was fun to write, but harder to read. If I were actually writing "inexactMatches" for something real, I would strongly prefer the first over the second. From what I've read, I think many people take a similar path when learning Haskell.
That said, I think everyone has a different threshold. For example, I've heard many people say that a for loop is more clear than something like "map" or "fold". I would disagree with that, but maybe that's just because I've gotten used to "map" and "fold".
So maybe the author's brain is just able to handle point-free style better than mine can, but I do think this particular example if far enough on the spectrum that most Haskell programmers would prefer the first version (for real code).
So if you're considering learning Haskell, don't be scared away. You will have to start getting used to point-free style, but probably not to this extreme.
You're going to spend all that work using "the author" everywhere and still manage to get my gender wrong ("his")? Okay. I don't really expect any different in this field, but just noting that.
Anyway, I'm well-aware of the temptation of writing point-free code. I did include the sentence "I can see the road to hell is paved with point-free style" myself, after all. I wouldn't prefer point-free style if it ends up looking indiscernible, but in this case I sort of wanted a way to express semi-declaratively "this function is the difference between these other two functions". Does the version I ended up with do that? Yes. But for all I knew there could have been a much better, more idiomatic way.
But yes, that was both a quest to improve that code and a mere learning exercise. I'm satisfied with the version I ended up with, though I don't think it's perfect, either.
I guess it goes like this: at first you don't understand a particular construct (pointfree style, monads.) Then when you kinda get it you tend to apply this new tool to everything. After a while it just get "downgraded" to its right place: just another useful tool in your programmer's toolbox.
In the case of pointfree style, there's a code golf aspect to it as well, it's kinda fun trying to rewrite a particular expression to eliminate variables and maximize the amount of non-alphanumeric characters!
> It feels a little redundant to have to manually list out all the elements when the information is known statically, and updating the list will be necessary if the Peg type changes. In Racket, writing a macro for this would be trivial, but alas, this is Haskell. Perhaps there is a way, I’m just not aware of it.
A reasonably clean way would be to define
data Color = Red | Green | Blue | Yellow | Orange | Purple
deriving (Enum, Bounded, Show)
Yep, I posted this on r/haskell and someone pointed this out, which is cool. The provided type for Peg didn't derive Enum or Bounded, but it's a good trick to know.
Great read. I've finally taken the plunge and have spent the last 3 weeks extensively studying Haskell in the evenings. My first attempt was a couple years ago, but somewhere between then and now I've grokked something mysterious and it's been easier to dig into. The last 6 months or so has been something like Common Lisp -> Racket -> Haskell, which may have contributed a little.
My long term goal is to write a realtime game server with it, however, I keep flopping back and forth between wrapping my head around the high learning curve and jumping to something more familiar to Get Things Done. It seems the payoff for learning Haskell is intrinsic in and of itself even if I never end up using it, yet I can't help but wonder if I'm spending my time wisely.
This was a great read, I'll be passing it along to anyone wanting to learn Haskell so they can get a good feel for what it's like.
You had some advantages though since you've used Racket in the past.
I feel like your Racket experience helped you draw conclusions that many wouldn't have otherwise. Great work though, I hope you write about more of your experiences.
I'm curious what conclusions you'd say those are... and if they're good or bad conclusions?
That said, I'm sure I'm totally influenced by various languages I've tried in the past. And FWIW, Racket was also plenty far from my first experience with functional programming. I know so many programming languages that I've gotten pretty used to being able to just "pick them up" in a couple of days (Racket pretty much included).
I really enjoyed reading what you've written so far, and I'm hoping you continue to write more.
It was really refreshing to see somebody write about the struggle to pick up Haskell - indeed, I had a lot of the same issues. I often feel the Haskell community is burdened with this stigma of "if you have to ask questions, you're probably too stupid to get it". This is despite the fact that there is actually a really great group of people always willing to help in #haskell. It's primarily an image problem, one a lot of FP languages suffer from.
We need more articles talking about the pain points of Haskell so we can get better at making this stuff accessible. We need to be honest with new starters, tell them it's okay to find this stuff challenging and show them where to find help. More than that, though, we need to think about what we can do in the language to fix some of these pain points in a way that the community is happy with.
Looking forward to reading this too. For the opposite trajectory (Haskell towards Racket) see this page from a little while back: http://artyom.me/learning-racket-1
Aha! I thoroughly enjoyed reading all that, and do hope you continue. It sounds like you're at or slightly ahead of my level of Haskell experience (I knew you'd need Eq before you did! But then the Applicative stuff was beyond me...), so this is very insightful for me as I wonder whether to try picking it up again.
"Fine. It's good enough. Moving On." made me laugh! It seems like you thought that could be refactored in a much simpler way. Not knowing (much) Racket, it didn't appear super obvious to me how. Were you alluding to a macro or something? How would you do it in Racket?
Ah, no, I probably wouldn't do it any simpler in Racket. Racket tends to de-emphasize more complicated function composition, which tends to serve it just fine. I've always adopted a somewhat pro-functional approach in my usage of the language, but even here there wouldn't really be a distinctly better way to do it.
I guess I was just hoping that Haskell, being a more composition-oriented language in many ways, would have some nice built-in to do that for me.
That was an interesting read for me, because I started off with How to Design Programs + Racket, before switching to Haskell.
(I would count Haskell as my first 'proper' language, and prior to all this, I had zero coding experience.)
I experienced a lot of the same detours that you have gone through.
re: point-free code
There's a plug in that you can use, called pointfree (cabal install pointfree). I found that it was more useful to me for experimenting with point-free style than writing my own code in that way.
From a PHP background, I've also been trying out haskell in the evenings, my guide being the learn you a haskell book[1]. So far so good, I've started a little blog[2] to clarify bits that sort of seem confusing to me.
[+] [-] cakoose|11 years ago|reply
But over time I realized I was overusing point-free style. It was fun to write, but harder to read. If I were actually writing "inexactMatches" for something real, I would strongly prefer the first over the second. From what I've read, I think many people take a similar path when learning Haskell.
That said, I think everyone has a different threshold. For example, I've heard many people say that a for loop is more clear than something like "map" or "fold". I would disagree with that, but maybe that's just because I've gotten used to "map" and "fold".
So maybe the author's brain is just able to handle point-free style better than mine can, but I do think this particular example if far enough on the spectrum that most Haskell programmers would prefer the first version (for real code).
So if you're considering learning Haskell, don't be scared away. You will have to start getting used to point-free style, but probably not to this extreme.
[+] [-] lexi-lambda|11 years ago|reply
Anyway, I'm well-aware of the temptation of writing point-free code. I did include the sentence "I can see the road to hell is paved with point-free style" myself, after all. I wouldn't prefer point-free style if it ends up looking indiscernible, but in this case I sort of wanted a way to express semi-declaratively "this function is the difference between these other two functions". Does the version I ended up with do that? Yes. But for all I knew there could have been a much better, more idiomatic way.
But yes, that was both a quest to improve that code and a mere learning exercise. I'm satisfied with the version I ended up with, though I don't think it's perfect, either.
[+] [-] draven|11 years ago|reply
In the case of pointfree style, there's a code golf aspect to it as well, it's kinda fun trying to rewrite a particular expression to eliminate variables and maximize the amount of non-alphanumeric characters!
[+] [-] throwaway183839|11 years ago|reply
A reasonably clean way would be to define
and then (e.g. in ghci) you can do I often define the useful function for exactly this purpose.[+] [-] lexi-lambda|11 years ago|reply
[+] [-] bojo|11 years ago|reply
My long term goal is to write a realtime game server with it, however, I keep flopping back and forth between wrapping my head around the high learning curve and jumping to something more familiar to Get Things Done. It seems the payoff for learning Haskell is intrinsic in and of itself even if I never end up using it, yet I can't help but wonder if I'm spending my time wisely.
[+] [-] codygman|11 years ago|reply
You had some advantages though since you've used Racket in the past.
I feel like your Racket experience helped you draw conclusions that many wouldn't have otherwise. Great work though, I hope you write about more of your experiences.
[+] [-] lexi-lambda|11 years ago|reply
That said, I'm sure I'm totally influenced by various languages I've tried in the past. And FWIW, Racket was also plenty far from my first experience with functional programming. I know so many programming languages that I've gotten pretty used to being able to just "pick them up" in a couple of days (Racket pretty much included).
Haskell... not so much.
[+] [-] nathankleyn|11 years ago|reply
It was really refreshing to see somebody write about the struggle to pick up Haskell - indeed, I had a lot of the same issues. I often feel the Haskell community is burdened with this stigma of "if you have to ask questions, you're probably too stupid to get it". This is despite the fact that there is actually a really great group of people always willing to help in #haskell. It's primarily an image problem, one a lot of FP languages suffer from.
We need more articles talking about the pain points of Haskell so we can get better at making this stuff accessible. We need to be honest with new starters, tell them it's okay to find this stuff challenging and show them where to find help. More than that, though, we need to think about what we can do in the language to fix some of these pain points in a way that the community is happy with.
[+] [-] ics|11 years ago|reply
[+] [-] lexi-lambda|11 years ago|reply
[+] [-] losvedir|11 years ago|reply
"Fine. It's good enough. Moving On." made me laugh! It seems like you thought that could be refactored in a much simpler way. Not knowing (much) Racket, it didn't appear super obvious to me how. Were you alluding to a macro or something? How would you do it in Racket?
[+] [-] lexi-lambda|11 years ago|reply
I guess I was just hoping that Haskell, being a more composition-oriented language in many ways, would have some nice built-in to do that for me.
[+] [-] mayisnotacake|11 years ago|reply
(I would count Haskell as my first 'proper' language, and prior to all this, I had zero coding experience.)
I experienced a lot of the same detours that you have gone through.
re: point-free code
There's a plug in that you can use, called pointfree (cabal install pointfree). I found that it was more useful to me for experimenting with point-free style than writing my own code in that way.
[+] [-] kamweti|11 years ago|reply
[1] http://learnyouahaskell.com [2] http://haskellrecipes.tumblr.com
[+] [-] iopq|11 years ago|reply