Currying vs Partial Function Application

While having a read in to the art of function programming, I stumbled upon a curious technicality. Those that know me know (perhaps wearily) I love talking about technical stuff.

Currying (wikipedia) builds a single function that, in effect, takes multiple arguments by composing a chain of functions that each take a single argument and eventually yield the final result:

f: (x, y, z) -> result
curry(f): x -> (y -> (z -> result))

So if you wanted to call a curried function, it would look something like:


Functional languages often compose multiple-argument functions using what appears to be currying.

But wait, that’s not what I just said! I must be an awful writer, spreading misinformation like that. After all, I’ve read plenty of blogs and articles that tell me that currying is where you “fix” some arguments in place ahead of final invocation. The result is creating a function with fewer arguments, like so:

f(x, y, z) -> result
g(z) -> f(1, 2, z)

It turns out that this is known as partial function application. How it came to be known as currying I am not sure, but it seems to be a very common misconception. I believed it too until recently! Yet another thing to remember.

Wikipedia contrasts currying and partial function application in detail if you want to compare them further.

Cancel All Queued Jenkins Jobs

I do not believe cancelling all queued Jenkins jobs is possible via the UI. Fortunately, it is possible if you have access to the Script Console.

Run this in Manage Jenkins > Script Console:


While this script is innocuous, always be careful when using the Script Console. Any script run inside it effectively has administrative permissions over Jenkins!

Backup and restore a stock Android device


Taking regular backups of important devices is sensible advice. And backups themselves are no good unless you can restore them. This guide gives a brief overview on how to backup and restore a stock Android device – that is, a device that runs an uncustomised version of Android, that is unrooted. It may also work for non-stock Android devices.

One big caveat: While this is the best method I have found without root, I have not had consistent results across devices when restoring backups, even among Nexus devices. So I recommend that this method is not relied upon exclusively for backup.

Usage information

We will be using adb backup and adb restore to backup and restore device state.

To find out usage information for your device, connect it and run:

adb shell bu help

This info was found by simply running adb.

This guide assumes the backup and restore commands work like stock Android devices.


  1. Set up your computer and device so that your computer can access the device via USB. There are plenty of good guides out there, but in summary this’ll involve enabling USB debugging on the device and installing the Android SDK Platform Tools.

  2. Run the following command, authorising your computer to access the device if you have not already:

    adb backup -apk -obb -shared -all -system
  3. Follow the instructions. In my case, I needed to unlock the device and confirm the backup operation (optionally entering a password to encrypt the backup).

This will store a file in the current working directory.


  1. Ensure the device to restore to is connected.

  2. Run:

    adb restore <path_to_backup>

Using .netrc with curl for Automatic Authorisation

The ~/.netrc file can store credentials. This can include things like OAuth tokens and plain text passwords.

Warning: Be very careful if you decide to store passwords in this file. The file is not encrypted, so you’ll be storing your password in plain text on the disk. This is generally a bad idea!

First, create the file and make it readable by only yourself:

touch ~/.netrc
chmod go= ~/.netrc

Then edit the file to contain lines that look like the following (one line per machine):

machine the.address.tld login the-username password the-password

curl can then read this file by providing the --netrc option:

curl --netrc http://the.address.tld/classified

Ignore a Package Update When Using Fedora and KDE

Recently I wrote about Escaping a login loop when using Fedora. Well, once I had downgraded the package, I wanted to ensure that it would not get automatically updated again!

To ignore the package when performing updated via dnf, add an exclude=<package> line to /etc/dnf/dnf.conf. For example:


dnf no longer requests me to update SDDM.

Unfortunately, the built-in updater for KDE (which I blieve is PackageKit) does not honour the settings in dnf.conf. It will, however, honour exclude= lines in the repo files in /etc/yum.repos.d.

Since I wanted to block an update to SDDM, I edited /etc/yum.repos.d/fedora-updates.repo and added an exclude=sddm directive to the [updates] block:

name=Fedora $releasever - $basearch - Updates

After a while, KDE stopped pestering me to install the SDDM update.

I technically probably only have to add the exclude to the repo files, but this is the process that I went through. If you’re feeling adventurous, you may try only updating the repo files.

Escape Login Loop in Fedora

The problem seems to be caused by an update to SDDM (Simple Desktop Display Manager).

On Fedora it can be downgraded, but first you need an internet connection. I enabled my wireless internet connection by running:

nmcli connection up <wireless-network>

Where <wireless-network> is the SSID of my wireless network.

I then downgraded SDDM:

sudo dnf downgrade sddm

Logins should then work after a reboot.

Make kdesu use sudo (a.k.a. stop asking for root's password)

When I tried to start partitionmanager (KDE Partition Manager) on Fedora 26, it would always ask for the root user’s password, despite the fact that the root user was disabled in my setup.

The dialog box that popped up looked like it might be kdesu. kdesu,. a.k.a. KDE su, is a KDE version of su that allows a process to be run as another user, like root. When I tried running kdesu separately it asked for root’s password again. So I knew the problem lay within kdesu, not partitionmanager.

The ever-helpful Arch wiki contained just the golden nugget I was after: a command that would configure kdesu to use sudo:

kwriteconfig5 --file kdesurc --group super-user-command --key super-user-command sudo

This fixed the problem for me, as sudo requests your password, not root’s. Whether you’re allowed to run the command depends on the contents of the system’s sudoers file. Look that file up if you continue to have difficulty.

Re-use Commit Message in Git

To re-use a commit’s message verbatim, including authorship and timestamp information, use -C <commit>:

git commit --amend -C @

Pro Tip: @ is a synonym for HEAD, the currently checked-out commit.

To reset the date as well, use --date now; to reset the author too, use --reset-author:

git commit --amend -C @ --date now
git commit --amend -C @ --reset-author
git commit --amend -C @ --date now --reset-author

If you want to use an existing commit’s message and also want a chance to edit it, use -c <commit>:

git commit --amend -c @

-c is compatible with --date and --reset-author too:

git commit --amend -c @ --date now
git commit --amend -c @ --reset-author
git commit --amend -c @ --date now --reset-author

Uploading to Google Play Music without matching

I’ve had some trouble with Google Play Music’s scan and match service. It sometimes matches tracks to the wrong versions of them. Sometimes the volume of a track is wildly different from what I have locally (with or without ReplayGain). Unfortunately, there is no way to disable matching in Google’s official Music Manager application.

gmusicapi supports uploading to Google Play Music without their “scan and match” service. gmusicapi-scripts utilises gmusicapi. Let’s use them!

  1. Install gmusicapi-scripts:

    # Windows
    py -3 -m pip install gmusicapi-scripts
    # Others
    pip install gmusicapi-scripts
  2. Convert tracks (if needed) to 320kbps MP3 and place them in <directory>.

    • If you place non-MP3 files in this directory, gmsync will try to convrt them with FFMPEG or AVConv if they are on the PATH. Look at the docs to see what formats it supports.
  3. Run gmsync. Follow any instructions it provides:

    gmsync up <directory>

gmsync uploads without matching by default. Perfect.