musicmatzes blog

shell

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

Some of you might know my little project rate. It is a bash script to collect a database of things you want to rate.

What this means and why I started to reimplement in C++ – read it here!

So I started to write this application because I wanted to keep track of animes I already watched, Bands I like but do not listen to that often and so on and so forth. What the application does is really simple: You can enter notes about a certain thing (in your favourite text editor, which is vim for me) and attach tags to it and put it into a category. Then you can give it a rating. The rating can be everything, from simply numbers to text to whatever you like. But it is supposed to be a number between 1 and 10, of course. That's also the way I use it.

So how does it work? Well, that's really simple: The “rate” script creates a directory structure in ~/.rate/collections/, whereas a folder is a “collection” of things and a file is a rating. So, I have something like “movies/animes/” as collections (they are nested, of course) and then a file for each anime I watched. The filename is generated from the title I passed “rate” when creating the entry. The file also contains a “header”, which includes a unique ID (which you really should not change), a list of tags, the title (the filename is the title, too, but as on linux you shouldn't include whitespace in file names, it is not the title as you typed it) and a rating of course. Custom fields could be added to the header, but this feature is not implemented yet. After the header, you can put your description.

That's basically it. “rate” provides some features to search this database, for example you can grep for text in your entries, you can view your entries, you can list your entries and you can attach more text to your entries or edit them. As everything is git controlled in the ~/.rate directory, you can reset if you (or the script,...) messed up somehow.

There's no release by now, as it lacks of some features by now. For example I want to be able to search for entries with a certain rating or within a certain range of ratings. I also want to be able to search for entries with aspecial set of tags or within a certain collection (I can do this, though) special set of tags or within a certain collection (I can do this, already)! After these things are implemented, I will release my first version, which would be 1.0 then. And, of course, I will package it for NixOS!

So why C++

Well, I have to learn C++ for my praxis semester. That's basically it. I wanted to learn a new programming language for a relatively long time, and that's my approach on learning C++. I was able to implement some things, but not yet to run an application. My first step would be to parse my already existing entries. Hope that works. As I stated in the github repos README.md file, I do not want to use any frameworks for this. No Boost, no Qt, no other libraries. I just want to use plain C++11 (or maybe 14 in future, not sure about this, though).

Also, C++ gives me way more posibilities when it comes to features. I can refactor things really easy and maybe the C++ implementation will continue to live whereas the bash implementation will die at some point. Who knows? The point is, the bash implementation implements a file format which is

  1. really simple
  2. forward compatible

The file actually looks like this:

key = value
other = value
another = another
---

<text>

and that's basically it. The three dashes mark the end of the header and everything before the header is a <key> = <value> list, whereas each line is only allowed to contain one key-value-pair. The value can be a list of values, for example a list of Tags whereas tags are seperated by a whitespace character (space) or a string, such as the title is. The bash implementation “knows” which key has to be which value and the C++ implementation has to know this, too, of course. But that's it.

The commandline interface of the application needs some work, though. Maybe it will get some REPL-like interface later on, or maybe something more interactive. By now, it is simply an interface where you can do one thing per call. I have no problem with that and I'm planning to keep backward compatibility with the bash implementation even if this one is not even released! It is fun to write such a tool and I really like doing it.


Also, it is not a that complex thing to implement and that's a huge point to me. I don't want to spend months and months in implementing a thing which only one or two people on this planet actually use. For bigger projects, I contribute to open source projects. That's a better way to produce large-scale software, IMHO.

tags: #bash #programming #c++ #linux #shell #vim

I started a fork of a diary application which is written in bash, because I thought there are some things missing and some features could be added – and the repository of the original author was really old.

I started to pretty it up and implement some 21st-century things so it becomes a really nice note-taking application.

So, initially the application was called “diary” and developed on sourceforge, by Jamie Briggs. Someone created a fork, named “diary-f”, which added some features.

The lastest change in the original repository is from February 2013, which is almost two years ago by now. The last change in the repository of the fork is from three years ago – even longer, yes!

So, the application per se is really good one. It is just a small shell script, but it works really good for me. Anyways, I missed some features, namingly:

  • Multiple separate entries per day
  • Everything should be kept in git, so I know when I edited the articles
  • GPG encryption everywhere

I started implementing multi-file support directly in the “diary-f” repository, but then decided to create a fork, as it won't be compatible with the original software anymore. By now, three things are done in the repository: I refactored the codebase to fit my coding style (well, it is still bash, isn't it?), mutli-file support as said and git support. I want to implement gpg support next and maybe the ability to add attachements to entries. And after these things are implemented, I want to be able to search the entry repository for certain entries in a simple way, which could be difficult, given the fact that everything is encrypted in there.


If you're interested in the application, I'd welcome pull requests for almost everything. Contributing guidelines are:

  • Document your work, how do things work?
  • KISS
  • DRY

That's basically it. I'm looking forward to your patches! tags: #bash #git #open source #programming #shell #tools

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

I really like to dump my brain into irc channels. You do, too? So, meet ircdump.

irc_dump.sh (the repo) / ircdump (the script-call) is a short shell script which dumps your text in all joined irc channels you previously joined. It uses ii as irc tool.

If you want to paste something, you just invoke it:

ircdump I like trains

and it dumps the text directly into all available IRC channels. Of course, you must do some setup right before!

You have to use ii to create/join the appropriate channels. You should create them at /tmp/ircdump or set the appropriate path right in the script. Once you connected to a server and joined the appropriate channels, the script does everything else for you. Note that it doesn't paste to the server channel, just to the channels you joined.

Use it with care! You will paste to _all IRC channels you joined with ii.

People gonna hate you!

Update: There is now a repo at my github account which contains utils when dealing with ii: irctools.sh.

tags: #programming #chat #irc #shell