musicmatzes blog

racket

This article is about the annoyance of programming language tutorials. First, I will argue why learning new programming languages always feels a bit like a pain to me. And then I will tell you why learning Rust was different.

I know a few programming languages. I've done things in C, Ruby, Java, Python, PHP, C++, Bash, Lisp (Racket, actually), Haskell, LaTeX, Nix, Make, Lua* and JavaScript*.

*: Only a bit, but still enough to say “I've done things in this language”

When I started learning programming, I learned Java and shortly after that Ruby. Both languages have their oddities, but besides their overall concept (imperative programming and object orientated programming) they are both rather easy to learn. After that I learned C. Learning C was a new world for me back then, as I only knew object orientation. I cannot remember which resources I've been using learning C, though I remember it was a pain. I had a good friend helping me, which was awesome, though I struggled a lot with the new concept.

After learning C, I did a fair amount of PHP. Learning PHP was simple (I actually did it in one weekend and a few thousand lines), though it again was a pain. It was a pain because of the tutorials and resources. And that's the point I want to discuss here.

All other programming languages I've been learning so far were painful to learn. Not because of their concepts (see Haskell, functional programming at all), but because of the resources. Haskell is a really good example here. There is exactly one resource I enjoyed while learning Haskell, and that's “Learn you a Haskell for great good”. And why? Because it takes your hand and shows you the new world. It is good because the concept of functional programming is new for most people reading this resource. Learning JavaScript, Bash, Lua or Python sucks because you already know what an object is. You know what a function or method is and you know that the basic syntax for arithmetic is the very same as in the languages you've been using by now. But all tutorials expect you start from zero – which is fine if you're actually starting from zero, but most of the time you're not. After learning Java and Ruby I understood what OOP is (actually not after learning Java, but after learning Ruby, because Java isn't a fully object oriented language in my opinion).

So, learning Haskell was kinda amazing. Learn you a Haskell is a really great book and if you want to learn Haskell, you really should read it. But what was even a better experience was learning Rust.

So why is that? It is because Rust is a new concept and the old concept (imperative programming). Learning Rust is not like learning Python after learning Ruby. It is like Learning Haskell after learning Racket. The concept behind the language is kinda the same, though it is different in most details.

Plus, the Rust tutorials and resources are freakin' awesome. Let me repeat that. The tutorials and documentation of the tools, libraries and everything, the resources on how to do things, are awesome!

Every documentation for each library looks exactly the same, which is a huge advantage over other languages library documentations. cargo, the Rust build-tool builds the documentation locally for you, if you want that. So working offline after you fetched the dependencies or your project (also via cargo) is no hassle. Building a new project with cargo is absolutely painless, its literally just executing a command, editing a textfile and executing another command (setting up the project, writing down dependencies and meta information about the project and building the project, which fetches the dependencies).

So really, if you want to learn a new programming language, check out Rust. I haven't even talked about its language features, and I will not, as this is not the goal of this article. This article is about resources and tutorials. And my conclusion is:

All programming language tutorials suck. Except the Rust language tutorial. tags: #programming #open source #bash #c #c++ #haskell #nix #racket #rust #shell

I just wrote my very first bit of racket code which actually runs somewhere. Want to find out what it is?

Well, it is a rather simple piece of code, and it helps me generating this very blog. If you visit this blog frequently, you may have noticed that the layout changed a bit. Chaning the layout was a thing I wanted to do for months and the adaptions I just did are exactly what I wanted to do all the time: Move the content in the center of the page, the lines are now shorter as the div in which the content lives got reduced in its width.

I also moved the tags and dates on the left of the articles, both on the index page and on the article pages. I really like that style. It wasn't that easy (for me as racket-newbie), because the blog engine I use (frog) has no method to insert a html-list of tags somewhere. So I coded it myself, right in the templates for the article and index pages.

Here's how I did that:

  1. First, I put everything into a subcontainer of the bootstrap layout. The date and tags (lets call it metadata) lives in a two-column-container to the left of the ten-column-container which holds the content
  2. I wrote a bit of racket code to generate a html-bullet-list out of the comma seperated list of tags frog gives me:
@(string-join
  (map (lambda (str)
        (string-append "<li>" str "</li>"))
       (string-split tags ",")))

What it does is simple: It splits the string in tags, which holds a list of tag-links by the seperator, the comma. Then it maps a lambda over the list of strings, which appends the string to "<li>" and "</li>" to that. Afterwards, the whole list gets joined together, so we have one big string left.

The template itself contains the <ul> and </ul> tags around the list. This way, I generate a nice bullet list for both the index pages and the article pages.

Unfortunately, the solution is not very DRY, as both templates contain the same code. There is no possibility to pass custom code to frog, yet. But I opened a feature request on github to include such an option (providing a pull request would be much nicer, I know – but as you already know, I'm a racket newbie and I'm not sure I can figure out such a thing myself).

tags: #blog #racket #programming

I have a problem. I want to write a small application. It should be a commandline application, but maybe I want to extend it later with a GUI or even a web interface. But I don't know what language to write it in.

This article could also be named “Which is the right tool for the job?”

The idea is simple: I want to write a journal-application, where one can take notes, tag them, query the journal for entries, optionally provide filters before printing them to print only some of them and so on.

I want to be able to encrypt them with gpg and I want to write posts to the journal with vim. I want to be able to configure these steps, of course, so I can use a certain key for encrypting the journal or maybe another editor (for these emacs lovers out there).

It should be designed to be extensible, so I can add a GUI or web interface later on. Or maybe a tex output, so I can compile a PDF out of it or something. Posts should be written in standard markdown, so this wouldn't be a big deal.

But I don't know what language to write it in. The languages which I can or would choose from are:

  • C
  • C++
  • Haskell
  • Rust
  • Java (not really...)
  • Scala (not really either, it's still JVM)
  • Ruby
  • Python (by extending jrnl)
  • Racket
  • Lua
  • Bash (I really don't want to write it in bash, but it's still a possibility)

As you can see, the first four languages are compiled languages, then Java and Scala are (lets call it) Semi-Compiled languages and the others are scripting languages. All of these languages have certain advantages over others.

The compiled languages

... have the advantages that they are fast. Haskell and Rust also have the advantages that if the compiler does not fail compiling the sources, the program just works ™.

Also, learning C++, Haskell or Rust would be a really great experience and may be beneficial later in a job or something.

The semi-compiled languages are also (kind of) fast, but they are JVM-languages, so I won't look into them here...

The scripting languages

Writing the application in a scripting language would have some other advantages: They would be much more flexible and I'd be faster writing the application (compared to Rust or Haskell, which I would need to learn with the application). I don't need to learn Ruby, I know a fair bit of Racket and I guess I can get productive with Python or Lua really fast.

Bash is another option and I'm actually an bash script for an almost similar job right now. I could simply extend this script, that would be an option, of course.

So which is the right tool for the job?

Can you tell me? I don't know which tool is the right tool for the job. After all, I don't think I should write such an application from scratch. So, for me, there are two options left: Extending jrnl, which is an Python script, or extending diary (I do not even find a link for this anymore), which is a bash script. Extending the bash script would be an easy job, I guess. But it wouldn't be as flexible as the Python tool is already. tags: #bash #c #c++ #haskell #programming #racket #rust #shell #tools

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:

  • Haskell
  • Go
  • D
  • Crystal

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!

So,... Haskell?

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 take 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.

Conclusion

  • Racket is awesome.
  • Haskell is Awesome.
  • Functional programming is awesome.
  • Yeah!

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.

tags: #programming #haskell #racket