If you are interested in reading this article in Spanish, check out my blog The Developer's Dungeon
As you probably know if you read my previous article, I am not a functional programmer, far from that. My real-world experience lies all behind the courting of Object Oriented Development. Well no more, I decided that I wanted to check what it is all the cool kids are talking about, see for myself if the benefits are real or just rumors.
This is all easier said and done as I would soon found out.
There are so many flavors of functional programming that I did not know which one to pick. I first read Structure and Interpretation of Computer programs and I really liked the Lisp type syntax, so Clojure was brought to my attention. I am also a C# developer so naturally, F# was mentioned multiple times... and after I read Mostly adequate guide to functional programming the idea that JavaScript could be enough for this journey was on the table too.
In the end, I picked the 'Hard Road', I wanted someone that would hit me in the face if I even thought about doing anything in an Object Oriented or Structured way, so that is how the holy grail of functional programming appeared.
Haskell
This is the first time I am learning anything remotely related to functional programming, the first time learning a language that has no C styled syntax and also the first time I don't have a real-world project I can jump in to get dirty immediately.
So the beginning was not easy, I searched forums and blog posts and it seemed like there was not a unified tool or IDE that could help a clueless guy like me, my most similar finding was Haskell for mac IDE. After spending half a day installing things that would not work on VSCode I decided to put out my wallet and just buy the damm thing.
As multiple people suggested, I started following Learn you a Haskell for great good and to be honest, I haven't had such a hard time reading a book and trying to learn something new in ages, although I understand the basic concepts about functional programming and pure functions, referential transparency and shit, every time I want to solve something on my own without looking at the book my mind gets blank.
I don't quit easy but I was shocked when I realized how slow I was making progress, so slow that I had a meltdown on twitter asking others if this was normal or if I was doing something wrong.
After struggling another extra day with the IDE and tooling -actually 2 IDEs, Intellij with the Haskell plugin for "Real Development" and Haskell For mac for testing and using the REPL- I started reading the comments I got on twitter and discovered some really nice extra resources:
- Zero Bullshit Haskell
- Haskell programming from first principles
- Exercism.io Haskell Track
- Dive Into Haskell
- Category theory book
- A Type of programming
I also received some encouraging words that made me realize the way I was feeling was perfectly normal. That is when it hit me: I haven't felt this way since I was starting to learn programming, indeed learning Haskell and functional programming is like learning everything all over again.
No variable assignation, no loops, no mutable state, no classes or objects, recursion? hello world?
Slowly I am starting to write my own functions:
I still cannot write anything to the console, I don't know how to, but that didn't prevent me from starting modeling my own SnakeGame
I know what you are thinking, is there anything positive you can say to me? You are not selling me this adventure of yours dude.
I can only tell you what I noticed in my short experience:
- Instead of modeling complicated classes representing domain objects with methods that would represent behavior and considering encapsulation, the code I produced so far naturally moves towards very very very small functions and because of the small composable functions it seems very hard to actually break the Single Responsibility Principle
- Instead of writing code specifying what it NEEDS to be done I am writing code representing what things ARE, it feels very strange.
- Most of the design patterns I often use are kind of useless, why would I create a factory if I can just return a function?, why would I implement a strategy if I can just pass a function as implementation?
- Haskell's type system is much more clever than others I have encountered, it usually knows what I want to do and gets out of the way if the functions actually make sense. Because of this, it is also possible to omit certain syntax because Haskell already knows what you mean.
I have to say that it is very challenging, but it is also fascinating, I truly think that this adventure can lead me to a place I would never want to come back from.
Unless I get eaten by a dragon I will be writing often to share what I have learned in this journey 😄
Top comments (6)
Nice write-up!
This is so incredibly true. I'm interested to hear if anyone actually learned Haskell first, and it was easier because you're not un-learning too.
This is pretty much exactly the sentence I keep in my head when I sit down to write functional code, in Haskell or any other language.
I also found the only way to get my head around Haskell was to write bash my head against it until it clicked. Books only helped me to a point...you've gotta write code, which is exactly what you're doing!
For outputting to the console, you want putStr/
putStrLn
, which can be used inside any function that returns an IO monad. You'll probably also want hFlush fromSystem.IO
.My similarly-spirited experiment led to a console game of TicTacToe, here's the code if you want an example of how I handled user IO.
Thank you very much for commenting, is nice to re check that I am not the only one who struggles with this. Thank you for the resources, I will make sure to read them once I get into the IO monad, I don't want to rush thing so I am following books and coding a long the way while trying to use only what I read.
Haskell is indeed challenging, but it is fun and painful at the same time ahha.
I think you're right here too: "this adventure can lead me to a place I would never want to come back from."
I don't use much Haskell anymore, not as much as I should but the process of learning it unlocked something I've never lost - it affects how I approach all problems, even in OOP projects.
That is good to hear, for now is only a hunch. I still need to do a lot of learning and practicing before it actually changes the way I solve problems and approach different implementations on my daily OOP job.
I think for me it doesn't necessarily always affect my implementations (but definitely some of them), but it did shift how I think about problems in a general sense, and how I explore a problem I don't fully understand.
Aaa Haskell as for 'weekend programming'? 😂