My journey of installing the NixOS Linux distro on my primary laptop, which all started from my hatred for the Haskell IDE Engine.
This week, I completed some coursework for one of the modules that I am taking for computer science: Functional Programming. Functional programming is basically a programming paradigm where every bit of code you write is a function. If you want to write anything, you create a function to do that. How do you write such a function? You make it call other functions. This was by far the most annoying concept which I have been exposted to, and found it extremely difficult to grasp, considering that I have been using the Object Oriented Programming (OOP) paradigm for the past 6 years.
For the functional programming coursework, we had to write some code in Haskell that would solve the game “mastermind”. Mastermind is basically a two player game, where one player thinks of a code of 4 colours, for example “blue blue green red”. The other player then has to guess the code. If the code is not right, the player that thought up the code must inform the guesser how many of the colours were in the correct location and correct colour and how many were in the wrong location, but still an existing colour from the code. For example:
1 2 3 4 5 Codemaker: blue blue green red Guesser: red green blue yellow Codemaker: Wrong. You have 3 correct colours in the wrong place Guesser: blue red green blue Codemaker: Wrong. You have 2 correct colours in the right place, and one correct colour in the wrong place
In order to complete this coursework, the module organiser provided us with the Atom text editor, as well as some plugins that makes the text editor act like an Integrated Development Environment (IDE), which is designed to help programmers write programs. However, this text editor and plugins are only installed on the machines inside the Department of Computer Science (DCS). Obviously, the best thing to do would be to install Atom on my Windows laptop and the plugins which are on the DCS machines. Luckily for me, the module organiser included a list of instructions on how to install the setup on Windows machines!
Off I go, reading the guide on how to install what I needed on my machine. I install
Haskell Stack, a compiler and package manager for Haskell. I install Atom, along with the following three plugins:
language-haskell for syntax highlighting;
atom-ide-ui for providing an IDE interface and
ide-haskell-hie which basically applies the IDE functionality to the Haskell language. I restart Atom and receive an error notification:
HIE is not installed! I click the button to install HIE - the Haskell IDE Engine and begin reading through the documentation that outlines how to install it.
It looks pretty simple. Clone the HIE repository from GitHub, then run the
make command for the version of the Haskell compiler of your choosing. However, the documentation also states that you could just install every version of the Haskell compiler, which is the simplest and easiest approach. Upon reading this, I notice a little warning box:
Warning: Requires 20+ GB of space and potentially more than 2 hours to install, so please be patient!
I’m not interested in waiting 2 hours to install HIE! You’ve got to be joking! I decide to run the
make command just for version 8.4.3, which is the version our coursework is written for. While this builds, I decide to talk to the module organiser about how complicated it is to install HIE on Windows, whereas on Linux machines, it’s as simple as running a single command. He informs me that he tried to install HIE on a Windows device for another student, but had no success in doing so. At this point, I decide to challenge the module organiser. If I can install the HIE, I’ll claim all of the glory of being able to do something Haskell-related that even he, a Haskell genius, could not do.
Three days later, I arrive at the conclusion that it is indeed impossible to get the HIE to work with Atom. Despite installing the HIE for all sorts of Haskell versions, Atom’s
ide-haskell-hie plugin refused to cooperate with the HIE. I end up claiming defeat and decide to just complete the coursework with a half-baked IDE.
After completing said coursework, I have a massive mental phase. Perhaps it’s because the coursework took such a toll on me. Perhaps it’s because of a lingering thought in the back of my mind. Who knows, but primarily, two thoughts come into my mind:
- Java is a terrible language - I should switch to something else
- Windows is a terrible operating system - I should switch to something else
Now, I have been a super keen Java developer as of 2012. It is by far my most favourite programming language, despite the fact it’s very bloated and has a lot of boilerplate code in order to do anything. However, I feel it was time to change. Java is old. Java is useless. Haskell is clearly the superior programming language. So, as a result of those thoughts, I decide to learn Groovy. Yes, you read that correctly - Groovy. Why on Earth of all programming languages would I want to learn Groovy? Well, it’s clearly got the best of both worlds:
- Uses basically the same syntax as Java. Almost all Java programs are Groovy programs.
- It runs on the JVM and it’s easy to use reflection (I have some obsession with metaprogramming in various programming languages).
- It’s got lots of those funky functional programming features that Haskell has.
At the time of installing Groovy, I decide to install Linux on my laptop. In a previous lecture, I discussed with a fellow computer science student about various Linux distros and one seemed to have caught my eye at the time - NixOS. I begin creating the live USB disk while I wait for Groovy to install on my laptop.
After creating the live USB disk, I have reason to believe that I damaged the USB because for some reason, my laptop refuses to boot from it! (It so happens that my laptop has some security setting in the BIOS that can be disabled). In despair, I switch back to my first plan of playing with Groovy and I have the time of my life learning the basic syntax of closures and dynamically inferred types. Of course, all good things come to an end and I realise how bloated Groovy really is: Since it’s possible to compile Groovy code into a standalone
.jar file, it has to include the Groovy library with it. This, in addition to converting the Groovy file into bytecode, has so much more overhead compared to simply writing the code in Java. Oh no, no no. This will not do. Groovy is not the way to go. It’s time to go back to Java once and for all.
The following day, I contact my good computer science buddy and they point out the security setting in my BIOS. It’s finally time to install Linux.
Now, NixOS is not like any other Linux distro that I’ve ever seen before. Basically, the entire system revolves around a configuration file called
configuration.nix, which is a Nix expression - Nix’s functional programming language that describes how to build packages and configurations. If you want to change anything related to the system, you dump it in
configuration.nix and rebuild the configuration file for the system. You want to install an application? Dump it in the config file. Want to add new users? Config file. Remove programs? Remove it from the config file - the system just doesn’t include them when the configuration is rebuilt, thus they are effectively “uninstalled”.
Unfortunately, I am not aware of anything that is mentioned in the above paragraph. I am sitting at my friend’s house, staring at the installation manual and trying to make heads or tails of how this bizarre operating system works. I’m following the commands, adding lines to the
configuration.nix file with the help of my friend. Not only have they never used this operating system before, they have absolutely no idea why on Earth I’d choose such a strange operating system.
Not only do I fail to set a root password, which causes the issue of “I cannot even log into the system”, I also fail to create a user account! After a good 10 minutes of panicking, we managed to collaboratively resolve the issue. I manage to get into the system successfully, before realising that I cannot connect to the internet, which is a requirement to install other programs. No problem! I click the manual which came pre-installed on the operating system and wait for it to load. Nothing. The manual was a HTML file. It so happens that I have no program that can actually read HTML files, other than
vim - a terminal text editor.
Another half an hour or so goes by and we end up resolving the issue of internet connectivity. I decide to head home and ensure that I add the credentials of my house network to the
configuration.nix file before departing. Everything from here onwards is going to be all on my own.
I’ve been using NixOS for just over 2 days now, and I must say that it is easily my favourite operating system. The fun of modifying the nix configuration file whenever you want to change anything and seeing the changes take effect almost immediately is truly something to experience. I’ve learnt how to use the
configuration.nix file effectively to install whatever I want and tweak the settings to do everything I could imagine.
I’ve recently discovered that many people post their
configuration.nix files online, and I used many to influence my own, which I also decided to post online for the world to see. My end goals for this operating system are as follows:
- Vastly improve my knowledge of
- Learn a bit about
Nix expressionsand hopefully write my own in the future
- Make NixOS my main operating system on my main computer
My friend asked me why I chose NixOS over other Linxus distros. Simply because NixOS is unique. I’ve seen all of the other computer scientists at my university use their own array of fancy Linux distros (One of which I discovered was just a heavily modified Ubuntu). I’ve used Ubuntu before and honestly, I never really liked it. It seemed slow, but that may come down to the poor specifications of the device I ran it on.
As I’m not very good at functional programming, and NixOS is a purely functional operating system, I also thought it would be a good way to have the opportunity to learn more about the functional programming paradigm.