Newcircuit 1c8db4401779333389b774086d6390f160bbb49078a0eda577b43dcf5018a77f

Ashley Whetter's Blog

[programming, linux] ++ [stuff]

Social inside twitter icon ee809e0d7c5b2294b7d548e7223909c678d76c5484045ae68ecb7c559cd7fade Social inside google icon dbbc88b746b52525f1e1bd5e2bf44152b2713fb976f7e68b903c2d13e9fbd160 Octocat 1fcbe3003defcb5ee415b3a7aa989bbc724ccf3c446436e848c27437901c6ca2 Social inside rss icon ff8ccbbb13f265afbe3cadba03c838cdbcad75b6f223a7937eab3ee35afc933d Social inside linkedin icon 5f3acefcb096b75afe32a0e0b3d90d1f2c1b374049eb8c1996203225e1ae34ba

Fixing URxvt Being Slow to Render Fonts

Recently I changed my URxvt font, and it required me to use both antialiasing and hinting. Subsequently URxvt was taking a good second to render everything on a 1080p screen. I fixed this by adding the following line to ~/.Xresources:

URxvt.buffered: false

Categories: Linux

Creating a config repo

When backing up a system it's not just your personal files that are important. If you're anything like me then you'll have put hours into crafting the perfect system configuration, and losing your configuration files would mean a huge headache if anything happened to your system. By creating a config repo, backing up your config files is easy so you can backup changes as you make them. It'll also make it easier to revert back to older config files and easier to share them with people if you use a public repository.

To start you'll need to make a bare git repository somewhere. Either use a hosting site or run the following commands on your personal remote git machine:

mkdir configs.git
cd configs.git
git init --bare

Next create a permanent directory somewhere on your local machine to store all of your configs. Copy the following script into the directory:

#!/bin/bash

scriptDir="$(dirname ${BASH_SOURCE[0]})"
cd $scriptDir

#Collect the listed local configs
for i in "/etc/rc.conf" "/etc/network.d/"; do
   cp --parents -r $i $scriptDir
done

#Collect the listed remote configs
rsync -varblpEAxogt <username>@<hostname.domain>:'.irssi .gitconfig' $scriptDir

The script will copy the specified config files into the directory of the script using their full paths. To add files just add their location to the list. Local files go into the 'local' folder and the remote files go into the 'remote' folder. Using their full paths will make the script compatible with multi-user systems, plus restoring the files will be easier. If you have multiple remote locations then you could add extra rsync commands and use a different folder names to back them up to.

Now that you've downloaded the script, make it executable with 'chmod +x <script name>', and run it.

Next you can backup your configs for the first time. In the directory that contains the 'local' and 'remote' folders; setup git with:

git init
git add <script name> local remote
git commit -m 'Initial commit'
git remote add origin <username>@<hostname.domain>:configs.git
git push -u origin master

To do any backups in the future just run the script and run 'git push origin' in the directory that contains the 'local' and 'remote' folders. If you want to run the script with a cron job then remember that you'll need to use an ssh key that has no password protection so that the rsync command requires no user input.

Categories: Linux

Summarising Haskell in 10 minutes

A few months ago I started learning haskell and it's definitely "something different". It's not like any programming language I had seen before and it carries a steep learning curve, but if you stick with it then you'll learn to love it.

I'll be using this example code to give you a quick overview of how haskell works. It takes any list (there are no arrays in haskell, only linked lists) and returns the sum of every element in the list.

sumList :: (Num a) => [a] -> a
sumList [] = 0
sumList (x:rest) = x + (sumList rest)

The first thing you'll notice about haskell is that there are no loops; only recursion. Line 2 acts as the base case and line 3 is the recursive call. We can do this without any if statements by implying the condition with haskell's pattern matching.

We see an example of this on line 2. [] says "if an empty list is passed to the function then return what is to the right of the equals sign". Line 3 has something similar but instead of an empty list we pattern match against a list with items, while also getting haskell to split the list for us. (x:rest) says "take the first element of the list and put it in x. The rest of the list goes into rest". Note that if we only have 1 element in the list then rest is an empty list ([]), so our base case is called on the next call.

Becuase haskell is a pure language we have access to infinite lists. This is allowed in part because of haskell's laziness. Laziness means that nothing is evaluated unless we need it. For example consider a function that prints every element in a list. A language such as Java requires us to pass the entire list so that it can use the list as a single entity, which is impossible because the list is infinite. Haskell instead takes the definition of our infinite list and will calculate the next element in the list only when the function is about to use that element, and then print it. One example of an infinite list is [1..] which is a list of all the positive integers, or [2,4..] which is a list of all the positive even numbers. We can't pass an infinite list to any function though. If we were to pass an infinite list to our example function then we would recurse forever because we never end up passing an empty list, therefore the base case never terminates the recursion.

Another interesting thing to notice is the function declaration on line 1. Firstly we don't assign any variable names here, only types. All elements except for the last after a :: (or => if we define generic types) are the types of each variable that is passed to the function. The last element is the data type that the function returns. Secondly, in this example we've used the generic type Num and bound a to the rules of that type. A generic type is like a set of data types that are grouped depending on what operations can use them. So in this example we used the Num to only allow numeric types (eg. Int Double Rational etc) because the + operator can only deal with numbers, it can't deal with String, Char, etc.

I hope this has given you a quick overview of what to expect when starting off with haskell. There are many resources online to help you learn haskell, but I reccommend always having the language documentation to hand for reference. You can view that here. The Prelude module is what provides all of the basic language functionality (it's the equivalent of java.lang in Java).

Categories: Programming Haskell