So I had a post about my frustrations on programming languages some time ago (the actual date of the previous article on the topic is not right, because I did some blog switching foo since). With this article I try to rethink the whole problem. My conclusion will be different from the conclusion of the previous article!
Haskell, Racket and the others
So, I said in the last article that I want to have a look into the following programming languages:
And well, I learned a bit of Haskell and it is an awesome language from what I can see so far. But then things changed, I started a semester project I’m now heavily involved in, which is in C. I also had several programming courses at my university where the requirement was C++ and Java, so things got stuck somewhere. I stopped learning Haskell. Sadly.
But in the past few days and weeks, I got my head into a new programming languages, as the careful reader of this blog already knows: Racket. Racket is a Lisp dialect. I comes with an wonderful documentation, a rich feature set (a nice REPL, a documentation tool, package manager which works really well and tries to avoid the dependency hell), is fast and easy to both read and write (at least from what I can tell by now). Racket is kind of my new love in manner of programming languages. I started learning it by implementing problenms from project euler and I want to write a small IRC bot in it, as soon as I consider myself as advanced enough to achieve this.
So, Racket is a functional programming language, but also supports non-functional programming paradigms. This basically means that you also can write OOP-stylish and imperaitvely in Racket. You might say “Yuck!” now, because it is not a pure functional language - but it is really good for me, and I can get my feet wet with functional programming slowly! This matters most for me!
The other languages listed are less important for me. I don’t want to learn Go, D or even Crystal anymore. I think, functional programming languages are my next (kind of) goal in life. A lot of people state that they became better programmers after learning a functional language (Haskell in particular). And because my overall goal is to become better at what I love doing, I consider functional programming as one of my main goals in life now. That may sound really vain or limited, but well, I also have other goals in life! They just don’t fit into this article, of course!
My goal is still learning Haskell some time, and I will, as soon as I consider myself a good Racket hacker! But for now, Racket has a better learning courve for me. I read a lot about the functional programming languages out there, mainly Lisp/Scheme like languages and Haskell. And a lot of people state that Haskell is a bit more advanced because of its syntax, because you have to consider operator prescendence and some other things, which you don’t have to care about in Lisps. So, I can start with a simple language, learning the functional approach, and continue with something like Haskell afterwards.
I saw a wonderful explanation on youtube on Monads just yesterday. I understand everything in this video, except the fourth part, which actually covers Monads. This is also one of the points why I don’t start away with Haskell. I want to fully understand the concepts first.
It would be really great to have a course about functional programming at my university, but unfortunately there is none. One Prof has a by-choice-event students can subscribe to, but unfortunately not this or next semester. I hope I will be able to attend the course in one year.
If not, I hope I can do something with functional programming in my bachelors thesis or in my masters degree, if I continue studying. Would be neat. If not, there are maybe some non-university courses around.
But is Racket fulfilling?
Of course it is! You can actually do everything you can do in pure functional programming languages! I just found out how to do function composition and partial application of functions. It is not as simple as in Haskell, but it works exactly the same way (don’t consider my statements here too serious, I’m just learning and it feels like it is the same…).
For example, we have this smart piece of Haskell code here:
take5 = take 5
take5 is now a function which is composed of passing
5 to the
function. It takes now 5 values from a list and returns them as new list.
Wonderful and simple!
But you can also do this in Racket. I don’t know how to do this problem in
Racket, as the
take function in Racket expects the list as first argument
and the number as second. So would need to switch arguments, and I actually
don’t know how to do this in Racket.
So lets do another example of partial application:
(define (add1-to-list) (curry map add1 )) (add1-to-list (list 1 2 3)) ; -> '(2 3 4)
As you can see, I created a function which returns a function that maps the
add1 function on a list. Afterwards I applied this function to a list. So it
is the same as in Haskell, but with a bit more verbosity, of course.
Side-note: I just found out (thanks to the Racket IRC channel) how to do flipping of arguments:
(define-syntax (flip stx) (syntax-case stx () [(_ f x ...) #`(f #,@(reverse (syntax->list #'(x ...))))]))
That’s the syntax rule, but it is very verbose. Using it is rather short:
(flip / 12 4) ; -> 1/3
But not as nice as you can do it in Haskell. But anyways, that’s hairsplitting and I will end this here and now.
- Racket is awesome.
- Haskell is Awesome.
- Functional programming is awesome.
So, to finallize this article now: I’m learning functional programming! It is awesome, concise and clean. It seems to be the best approch to abstract complex problems and address the problem of complexity and abstraction (wanna know more about this, watch the linked youtube video)! I’d love suggestions on tutorials, papers and other reading material to get better. Feel free to send me everything you might consider as a good starting point to get my feet even more wet.