Deprecation in the type signature

The fact that a function is deprecated should not just show up in the function name (_DEPRECATED suffix), or in the compilation logs as a warning. If that is all we add to discourage the use of deprecated functions, the barrier to using them may still be too low. We should actively make it un-fun to use deprecated functions.

The trick will be to have deprecation show up in type signatures. Let’s get started with this annoying newtype wrapper around a function:

newtypeDeprecated a b =Deprecate { useDeprecated :: a -> b }

Now, to deprecate a function, we just change a function myFunction into myFunction_DEPRECATED by putting it in a where clause and adding the _DEPRECATED suffix. (Don’t forget to add a deprecation plan in the comments!)

The smiling poop operators

Before we delve into how to fix up the rest of the code so that it compiles again, let us make using deprecated code even nastier. We can make a new operator to un-deprecate a Deprecated function:

(💩) ::Deprecated a b -> (a -> b)
(💩) = useDeprecated

Now we can hide the useDeprecated function and the Deprecate constructor so that this operator has to be used. We can then still use myFunction_DEPRECATED if it is absolutely necessary, but it is already not very fun anymore:

λ> myFunction_DEPRECATED 💩 AB

Sadly, deprecating functions with multiple parameters will now require a lot more parentheses. That could be smellier! Here is the double poop operator:

Last week I published a paths library. I showed it to the Haskell subreddit and learned from their reaction.

With good intentions I set out to create a safer way to handle paths in Haskell. After a few days of coding and lots of testing, I had a first draft of a solution. Some polishing later, I put it up on Hackage, wrote a blog post about it and put the blogpost up on reddit.

Stop

I got very reasonable not-so-positive reactions. The main reaction pointed me to the path library. This library solves the same problem (and does it better) and is much more widely used. Subsequent reactions made me reconsider what made safepath different in the first place. I decided to stop work on safepath for now.

Reconsider

There are aspects in which path is superior to safepath. Most notably: it performs better, is already widely used and has some more advanced safety features. The biggest (and arguably only) advantage of safepath was that safepath is tested much more thoroughly.

If I was going to make safepath better than path, I was going to have to copy a lot of features and then convince people to start using safepath instead of path in the future. It would have been a lot of extra work, just for a more thoroughly tested safe paths library.

That is why this post’s title is not “Safer paths, part 2 - safepath IO operations” as I had planned last week.

Contribute

Instead of stubbornly continuing work on safepath, I am currently trying to contribute tests to the paths library. You can follow the progress here. When this is done, I will deprecate safepath and point any users towards path instead.

Filepaths have been a pain in my neck for years. Paths are hard, overused, misused and mostly unsafe. In this post I present a newly released library that serves to make working with paths safer in the common use-case.

Misuse and scope

Have you every thought about why we use paths in the first place? and why we use strings to denote them? Is it not weird that . means the ‘current’ directory (whatever that even means) and is also the separator for extensions? Is it not absurd that / is both the root of the path system and the separator? Path are hard, but in any case, we are stuck with them now.

Paths are often overused or misused. By this I mean that they are used to denote more than just the location of a file(/…). Sometimes a path is a vital part of the meaning of the contents of the file. Sometimes the mere existence of a file at a certain path even has a meaning.

The safepath library is only to be used for real paths. Paths that can point to a directory, a file, a device, a socket, etc. It is not meant to be used for glob patterns, for $PATH’s, etc. It also encourages safer use of paths: only absolute paths, no Strings and valid-by-construction Path’s.

Data.FilePath versus System.FilePath

Data.FilePath uses an opaque datatype to represent a path instead of a plain String. This is the exact opposite of what System.FilePath does.

safepath encourages safe usage of paths: preferably no semantics in paths and no String juggling.

Data.FilePath versus System.Path

Data.FilePath’s opaque data type with one type parameter: Path. There are two possible occurrences of this path:

typeAbsPath=PathAbsolutetypeRelPath=PathRelative

This means that there is a type-level distinction between absolute and relative paths now. It ensures that always the right type of path is passed to a function. It should also encourage programmers to only ever use Absolute paths in the heart of their application.

This approach may looks familiar. There are the path and pathtype libraries that do something similar, only with more type parameters.

These different parameters serve to also support:

Whether a path points to a file or a directory

What platform the path originates from

The Path in Data.FilePath does not make these distinctions for two reasons:

Whether a path points to a file or a directory can not be determined from the path itself. Whether it points to a file or a directory on disk is not even an immutable fact. It is dangerous to pretend that Path Dir is any safer than ∃ t -> Path t. As such, Data.FilePath does not make this distinction.

Supporting different platforms’ paths in the same system is not a common enough use-case. The common use-case is to use the hosts platform’s paths.

Implementation

A path is data with invariants

A path has invariants. Some can be encoded in the type, others have to be contained and heavily tested. Of course these should be hidden from the user, but they should be thoroughly tested. Looking at the other ‘safe’ path libraries, I see only a handful of tests and no property tests to check invariants.

Extreme testing

In terms of lines, there are many more for testing as there are for code. In absolute numbers, there are:

over 150 doctests

over 100 property tests

over 10000 unit tests for parsing and rendering

Doctests ensure that the semantics of functions are at least intuitively clear. Property tests look for edge cases that need to be handled and ensure that the invariants of the Data.FilePath types are maintained under all circumstances. Lastly, the unit tests serve to ensure that when the handling of the paths changes behind the scenes, the API retains its semantics.

I once asked my friend whether he understood Monads and could explain them to others. He sarcastically responded “No, I have not reached the burrito point yet.”, supposedly in reference to a paper that explains burritos as strong monads.

He defined ‘the burrito point’ as the level of understanding at which you can understand why a seemingly simple analogy is relevant with respect to a concept that is perceived to be hard to understand. More generally it can be taken to mean “an adequate level of understanding”.

Down the rabbit hole

There isn’t much for documentation on that page already, but an educated guess brought us to the GHC module. We searched for ‘parse’ and found parseModule. So far so good, combining the information from a tutorial from version 7.6 and what we saw in the type signatures, we managed to call this function and get a ParsedModule.

Now we could start writing our static analysis piece, right? How complicated can the ParsedModule be? More complicated than we thought, as it turned out. From a ParsedModule, we got a ParsedSource, which is just a type synonym for a Located (HsModule RdrName). Hmm, let’s see: Located is a type synonym for GenLocated SrcSpan and GenLocated has the first piece of documentation: “We attach SrcSpans to lots of things, so let’s have a datatype for it.” SrcSpan also had some documentation, so we were able to figure out that it means “Rectangular portion of a source file”.

Great, we know what Located and SrcSpan are, let’s go down the other half of the rabbit hole. What is HsModule? The documentation says “All we actually declare here is the top-level structure for a module.”, but it does not explain why name is a parameter. Never mind, we were looking for the declarations in a module and specifically the left-hand side of functions. The [LHsDecl name] part of the HsModule name seemed promising, but what is a LHsDecl? “Left-Hand side Declaration”? That’s exactly what we need! Oh it’s just an alias for Located HsDecl and has nothing to do with the left-hand side of anything. That’s anticlimactic.

This story goes on for quite a bit longer. We spend a few hours trying to figure out how we could use the GHC API but we felt no more confident after that than when we started, so we decided to use haskell-src-exts instead.

Improvements

The reason why the GHC API was to confusing was twofold:

Most of the GHC API is undocumented.

Most of the names in the GHC API are abbreviations.

I had been trying to find something to do for my first GHC contribution, so I decided to contribute documentation. In particular, I was going to add the expansion of every abbreviation I could find in the names to their documentation, so that the next time someone wants to write some static analysis tool, they will not be discouraged by the API documentation.

Boolean blindness has been discussed over and over and over and over again. The conclusion seems to be that always using Boolean values for decisions is a generally bad idea and that using church encoded lambda calculus instead is not much better (and impractical). Here are my two cents on the matter: Use evidence instead of Boolean values.

For the purpose of this post I will use a contrived example. It is important to focus on the problem of boolean blindness here, and not the efficiency of the solution to the given problem.

Boolean blindness for primes

Say you want to implement a primality test. You might write a function with the following signature:

isPrime ::Int->Bool

The first problem with this function is the way it will be used. The call site of this function needs to know that the Boolean value it obtains reflects on the primality of the integer. This phenomenon is called Boolean blindness.

The second problem is that we have to trust that isPrime works and the only way to check that the resulting Boolean corresponds to a given integer is by evaluating isPrime again. In other words: There is no way to link the resulting Boolean value back to the integer under test other than to ‘remember’ where it came from.

Another name for the Boolean value

The first proposed solution consists of introducing a type isomorphic to Bool with a more meaningful name and more meaningful constructors:

dataPrimality=IsPrime|NotPrimeisPrime ::Int->Primality

This solves the Boolean blindness problem, but we still have to evaluate isPrime again to check that a given Primality value corresponds to a given integer.

Evidence

A solution to the second problem is to introduce a newtypePrime and write a smart constructor for it:

newtypePrime=PrimeInt-- INVARIANT: must be primeprime ::Int->MaybePrime

Now you can rigorously test that any value produced by this prime function does in fact contain a prime. Then a Prime value can serve as evidence that the value within is prime. In this way we can relate a Prime value back to the integer it concerns and we have solved the Boolean blindness problem.

Testing

I use the word ‘evidence’ because I really mean ‘evidence’. In a perfect world we would use a proof, but unfortunately here we have to resort to evidence.

The power of the evidence comes from the testing we use to ensure that the invariants hold at all times.

Values of custom types usually have invariants imposed upon them. In this post I motivate and announce the validity, genvalidity and genvalidity-hspec libraries that have just come out.

Contrary to what we might like to think, an absence of compilation errors does not imply correctly functioning code. In some cases we expect some invariants to hold about our data, but we don’t necessarily check them rigorously.

This is a situation in which the typesystem may be expensive to use to guarantee correctness. That’s why we will use testing instead.

A running example

I will take a contrived example to keep the blogpost short. Assume we have the following context:

Genvalidity

Now that we have this concept of Validity, we can start writing tests using it. We will ignore the tests which assert that the output is a valid prime factorisation for now. We can then write the following tests with respect to validity:

This is quite a mouthful, isn’t it? There are also some non-stylistic problems:

someGenerator `suchThat` (not . isValid) runs someGenerator and retries as long as isValid is satisfied. For types that are mostly valid, this can take a long time and will slow down testing significantly.

Generators like GreaterThanOne <$> arbitrary become quite large (in code) for larger structures. Ideally we would only write them once.

genInvalid Has a default implementation, but when generating GreaterThanOnes, on average 50% of all generations have to be retried at least once. We can specialize this implementation to run faster by using an absolute value function:

Standard tests

We can use these new toys to write tests as described above, but we can also use some of the standard tests that are available via genvalidity-hspec. For example, the above tests can be rewritten as follows:

Because we have now written a custom implementation of genValid for GreaterThanOne, we should also add the validitySpec:

validitySpec (Proxy ::ProxyGreaterThanOne)

This will ensure that genValid and genInvalid keep working as intended. However, it cannot check that all possible valid(/invalid) values can still be generated by genValid(/genInvalid), so be careful and check that yourself.

It may come natural to try and save money wherever we can, but I argue this may be a bad idea.

Your time is finite and you cannot make more of it, so it makes sense to put a steep price on it. This also means that, as long as you have the money, it is a good idea to spend money instead of time whenever the time you save is worth more than the money you spend to save it.

Spending money to save time (and effort) is not a new idea. You are doing it already.

You could make your own clothes, but is easier and much less time consuming to buy the clothes instead. You could build your house yourself, but it is easier and cheaper (in time) to buy/rent a house than to build it yourself.

In which situations you spend money instead of time is probably largely determined by how you brought up. Chances are that you’ve never reconsidered in which situations it makes sense to spend time and save money or vice versa.

This reasoning is different for different people, so I will not use concrete numbers, but here are some obvious areas in which you should (re)consider your strategy. Obviously you need to have the money before you can consider spending it instead of time, but that is also something you should decide for yourself. These are roughly sorted by decreasing importance and increasing price.

Food:

Growing food and cooking for yourself can save you a lot of money, but it one of the most time consuming activities on this list. You have to eat very frequently and cooking takes a relatively large amount of time. How much does it really cost to have money taken care of?

Transport:

Walking everywhere is really cheap, but takes a long time. Commuting by bicycle is marginally more expensive, depending on the bicycle, and takes at least three times less time. Public transport is slightly more expensive and goes even faster, etc. Figure out which trade-off works best for you.

Cleaning:

Cleaning your accommodation is another time consuming activity. Chances are you have never even considered using a cleaning service. Have a look at cleaning services near you and decide whether it is worth it to clean your home yourself.

Laundry:

If you’ve been brought up in a household that does its own laundry, you have probably never even considered using a laundry service. Doing laundry can take up a lot of time, especially if you do not have your own laundry machines. Have a look at laundry services near you before you decide whether using it is valuable to you.

Travel arrangements:

If you travel a lot, chances are that you spend a lot of time arranging your travels. Consider whether it is worth it to have someone else to figure out the cheapest way to travel and to arrange those travels instead of doing that yourself.

Personal management:

Figuring out who to meet and when is a time consuming practice in and of itself. Maybe it is worth getting a secretary?

The list of areas where you can save time by spending money can go on much longer. If you are really rich, it may be worth getting a chauffeur, a butler, a private helicopter with pilot? This may sound ridiculous, but make sure you know where you draw the line and why, because you only have a finite (and small!) amount of time.

Using arguments, configurations, settings, options or instructions in any language can be a struggle. There are quite a few libraries to solve just this problem and most of them involve either some global state or an object that is carried around through the program. Seeing as neither of these options are feasible and scalable in Haskell (when implemented naively), one has to think twice about how exactly to do it. In this blogpost I propose a general scheme to deal with all of these.

This is a very practical blogpost. The scheme is geared toward small command-line tools but can also be used more broadly. It is possible to apply the idea presented here directly, but the reader is encouraged to modify the proposed scheme to suit their needs.

Definitions and Types

Commands

There are different ways to specify modified behavior of a program. The first of these that the user comes in contact with are the command-line arguments.

Regular command-line arguments are never prefixed by -. They serve to specify commands and arguments to commands. Examples include the file.txt in cat file.txt and deploy config.sus in spark deploy config.sus

These commands are represented by a data type Command that is strictly a sum-type. The definition of this data type might look like this:

For the record; there are two exceptions to the “no---prefixes” rule: --help and --version.

Flags

Next up are the closely related command-line flags. They are always prefixed by - for short flags and -- for long flags. Examples include switches like --verbose. We use a data type Flags to represent the relevant values of the command-line flags and arguments. The definition of this data type might look like this:

dataFlags=Flags
{ flagVerbose ::Bool
}

Except for the flags --help and --version, flags should never specify commands. They should only modify the behavior already specified by commands.

Arguments

A Command value and a Flags value together make the Arguments.

typeArguments= (Command, Flags)

We will use this definition later.

Configurations

The last piece of configuration comes in the form of configuration files. Common examples of contents of these include the url’s of the servers to fetch data from. The contents of a configuration file are represented by a data type Configuration.

I leave the actual encoding of Configurations in bytes on disk up to the user.

Putting all of these together into instructions

You could drag around a triple of type (Command, Flags, Configuration) around in the entire program, but this approach has some disadvantages:

It is entirely possible that not all (Command, Flags, Configuration) triples represent valid settings for your program.

This is a triple and not a single value. You would have to take the value you need out of the right part of the triple every time you use it later and that is somewhat cumbersome.

The proposed solution to this problem uses a data type called Settings and a type synonym type Instructions = (Command, Settings). The idea is to combine the Command, Flags and Configuration values together into a Settings value. Exactly how this can be done is discussed in the next section.

Constructing settings

To construct the Settings value we need to keep the following in mind:

We can get the command-line arguments to the program with the System.Environment.getArgs :: IO [String] function

Where to find the configuration file may need to depend on the command-line arguments.

The goal is to build a function of type IO Settings or IO (Either Error Settings)

First we construct an Arguments value from the arguments with a function with the following signature:

getArguments :: [String] ->EitherErrorArguments

This function embodies the idea that not all combinations of command-line arguments are necessarily valid. As for implementing this function, which I leave to the reader, I recommend optparse-applicative.

Next is the configuration file. We use a function getConfiguration :: Arguments -> IO (Either Error Configuration) to read the configuration file, failing with a nice error message if anything goes wrong. The location of the configuration file can be a default value and/or specified by the Arguments.

To build the Instructions value, we write a function combineToInstructions :: Arguments -> Configuration -> Either Error Instructions. The goal is to write this function in such a way that it only produces a Right value if the resulting Instructions are valid (and to test that).

If not all of the above data types have a meaning in your specific use case, for example if you do not need any configuration files, you can always make the data type isomorphic to the unit type ().

dataConfiguration=Configuration

The last piece of the puzzle is then to write the getInstructions :: IO Instructions function.

You may want to use the type synonym type Configured = ReaderT Settings IO.

Using the settings

What exactly you do with the Settings of course depends entirely on what you would like your program to do. A Reader monad or ReaderT monad transformer are very easy ways to drag the configuration along throughout the program without having to explicitly make the Settings an argument to every function.

A note on the MonadReader type class

It may be tempting to define one giant monad transformer stack like this:

However, if you then write every function in this monad, every function gets stuck in IO. It becomes cumbersome to test these. Instead you would really like to only put functions in the parts of the monad stack they need. Pure functions don’t need to be put in an IO transformer, functions that don’t fail don’t need to be put in ExceptT, etc.

This problem can be solved with the mtl-style monad transformer type classes. A function that requires IO, we give a MonadIO m constraint and use liftIO. A function that requires Settings, we give a MonadReader Settings m constraint, etc.

We can then put the dispatched function in the MyStack monad and use all the functions that have constrains that are satisfied by this monad. Meanwhile we can still test the pure functions purely.

Conclusion

This concludes a schema for settings in Haskell, any feedback will be greatly appreciated.

I have written quite a bit of LaTeX in the past but most of it was in my native language. Since that language is not English I figured I would write my next bits in English so that it would be helpful for more people.

I intended to write a collection of notes on mathematical subjects, because that is how I study and math ages well anyway. However, LaTeX just was not going to be good enough. It allows for too many mistakes, does not impose discipline and has really ugly syntax.

Requirements

I had been thinking about writing a DSL that compiles to LaTeX because there were some features missing from LaTeX:

Infix macro’s.

Curried macro’s.

Local constants

Painless subpart compilation.

Generation of graphics.

Caching of dependencies.

Parallel resolution of those dependencies.

Nice Turing-complete programming for the generation of certain repetitive parts.

Compile-time safety with respect to references.

I would write my notes in this new language and the code would then be compiled down to LaTeX before it was compiled to a pdf file. Moreover, when compiling only a part of the code, only for that part would the LaTeX be generated.

Haskell instead.

I quickly realized that writing such a DSL was going to take an enormous amount of time. It would take so much time that I would never even get to writing my notes.

As it happens, Haskell is really good for writing EDSL’s, and the HaTeX library already existed so I would not have to reinvent the wheel. The combination of Haskell and HaTeX already had most of the features I was looking for. Functions can be used as LaTeX macro’s and they can already be curried. Haskell has local constants and is Turing-complete.

The other features I would have to implement myself. I set out to create what would eventually become the back-end system for The Notes.

Writer experience

The idea is to have the writer focus on writing and not on how to swashbuckle with annoying syntax and repetitive LaTeX code.

The building block of these notes is a data type called Note. Note is a Monad that takes care of all the required features while providing a clean interface to write my notes. Note is also an instance of IsString such that I can write literal strings and they will end up in the notes as expected.

LaTeX packages

When writing LaTeX, we often find that we need some external package, add it to the preamble, and then continue writing. There are two problems here:

You need to manually manage the packages that your code uses

Packages can conflict or malfunction when they are loaded in the wrong order.

Note uses the packageDep :: Text -> Note function to declare that a certain package is required. Note then makes sure that the right \usepackage statements end up in the preamble and that they are in the right order.

Chapters, sections and paragraph

To allow for subpart compilation, I chose the level of chapters, sections and paragraphs with respect to granularity. Sections are written with the section :: Text -> Note -> Note function. Code for a section then looks really simple:

mySection ::Note
mySection = section "here be a title"$do"Here are the contents of my section"

Note will take care of ensuring that the LaTeX code for this section only gets generated when it is selected for compilation.

Generation of graphics

All the power of Haskell is at the writer’s disposal for the generation of content, and some parts are made even more convenient. For example, a Bayesian Network record :: BayesNet can be drawn with bnFig.

bnFig $BayesNet ["A", "B", "C"] [("A", "B"), ("B", "C")]

Similar code works for finite state automata, lattices etc. All you need to do for this to work is tell Haskell how to turn your data type into a graph by instantiating the Graph Typeclass. Note will then take care of generating the illustration before the LaTeX compilation, caching it for later re-use and generating the right reference to it to put in the resulting LaTeX code. Note will also make sure that if there are multiple of these dependencies, they will be resolved in parallel.

Safe references

When you write a reference in LaTeX with \ref{<foo>}, and there is no corresponding \label{<foo>}, the compilation will succeed as normal, but there will be an ugly “??” in your pdf where the reference was supposed to be. In the notes, references are made with ref :: Label -> Note and labels with lab :: Note -> Note.

Note takes care of making sure that there is a lab for every corresponding ref and, unless you use --ignore-reference-errors, it refuses to compile the document if there are missing labels.

Code generation with Template Haskell

To write beautiful notes with a lot of internal references and a nice index, a lot of repetitive code is required. I opted to take the grind out of this process by writing some template Haskell that generates the necessary functions to lift the burden from the writer.

When the writer declares a term with makeDef "pie", Template Haskell will generate some functions such that pie :: Note is now available for literal usage. Using pie also ensures an entry in the index at the back of the pdf. Note that spelling errors now become compile-time errors for these terms.

pie' is the bold version of pie. pie_ is a literal version that includes a note that references pie' for easy referencing of terms. The functions pies and pies' are also generated to be used as plurals and they take care of referencing and indexing as well.

My school work has finally produced something worth showing off. For a “Program Analysis” course, Pavel Kalvoda and I have made a new proof-of-concept program analysis tool for Haskell. I will not go into how exactly the tool works, but rather how you can use it.

Patterns and background

On a very high level, Haskell’s argument patterns let us define the value of function applications for different inputs. Take the following function as an example:

f ::Bool->Bool->Int
f FalseTrue=1
f FalseFalse=2
f False _ =3

The result of this function, when given input of the form f False True, is 1. On the other hand, if the are of the form f False False, then the result is 2.

First notice that the last clause, namely f False _ = 3, is redundant. It will never be selected and removing it will not change the semantics of the function.

Second, notice that these patterns are not exhaustive, namely there are inputs for which no clause can be selected. In this case, f True False would be one such example.

Next, observe the following example:

g ::Bool->Bool->Int
g _ True=1
g TrueTrue=2
g _ False=3

Now, notice that the second clause will never be selected for evaluation, because anything that would be selected by the second clause will already have been selected by the first clause. However, removing the second clause will change the semantics of the function, so it is not redundant. In particular, the evaluation of g undefined False will diverge while without the second clause it wouldn’t. We say that the second clause has an inaccessible right-hand side.

Non-Exhaustiveness, redundancy and inaccessible right-hand sides are three issues that usually indicate a problem with the code. Non-exhaustiveness and redundancy used to be addressed by GHC already (with -Wall), but recently a paper appeared that addressed all three of these problems and immediately also addressed them for GADTs and guards too.

Their approach was parametric in a so-called oracle that would have to be able to tell whether certain constraints are satisfiable. These constraints could be divided into term-constraints and type-constraints. They used a non-trivial type-constraint oracle, namely the GHC type-checker and a near-trivial term-constraint oracle. This meant that, even though their algorithm would allow for analysis of guards, in practice there was still not much improvement on that part.

This is where we come into the picture. We reproduced their algorithm and implemented a non-trivial term-constraint oracle to perform a more precise analysis of guards. The resulting code can be found on Github. In what follows, I will discuss the tool we built and our results.

Exhaustiveness, Redundancy, Inaccessibility

First of all, our tool can still handle the same problems as GHC 7.10.3 could:

For example, in the case of the following function (the first example from earlier) …

f ::Bool->Bool->Int
f FalseTrue=1
f FalseFalse=2
f False _ =3

… our tool would output the following recommendations:

In function f:
The patterns may not be exhaustive, the following clauses are missing:
f True _
The following clause is redundant:
f False _

However, our tool can now also do more than that.

For example, consider the following (erroneous) implementation of an absolute value function:

abs ::Int->Int
abs x
| x <0=- x
| x >0= x

Our tool will identify the problem, show you under which circumstances the problem manifests itself and show you an example of such a situation.

In function abs:
The patterns may not be exhaustive, the following clauses are missing:
abs a
Constraints:
not (a > 0)
not (a < 0)
Satisfiable. Model:
a = 0 :: Int

It can also figure out if guards are redundant. Consider the following function:

bguard ::Bool->Int
bguard x
| x =0| not x =1| otherwise =2

The tool will figure out that this last guard is redundant:

The following clause is redundant:
bguard x | otherwise

Evaluatedness

There is another nice consequence of the way this analysis happens. Other related analyses become a lot simpler.

We built a proof-of-concept implementation of a tool that tells you how, when and how deeply arguments to a function will be evaluated during pattern-matching.

As an example, consider the fst function:

fst :: (a, b) -> a
fst (a, _) = a

The evaluation of fst undefined will diverge while the evaluation of fst (undefined, undefined) will not diverge during pattern-matching. This is because the fst function only evaluates the topmost constructor ((,)) during pattern matching.

Our tool will produce the following output:

Evaluatedness of 'fst'
fst a
a: a

This should be read as: “When fst is evaluated with an arbitrary argument that we will call a, the first constructor of a will be evaluated.

Let’s take a more complicated example. Consider the following contrived example of an implementation of a length function:

This shows that it figures out that the list constructors will always be evaluated up to two levels deep, but that the contents of the list will not be evaluated. Indeed, length [undefined, undefined] will simply be evaluated to 2.

Conclusion

This is by no means a production-ready tool, but it was really fun to build. We hope that the tool can be of some use anyway, either academically or practically.

The function pandocCompilerWithTransform expects a Pandoc transformation myTransform :: Pandoc -> Pandoc. and applies it to the result of the pandoc compilation. We’ll implement this Pandoc transformation such that it adds the ERT at the top of the blogpost.

Slot machines and distractions

The basic idea is that some of current technology is addicting because it acts exactly like a slot machine. You pull a lever to sometimes (!) get a reward. Apparently that is incredibly addicting to humans. Examples include ‘pull to refresh’ or clicking ‘receive email’.

The fact that we spend our lives at these slot machines hit me so hard that I decided to try and throw away as many of them as I can. It has proven not to be a trivial task.

In the past I have already made an effort to get rid of distractions. Unfortunately, getting rid of distractions the naive way will often create another slot machine and vice versa. For example, if you turn off notifications from receiving an email, the unconscious fear of missing something important (FOMSI) can cause you to start checking it addictedly. Then it becomes a slot machine. If you turn on notifications so you only need to check when there is something to see, then the slot machine disappears, but you will be interrupted again.

In what follows I will describe how I tried to remove the slot machine without turning them into distractions. It is about making sure that choices I make are conscious and that they really are choices that I want to make and want to want to make.

Low hanging fruit

Smart watch

A smart watch is not useful. It is fun, a nice gadget, but not useful. I have not missed it since I took it off.

Twitter

Twitter has not really brought me anything useful. It is fun, but addictive and not a slot machine I want within my reach.

Of course Twitter did not let me go so easily. I will get to delete my account in thirty days as long as I do not log in anymore. This really shows how they are trying to hijack your time.

Youtube

Google accounts are linked to everything made by Google, including email, so I cannot just remove it. What I can do is remove all of my subscriptions.

I will find out some way or another if there is some video that I really need to see. No need to play the slot machine to find out.

Facebook

Facebook has a great ‘settings’ board. Both privacy and notifications can be heavily configured.

I just set everything to ‘as few notifications as possible’ and turned off chat.

Phone

There is this ‘no notifications’ mode on Android phones. Of course just turning that on would just turn my phone into another slot machine. For this to work, I needed to first remove all slot machine apps from my phone.

Anything that has a ‘slide to refresh’ function has to go. That included reddit, stackoverflow, etc…

After that, turning off all notifications just relieved more mental pressure.

Email

Email is a necessary evil, so how can we make it less intrusive and still not a slot machine?

Removing all email notifications will turn email into a slot machine, but turning on notifications to not have to continuously refresh will make email intrusive again. I would have to make some special arrangements. Here is the current idea:

I only look at email once a day, in the afternoon.

I make sure that it is impossible to pull any slot machine levers

I make sure that I only get interruptions that are strictly necessary.

I have a little script called process-mail.sh that handles everything concerning receiving email. The first thing I did was to make sure that I do not run this script manually. I added this to the top of the script:

if [["$1"!="AUTOMATICALLY" ]]thenecho"You must not run this script manually!"exit 1
fi

It is not foolproof but it is a start and it ensures that I consciously choose to receive mail manually when I do.

Next, I made sure that I do not check email any sooner than the afternoon. Instead of processing email every five minutes, like I used to, I now only process email at 16:00.

This ensures that I do not pull any levers to receive email and that I cannot be interrupted by them either.

No classifier after all

I thought about making a classifier for emails that could tell when an email was important enough to interrupt me right then. I was ready to start implementing a classifier like this. I had looked up libraries, thought about how to arrange the system and how to make the training data. Then I realised that there would be no emails at all that I would ever classify as ‘worth an interruption’. So after all, as fun as it may have been, I will not be writing a classifier for now.

]]>Sun, 29 May 2016 00:00:00 UThttp://cs-syd.eu/posts/2016-05-29-reducing-the-number-of-slotmachines.htmlTom Sydney KerckhoveIt's not about how others look at me. It's about how I look at myself. - Will Fratallihttp://cs-syd.eu/quotes/2016-05-22-its-not-about-how-others-look-at-me-its-about-how-i-look-at-myself---will-fratalli.html
[ERT: 1m16s]

I like to dress up. For some reason my clothing has prompted many strong opinions on the matter. In this post I’d like to put some misconceptions to rest.

Suits

Will Fratalli is a fictional character. He’s a blind tutor to a recently deformed kid that is obsessed with his appearance. This character manages to voice my opinion on the matter perfectly.

I don’t care about what people think about how I look. I do, however, care about what I think about how I look.

I am fortunate enough to be able to see and fortunate enough to have a choice in the matter of what I get to wear. I am young and lucky to be healthy. This is the perfect time to enjoy being able to dress up however I want.

I love to wear suits, so I wear suits. That is all.

Misconceptions

Doesn’t it make formal occasions less special?

Maybe, but why should only formal occasions be special? For me, every day is special.

Aren’t suits really uncomfortable?

No, they’re like a sweat suit over your entire body, but one that looks really good.

So, you always wear suits?

No, of course not.

You look like you consider yourself superior to others.

That’s really not my problem. Again: I don’t care what you think about it.

Our way of writing down numbers is quite well designed. It allows for some very clever tricks when performing simple algebraic computations.

For example, long multiplication and long division are a very handy side-effect of our number system. Unfortunately our first introduction to numbers is usually accompanied by a lengthy explanation of all the clever tricks that can be used to quickly compute the value of simple expressions. Our teachers get so caught up in teaching those clever tricks that they forget to teach the most fundamentally important concept in elementary mathematics: Asking questions.

In what follows, I will explain numbers and how elementary algebra is just fancy counting. I will deliberately focus on the meaning of operation rather than on how to practically compute the result.

Back to the basics

Dots on a line

There’s no need to start with an abstract definition of a number. Instead, draw a line with an ellipse on one end. Now draw some dots on that line approximately equal distances apart.

This ellipse happens to be called ‘zero’. Numbers are about asking the question “How many steps away from zero is this dot?”.

After the first step we are at one, after another step we find ourselves at two and after one more step we arrive at three.

To be honest, the way we name and write down numbers already seems way more confusing than the numbers themselves. The symbols are arbitrary and the names even more so, but we know how to count, so let’s start counting.

Addition and subtraction

Let’s take an example. If we start at zero, take three steps to arrive at \(3\), then take five more steps in the same direction, we arrive at a dot that we label \(3 + 5\). We pronounce \(3 + 5\) as ‘the sum (or addition) of \(3\) and \(5\)’.

Note that the counting happened before the labeling. Addition is just the name for this way of counting.

The addition, the number with label “\(n + m\)”, of two numbers \(n\) and \(m\) is all about the following question:

“If I’m at \(n\), then take \(m\) steps in the direction away from zero, where do I end up?”

If we go about it the other way around, and take \(5\) steps first, then \(3\) more steps, we arrive at a dot that we would like to label \(5 + 3\). However, we notice that it’s already labeled \(3 + 5\). Similarly, if we just take \(8\) steps starting from zero, we arrive at that same dot as well. This is why we state that \(3 + 5\) equals \(8\), as well as \(5 + 3\).

Again, note that we start with the process and conclude that 8 equals \(3 + 5\), not the other way around. In the case of numbers, ‘equals’ just means ‘using these two different ways of counting, we arrive at the same dot.’.

Let’s take another example. If we start at \(8\) and step backwards for \(3\) steps, we end up at a number that we label \(8 - 3\). This number happens to be \(5\). In other words, to get to \(8\), starting from \(5\), it takes us \(3\) steps. That’s why we say \(8 - 3\) equals \(5\). This label \(8 - 3\) is called the subtraction of \(3\) from \(8\).

The subtraction \(n - m\) of two numbers, \(n\) by \(m\), requires the following question:

“If I’m at \(n\), then take \(m\) steps back into the direction of zero, where do I end up?”

or, alternatively:

“If I’m at \(m\), how many steps do I have to take to get to \(n\)?”

Multiplication

Up until now we’ve only ever taken one step at a time. Steps of plus one, if you will. Let’s see what happens if we take bigger steps.

Suppose we are at zero and start taking steps away again. This time, however, instead of taking steps of plus one, we take bigger steps, say steps of plus two, for example. After one big step of plus two we arrive at two. After another such step we are at four and one more step later we get to six.

Because it takes \(3\) steps of \(+2\) to get to \(6\), we say that \(3 \times 2\) equals \(6\). Incidentally, taking \(2\) steps of \(+3\) also gets us to \(6\).

Now it’s easy to see that taking no steps of arbitrary size gets us nowhere. We would just stay at zero doing that: \(0 \times anything = 0\). Similarly, taking any number of steps wherein we don’t move forward at all, gets us no further either: \(anything \times 0 = 0\).

The multiplication \(n \times m\) of two numbers \(n\) and \(m\) is about asking the following question:

“If I take big steps of size \(m\), where do I end up after \(n\) of such steps?”

If we describe this ‘taking steps of \(+something\)’ behavior can be described as ‘living in a \(+something\) system’. In a \(+something\) system, we can only take steps of \(+something\).

Now we can ask the question of the multiplication of \(n\) and \(m\) in terms of such a system:

“In a system of \(+n\) steps, where do I end up after \(m\) steps?

Division

Let’s say we are back in this \(+2\) system. We can only take steps of \(+2\). How many steps does it take to get to \(8\)? As we saw in the previous section, we need \(3\) steps of \(+2\) to get to \(6\). One more step of \(+2\) then gets us to \(8\) so it takes \(4\) steps of \(+2\) to get to \(8\).

Because it takes no steps of arbitrary size to get from \(0\) to \(0\), we say \(0 \div anything = 0\).

Now comes the striking idea of division by zero. Let’s see if you can figure out why division by zero has no good answer.

It takes \(3\) steps of \(+4\) to get to \(12\), so \(12 \div 4\) equals \(3\), but how many steps of \(+0\) do we need to get to \(12\)? In other words, what is \(12 \div 0\)? There is no number of steps of size \(+0\) that you could ever take to arrive at \(12\), so we say \(12 \div 0\) is undefined. Similarly, \(anything \div 0\) is undefined.

Undefined, in the case of numbers, just means ‘there is no good answer to the question that these symbols represent’.

Division is to Multiplication as subtraction is to addition. As such, the division (or quotient) \(n \div m\) of a number \(n\) by another number \(m\) is about asking the following question:

“How many steps of \(+m\) does it take to get to \(n\)?”

or, alternatively, using the system explanation:

“In a \(+m\) system, how much is \(n\)?”

You see, \(8\)is\(4\) if you are counting in \(+2\)-sized steps and \(12\)is\(3\) in a \(+4\) system.

You could say that \(4\) is \(4\) in a \(+1\) system. Similarly, \(9\)is\(3\) if you are counting in a \(+3\)-sort-of-way.

Pause to breathe

At division is where most people stopped trying to push elementary mathematics into their brains. I challenge the idea that not everyone can understand the basics. As I said, it’s all about questions. A curious student will, at this point, have started to ask more of their own questions.

“Why not continue this trend of changing systems?” “What happens if I take different kinds of step?” “Do I have to take equally large steps every time?”

That’s exactly where the next part takes off.

Powers

Up until now, we have only taken steps of \(+something\). We know what multiplication is now, so let’s try taking steps of \(\times something\).

You’ll notice you won’t get very far if you start at zero, so we’ll have to start from somewhere else. How about one? Let’s draw that line again:

Let’s look at a system of \(\times 2\).

After one step, we’re at \(2\). After two steps, we find ourselves at \(4\). The third step(power) brings us to \(8\).

The idea that steps of \(\times 2\) are somehow ‘larger’ can be misleading. They are just a different way of counting. As such, we can draw this line with the dots placed in such a way that the steps seem equal in size. This makes it easier to simply think of them as different steps.

After two steps of \(\times 3\), we are at \(9\). This is why we say that the second power of three (\(3^2\)) is \(9\).

Finding \(n^m\), the \(m\)-th power of \(n\), is about asking the following question:

“In a \(\times n\) system, where do we end up after \(m\) steps?”

Logarithms

Now for the operation that looked like alien magic the first time we looked at it: logarithms.

Let’s start with an example. If we take \(3\) steps of \(\times 2\) and end up at \(8\), that means it takes \(3\) steps of \(\times 2\) to get to \(8\).

How many steps of \(\times 3\) does it take to get to \(9\)? Well, just count them. We need to take \(2\) steps of \(\times 3\) to get to \(9\).

\(9\)is\(2\) in a \(\times 3\) system. \(8\)is\(3\) in a \(\times 2\) way of counting. \(4\)is\(2\) in a \(\times 2\)-sort-of-way.

Because \(2^3\) equals \(8\), we say that the logarithm, in a \(\times 2\) system, of \(8\) is \(3\). Because \(2^3\) equals \(8\), we say that the logarithm, base \(2\), of \(8\) is \(3\).

How many steps of \(\times 5\) does it take to get from \(1\) to \(1\)? Zero steps. We say that \(\log_{5} 1\) equals \(0\). Similarly, \(\log_{anything} 1\) equals zero.

How many steps of \(\times 0\) does it take to get to \(7\)? You can take any number of steps of \(\times 0\), but you will never move go anywhere except to \(0\). As such there is no number of steps that you could take to get to \(7\) in a \(\times 0\) system. We say \(\log_{0} whatever\) is undefined.

Now we will investigate why there was no way to put \(0\) on the ‘log’ scale we drew earlier. To plot \(0\), we would have to count how many steps, forwards or backward, of size \(\times 2\) we would have to take to get from \(1\) to \(0\). Because no number of steps suffices to get to \(0\), we say that \(\log_2 0\) is undefined. Similarly \(\log_{whatever} 0\) is undefined. This is why we cannot plot \(0\) on a log-scale.

Computing \(\log_{n}{m}\) is about asking the following question:

“How many steps of \(\times n\) does it take to get to \(m\)?”

or, alternatively:

“In a system of \(\times n\), how much is\(m\)?”

Square Roots

Roots are the most confusing of the elementary operations in my opinion.

Now we’re going to look at things that are \(2\) in a \(\times something\) system. 4 is \(2\) in a \(\times 2\) system, \(9\) is \(2\) in a \(\times 3\) system, \(16\) is \(2\) in a \(\times 4\) system. Things that are \(2\) in a \(\times something\) system are called squares and their systems are called the square roots. That means that \(4\) is a square with square root \(2\), \(9\) is a square with square root \(3\) and \(16\) is a square with square root \(4\).

If it took me two steps in a \(\times\)-something system to get to \(9\) so they must have been \(\times 3\)-steps.

If \(16\) is \(2\) in a \(\times\)-something system, then it must have been a \(\times 4\) system because \(1 \times 4 \times 4\) equals $16.

Computing \(\sqrt{n}\) is about asking the question:

“If I know I took two steps in a \(\times\)-something system to arrive at \(n\), how big were my steps?”

Conclusion

Numbers don’t have to be confusing. You just need to learn to ask the right questions and stay curious.

If you liked this explanation, and there is some other bit of mathematics that you would like explained, please let me know. I love explaining maths to people who really don’t like maths (yet).

I’ve recently been teaching mathematical induction to second-year university students of informatics. I’d like to summarize some of the background around induction proofs, as the subject slightly more complicated than a single class warrants.

Preliminaries

Predicate

Let \(A\), be a set. A predicate on \(A\) is a subset of \(A\).

The difference between a predicate and a subset lies in the way we talk about them. We say a predicate \(P\) holds for an element \(a\) of \(A\), if \(a\) is an element of \(P\). We write ‘\(P\) holds for \(a\)’ as \(P(a)\).

For example, \(\{ x \in \mathbb{N} \mid x < 5\}\) (\(= \{0, 1, 2, 3, 4\}\)), is a predicate on \(\mathbb{N}\). This predicate can be written in terms of a single logical expression involving a ‘parameter’ from \(\mathbb{N}\) as follows: \[
P(n) = n < 5
\] We can therefore abbreviate it as \(\overset{<5}{\triangleleft}{A}\), \(\lambda x \rightarrow x < 5\) or simply \((< 5)\) using some notational abuse.

Binary Relation

We will restrict our attention to internal binary relations:

Let \(A\) be a set. A binary relation on \(A\) is a subset of \(A \times A\).

The difference between a binary relation and a subset of \(A \times A\) again lies only in the way we talk about them. If \(R\) is the symbol for a given binary relation, we abbreviate \((a, b) \in R\) to \(a R b\).

For example, ‘divides’ (\(\mid\)) is a binary relation on \(\mathbb{N}\) that contains the tuples \((a, b)\) for which \(a \mid b\) holds.

Reflexivity

We call a relation \(R\) on a set \(A\)reflexive if the following property holds: \[\forall a \in A: (a, a) \in R\]

Well-founded relation

We will need well-founded relations in well-founded induction so let’s define them up front.

Let \(A\) be a set and \(\prec\) a binary relation on \(A\). We call \(\prec\)well-founded if there don’t exist any so-called ‘infinitely descending chains’ in \(A\). In other words, the following property holds for \(\prec\). \[ \neg \left( \exists \left\{ a_i \in A \mid i \in \mathbb{N} \right \}:\ \forall i \in \mathbb{N}:\ a_{i+1} \prec a_i \right) \]

Exercise: Prove that a non-empty well-founded relation cannot be reflexive.

Otherwise we can take an arbitrary element \(a\) and build the infinite descending chain of only \(a\)’s.

Note that this means that a non-empty well-founded relation can never be an order as orders are defined to be reflexive.

Minimal element

A minimal element is usually defined for partial orders, but we can define it for a well-founded relation as well:

A minimal element \(m\) of a set \(A\) according to a well-founded relation \(\prec\) is an element as follows: \[ \neg \exists a \in A:\ a \prec m \]

Note that if we were to define the minimal element of a partial order in the same way, we would have to add the requirement that \(a\) should be different from \(m\) in the defining formula, otherwise there could never be any minimal elements for a partial order because partial orders are reflexive by definition.

Well-founded induction

The must fundamental kind of induction that I teach is well-founded induction.

Let \(A\) be a set and \(\prec\) a well-founded relation on that set \(A\). Let \(P\) be a predicate on the set \(A\).

An intuitive explanation

An intuitive explanation for why this inference rule makes sense can be stated as follows. (Of course this could never be the real proof because that would make for a cyclic argument.)

We assume the left-hand side of the implication (\(\Rightarrow\)) and prove the right-hand side.

Let \(M_0\) be the subset of \(A\) that contains only the minimal elements of \(A\). In other words, let \(M_0\) be the following subset of \(A\): \[ M_0 = \left\{ m \in A \mid \neg \left(\exists n \in A:\ n \prec m \right) \right\} \]

Note that for all the elements of this set, \(P\) must hold according to the our assumption.

We now define the subset \(M_i\) of \(A\) for an \(i \in \mathbb{N}_0\) as follows: \[ M_i = \left\{ m \in A \mid \forall n \in A:\ n \prec m \Rightarrow n \in M_{i-1} \right\} \] Intuitively this is the next set of elements for which we prove that \(P\) holds. We use our assumpution again to prove that \(P\) holds for all elements in \(M_{i}\) because it holds for all elements in \(M_{i-1}\). If we go on like this, eventually we will have shown that \(P\) holds for all elements of \(A\).

Why a well-founded relation

Note that if \(\prec\) would not be well-founded, then by definition there must exist an infinite descending chain of elements in \(A\). If there exists an infinite descending chain of elements in \(A\), then there need not exist any minimal elements. (Allthough the non-existence of minimal elements is not a necessary requirement for there to be a problem, this is the simplest way of showing that at least well-foundedness is necessary for induction.) If there aren’t any minimal elements in \(A\) then there is no way to start the recursive argument that we build in the previous section.

Suppose, for example, that we would use a reflexive relation, then \(\left(\forall b \in A:\ b \prec a \Rightarrow P(b)\right) \Rightarrow P(a)\) is automatically true for all elements \(a\) in \(A\) and all predicates \(P\) on \(A\) while \(\forall a \in A: P(a)\) may not be true.

Structural Induction

Structural definition is a special case of well-founded induction where the set \(A\) is a set of terms in some recursively defined language of terms. For example, \(A\) could be the set of trees in Haskell:

dataTree=Leaf|BranchTreeTree

The well-founded relation that is then used is called a subterm relation \(\sqsubset\). It is usually defined as the transitive closure (smallest relation that includes the original but is also transitive) of the obvious well-founded relation that defines any term to be a subterm in another term if it is part of the recursive definition of that term.

For example, in the case of Trees, that would mean that \(\sqsubset\) is defined as the transitive closure of the relation recursively defined as follows:

The subterms are [2,3], [3] and []. [1, 2] is not a subterm as per this definition.

A note on structural induction on data in Haskell

Inductively defined terms in a language are usually defined to be finite in depth. As it would be undicidable in general to check whether a function produces only finite terms, and Haskell uses lazy evaluation anyway, Haskell’s types naturally contain infinite terms as well.

However, for a subterm relation to be well-founded, \(A\) must contain only terms of finite depth. Otherwise there trivially exist inifinite descending chains of subterms. As such we have to assume terms in depth when writing induction proofs.

Natural induction

The (strong) natural induction inference rule is just a special case of structural induction as per the von Neumann construction of natural numbers.

Alternatively you could say that it’s a special case of well-founded induction by proving that \(<\) on is a well-founded relation on \(\mathbb{N}\).

How to write an induction proof when your grades depend on it

A proof is for humans. The languages we use for communication with other humans tend to have enough redundancy built into them such that even when words are omitted in speech, communication can still proceed safely. This implies that we tend to consider communication, as we would use it in speech, slightly redundant when we write it down. There is enough context, and words will not just dissapear in text, to make out what was meant.

In the same way, a mathematically inclined person will be able to figure out from the context what you meant with a proof. This comes in handy in literature, but can be confusing in class.

In class, the person grading your solution does not care as much for checkng whether the theorem holds (through the proof) as they do for checking whether you wrote down a correct proof (even if it’s already clear that the theorem holds), understood the material and should be awarded a good grade as a result. The way you write down proofs should be different.

Write down the set \(A\) you want to inductively prove a predicate over.

Write down the predicate \(P\) that you want to prove for all elements of that set.

Make sure that the ‘argument’ to the predicate is in fact in the set that your predicate is on. That is, \(P\) is in fact a predicate on \(A\).

Define the well-founded relation that you will be using and prove that it is in fact well-founded if it’s not a commonly-known-to-be-well-founded relation like \(<\).

If you make a case distinction, write down that you are trying to make a case distinction and prove that the union of the cases forms the universe that you would like to make the case distinguish in. For example, \(x = 0\) and \(x \neq 0\) are complementary but \(x = 0\) and \(x > 0\) may not be.

In a case distinction at the top-level, write down the predicate again for each specific case. For example, in the case of Haskell lists, write out what \(P(\)[]\()\) means explicitly for the base case.

In the case of weak natural induction, write down the induction hypothesis explicitly if you refer to it.

A general schema for a structural induction proof

Let \(Q\) be the description of some predicate on a set of terms \(A\). This description will usually not be given a name separately. Suppose we are trying to prove \(\forall a \in A: Q(a)\). The rest of this section is a general schema for a proof that uses strong structural induction. The blanks, indicated by the fact that they are written in code style, are the parts that you fill in for a concrete proof. The rest can remain virtually untouched.

Theorem: \(\forall a \in A: Q(a)\)

Proof:

Define \(P\) to be a predicate on the set \(A\) as follows:

[Definition of P]

We prove this theorem by strong structural induction of the predicate \(P\) over the set \(A\) using the following subterm relation \(\sqsubset\).

[Definition of ⊏]

Note that \(\sqsubset\) is in fact well-founded:

[Proof that ⊏ is well-founded]

Let \(a\) be an arbitrary element of \(A\). We distinguish the following cases:

(Base cases) \(a\) is of the form minimal element of A. We prove P(a) in this specific case:

Proof that P(a) holds.

(Inductive case) \(a\) is of the form construction from subterms b, c, ... in A for some subterms b, c, ... in \(A\). We prove P(a) in this specific case from P(b) ∧ P(c) ∧ ... (which we call the induction hypothesis).

Proof that P(a) holds.

(Conclusion) By the inference rule of strong strucural induction and the cases numbered 1 and 2 above, we conclude that \(P\) holds for all elements of \(A\).

QED.

P.S. If you like this way of explaining maths, you should have a look at my math notes.

In this post I will go into why a functor is not a box, and why it is a bad idea to to explain functors as such. The ideas in this post extend beyond the problem of explaining functors, but functors will serve as a good example.

I have been thinking a lot about inaccuracies in teaching lately. I have come to the conclusion that inaccuracies may be required for a good explanation, but they have to be handled responsibly. In my opinion, inaccuracies should only be considered responsible if they approximate an accurate description of the real situation. That means that any explanation that is verifiably false should be considered irresponsible and must be avoided.

Boxes?

The most pungent example that came to my mind on this topic was how functors are usually explained as boxes. Functors are often explained as “A functor is a box”, or the slightly better “A functor is like a box”. Examples of this can be found here, here, here and here, but also here and here, here, here, here and some more here (and that’s just the first two pages of Google’s results for ‘A functor is a box.’).

I would like to address this as a didactic failure. I have only two ways of responsibly explaining the concept of a functor and they certainly do not include a box-analogy.

If you don’t agree that a function is not a box, at least give me that it’s not cuboid-shaped nor has a lid.

Okay, maybe not a box but…

Sometimes we see other analogies like a ‘container’, which is only marginally better because we never used any box-specific properties of a box (like its cuboid shape) in what’s written above so we might as well have written ‘container’. ‘Mappable’ is also sometimes used, but as discussed in the Const a example, it is also only slightly better as any type can be made mappable by adding a phantom type variable. Of course you can still accurately call a Functor a box if you defined ‘box’ to mean ‘Functor’ but then the point of the analogy breaks down.

Why boxes?

If Functor really doesn’t mean ‘box’, why do so many blog posts appear that say otherwise? This is speculation, but my guess is that the writers of these explanations want to explain the concept of a Functor such that readers who haven’t understood higher-kinded types and/or type classes may understand it as well. This is perhaps a noble endeavor, but I consider it harmful to the reader. By willfully writing erroneous explanations, they deny the reader good foundational knowledge of what a Functor really is.

It is essential that a beginner Haskell programmer figures out what type classes and type constructors are before learning what a Functor is. Similarly, you wouldn’t try to explain what a mammal is by saying ‘a mammal is a human’, even if you don’t want to explain where milk comes from.

I’ve had the enormous privilege to live with an aspiring magician myself. I’ve witnessed first-hand how magical seemingly benign manipulation of small objects can amaze the smartest people.

Of course it is amazing to see my brother’s show. Audiences get to enjoy a night of bewilderment and laughter. I can only imagine how invigorating it must feel for him.

If you only come to the show, you will never see the real work. For every hour of a show, he spends at least 40 hours practicing. I’m not saying he finds it any less enjoyable but it’s important to realise what kind of work goes into making magic happen.

Not all magic happens during one of my brother’s shows. Other people too do amazing work. Oddly enough, the fact that magicians practice a lot is comparatively well-known.

We each know how much we work ourselves and we know about our achievements through it, but somehow we never fail to underestimate how much another person may be willing to work for their goals.

This is not something to be disheartened by. It means that you too can achieve magic. It may, however, just require you to spend more time than anyone else might reasonably expect.

Working from home is an increasingly available option where it used to not be possible at all. Unfortunately that also means that not as much is known about working from home. An entirely new set of best practices is required.

One of the main advantages of working from home is that you don’t have to get dressed. You can just wear your pyjama’s all day.

Unfortunately, working in your pyjama’s is not as good an idea as you may originally have thought. Yes, you save yourself the time it takes to get dressed and you may be much more comfortable, but the hidden disadvantages are overwhelming.

We have been trained to get ready to sleep when we wear our pyjama’s. As a result, working in our pyjama’s has a habit of making us rather unproductive/lazy.

When you work in your pyjama’s, you’re telling your brain that “It’s all right. We’re going to bed soon. You can doze off now.”.

We need to make it a habit to tell yourself to get our clothes, go to the bathroom, wash up and get dressed. Then get back to work.

Polyvariadic functions can be useful to improve the user experience when writing an EDSL in Haskell. Instead of making your users write doSomething ["With", "these", "arguments"], you could have them write doSomething "With" "these" "arguments".

Your intuition will probably tell you that making a polyvariadic function will be unsafe, but Haskell allows you to make it safe. Of course it is not as easy as in Python, but then again, polyvariadic functions in Python will never be type safe.

Background: Currying

The concept of currying needs to be very clear before we can dive into polyvariadic functions.

A function with two arguments: f :: a -> b -> c really only has one argument. The -> operator is right-associative, so we can rewrite this type signature as f :: a -> (b -> c). This means that f takes a value x :: a and gives you a function f x :: b -> c.

When we write down functions with ‘multiple arguments’, the parentheses are usually omitted, but in reality f x y z is parsed as ((f x) y) z.

The problem of polyvariadic functions

What we want to build is a function of type a -> (a -> (a -> (... -> b ))) where the length of this chain of -> operators is determined by how many arguments are given to the function.

Meanwhile, we would like to implement this function as if it were of type [a] -> b.

Keep in mind that, with what I am about to show you, it is also possible to implement more complicated polyvariadic functions (for example with different types as arguments).

A first draft of a solution

The trick that we will employ to make this happen will involve a typeclass. Let’s say we would like to build the polyvariadic equivalent of a function sumOf :: [Int] -> Int. We would then write a typeclass SumArgs as follows:

classSumArgs a where sumArgs :: [Int] -> a

Instances of this class, ‘know how to make a value of their type from a list of integers’.

This may look like black magic at first. I will explain how this works right now. Why it is useful should become clear later.

Note that the sumArgs function in the second instance is of type SumArgs r => [Int] -> (Int -> r). That is, given a list of integers is :: [Int] and another integer i :: Int, we have to build a value of type r where r has a sumArgs instance. r, having a sumArgs instance, can be built using sumArgs :: SumArgs r => [Int] -> r if we have a list of integers. We will build this list by adding i :: Int to the existing list is :: [Int].

Now we are ready to add the functionality that will use sumOf :: [Int] -> Int in a polyvariadic context. We will do this with another instance:

instanceSumArgsIntwhere
sumArgs = sumOf

This instance explains how to build the result (of type Int) from a list of Int arguments.

We could now use sumArgs as let f = 5 :: Int in sumArgs [] f f :: Int and we would already have a polyvariadic function, but the empty list n there is still ugly.

Under the hood of the black magic

sumOf' f g is declared to be of type Int, which means we can write it as sumArgs [] f g :: Int.

If we add the parentheses in the right places, we get ((sumArgs []) f) g :: Int. Now we will examine what Haskell’s type inference does:

Peeling off one layer, Haskell figures out that (sumArgs []) f must be of some type c -> Int where g is of that type c.

Peeling off the next layer, Haskell figures out that sumArgs [] must be of some type b -> c -> Int where f is of that type b.

It knows that sumArgs is of type [Int] -> a.

It identifies a with b -> c -> Int to come to the conclusion that sumArgs is of type [Int] -> b -> c -> Int where b and c are the types of f and g, respectively.

Because it knows that f and g are both of type Int, it specializes the type of sumArgs to [Int] -> Int -> Int -> Int, which is exactly what we want.

The reason that sumArgs :: [Int] -> Int -> Int -> Int is a valid type signature, is because Int -> Int -> Int has an instance of SumArgs. Int -> Int -> Int has an instance of SumArgs because Int -> Int does. Finally, Int -> Int has an instance of SumArgs because Int does.

Backward compatibility

I motivated polyvariadic functions by arguing that they look nice in EDSLs. If you are interested in improving the user experience of your EDSL, chances are that you have already implemented it. This means that there is probably already a bunch of code that uses sumOf :: [Int] -> Int directly. Now, there is a way to change the type of sumOf to SumArgs args => a without breaking any of your users’ code and it is by adding one more instance to the above code:

This isn’t as much a famous quote as it is a life motto from a good friend. Don’t be afraid to be an additional agenda item. Don’t be afraid to be deviant.

From a young age our whole lives seem to be laid out for us. Because this is a consequence of the fact that we were fortunate enough to be born rich, we are expected and taught to be grateful for this ‘guidance’. Any deviation from this ‘ideal’ path is frowned upon and considered ungrateful. We are quickly branded as weird as soon as it becomes clear that we aspire to deviate from the norm. It is considered rude and problematic. Next thing we know, we are an additional agenda item in the weekly meeting of the ones that lay out that path.

Years later those who grew up in this kind of environment will either resent it and move away or help maintain this imprisonment of averages. The entire culture now embodies this pursuit of mediocrity and the dangers of such a toxic environment could well make up a shelf of books.

Because you’re reading this, I will assume that you are one of the people who has not been rigorously average their entire life. At some point you must have felt guilty. Being warned about the fact that you were a separate agenda item will have felt at least a fraction as bad as it was meant to make you feel. Of course when you think about it, the greater fear would be to never be a separate agenda item.

Ultimately you will regret having been average more than you will regret pushing further. Knowing you conformed is never a defining moment.

This one bad day will not stop you from achieving your goals. What will stop you is if you let this bad day bring you down and make you give up.

Tomorrow will be better.

I know, you’re sad, so I won’t tell you to have a good day. Instead, I advise you to simply have a day. Stay alive, feed yourself well, wear comfortable clothes, and don’t give up on yourself just yet. It’ll get better. Until then, have a day.

Technical debt is a curious issue and a plague to say the least. Here are some tips to automatically keep it out of your code.

The problem

Wanting to finish our code quickly, for whatever reason, sometimes leads us to take on some technical debt. This could mean badly designed code, bandage solutions or even causes for an unnecessary amount of manual intervention.

Once technical debt is in the code, we will rarely take the time to pay it back. We’ll happily leave dirt hacks in the code as long as they make the difference between a working system and a non-working system.

I’m not going to go into the causes of technical debt. Both human and technical factors could be at the root of the problem, but I want to focus on some solutions. These are some ways to pick the low hanging fruit.

Git hooks

We can put some systems in place to automatically help us avoid technical debt. It’s important that these systems enforce discipline automatically and don’t require manual initiation.

Git hooks allow us to run arbitrary code at specific points in the version control process. In any git repository, we can find a .git repository with a directory of hooks:

Specifically I want to show what you can do with the pre-commit and pre-push hooks.

Style

As a warmup, you can implement automatic code formatting enforcement. You will need a command-line too that takes care of the formatting. Either a code formatter or a code style suggestion tool (like hlint) will do.

Let’s assume the tool is called linter. It should have an exit code other than 0 if there are any warnings or style errors.

We put it in .git/pre-commit:

set -e # Exit on first error
linter

Now, any time we run git commit, Git will call linter and prevent you from committing if there are any errors. Of course you can also circumvent this by adding --no-verify to the git command.

Recommended checks

Now that we’ve added our first git hook, we’re ready to start discussing what other checks should be enforced automatically. This discussion should ideally involve all the project’s contributors.

In my opinion a number of code health checks are important. These include checking that files don’t contain trailing whitespace, that code is indented correctly, that the linter doesn’t produce any warnings. Feel free to add anything you can come up with. Use the tools that are at hand for the appropriate programming language.

I also recommend checking that all the code still compiles without problems, that all of the tests still pass and maybe even that benchmarks haven’t gotten worse. Add checks for all predicates that you would like to be invariant under development.

Installing the hooks.

Even if you add the git hook scripts to your repository, you cannot force contributors to install them. This is a security feature of git. You can, however, make it easier for your contributors to install the hooks so that they don’t have to copy scripts around. Just put your hook scripts in a scripts directory in your git repository and add this ħooks.sus file to the top level directory:

If, like me, you’re interested in writing extremely safe code, you’ve probably been annoyed about function’s contract before. In this post, I present a way of improving the correctness of elegant code and the safety of correct code.

I will take a mathematical function as an example because that’s simpler, but the point stands for functions concerning business logic as well. I will use Haskell to show some code but the idea I present applies to languages other than Haskell as well. Even imperative and/or untyped languages.

Arguing with a programmer

Mathematical functions are quite easily designed with respect to error handling, right? When I ask you to implement the greatest common divisor function, you may have to look up Euclid’s algorithm, but you have a general idea of the expected result. You may implement something like this:

gcd ::Integer->Integer->Integer
gcd a b = gcd b $ rem a b

This code elegantly embodies the idea of Euclid’s algorithm, but it doesn’t even terminate. When I ask you to revise this code you will add the base case:

gcd ::Integer->Integer->Integer
gcd a 0= a
gcd a b = gcd b $ rem a b

Now this code terminates, but it’s incorrect.

First off: What is the value of gcd 0 0? gcd 0 0 is undefined, but this code will evaluate it to 0. When I demand you fix it, you grudgingly add a case for that as well:

gcd ::Integer->Integer->Integer
gcd 00= error "The greatest common divisor of 0 and 0 does not exist."
gcd a 0= a
gcd a b = gcd b $ rem a b

gcd is defined for negative numbers, but this code will not produce the correct result. In fact it will evaluate gcd (-25) (-5) to -5 while the greatest common divisor is mathematically defined to be a positive number.

You argue that people who use this function will know what they’re doing, but when I press you on it, you change the code again to fix this issue:

You look at the code some more and decide that its functionality is correctly defined. At this point I, annoyingly, argue that this simple function should be total. We can prove that it terminates for any input, but after writing this proof, we want to be sure that that means that our code is safe to run.

This code is not safe to run. Annoyed by my persistence, you make what you promise to yourself is the last change to the code:

Now I will argue that Maybe Integer is not really the right type for the result of this function because the result of gcd is always positive. I argue that we should define a more informative type Natural and make the return type Maybe Natural.

At this point you’re ready to start flipping tables so I stop arguing and leave it at this.

The result of my pestering

We’ve gone from some simple code that embodies the idea of the algorithm…

In the process, you went from happily looking at elegant code to disliking the code and figuratively pelting me with vegetables.

Solutions?

How then, do we write code that covers all cases without removing the elegance?

One obvious solution would be to keep the function simple, partial and only partially correct:

-- | Greatest common divisor-- -- Only produces a correct result for positive inputs a and b where at least-- one of a and b is non-zero. Will return bogus results otherwise.
gcd ::Integer->Integer->Integer
gcd a 0= a
gcd a b = gcd b $ rem a b

This way we move the responsibility of handling the errors to the user. This is not really a solution, the problem is just moved outside the scope of your work. Unfortunately this is still the most commonly used ‘solution’.

Closely related to this solution, but already much better, is to annotate gcd with some Liquid Haskell annotations to ensure that the arguments are in the correct subset of Integer. This is still not a solution for users that don’t use Liquid Haskell, nor is its use (and thus the safety) enforced.

A second option is to write correct code to define a partial function:

My studies are slowly reaching their end and I’m having more and more experiences with recruiters. Companies as well as universities make applicants jump through so many hoops that they seem to forget that they are being selected as well.

I get to see both sides of the story because someone close to me is in recruiting. Let me first say that there are many more bad candidates than there are bad recruiters. I just hope that recruiters make an effort not to treat every candidate as a bad candidate. Treat a candidate with the same professional respect with which you would treat a coworker. They may just become one.

I have fairly high standards, both for myself and of my work. My workplace is important to me. I will be representing it and investing in it. I therefore respectfully reserve the right to reject any company that I’ve applied to based on our interactions during the selection process. In the same way I respect that companies retain high standards with respect to their candidates.

Make sure you know what you’re doing

Recruitment is not at all something you should be doing without the proper training. Unfortunately, many recruiters are not educated to be a recruiter.

To be a recruiter, more is required than just knowing how you find candidates. You need insight in the human psychology and the valuable skill of communication.

As a recruiter, you are the first person an outsider will be in contact with. For the duration of the selection of the candidate, whether it should be successful or not, you are the face of the company.

Listen to yourself

Be consistent in what you say. Don’t tell me “You can ask any remaining questions via email” and then reply to my email with “We won’t be going forward with this application. We expected these questions during the conversation.”

Write names correctly

If you can’t muster the effort to make sure you write my name correctly in an email, how do you expect me to come work for a company that hired you? I have standards too. Oh, and don’t tell me Mr van der Kechkov is a typo that should have been Mr Kerckhove.

Make sure your system works

When I go to a company’s website to apply, or to find a recruiter’s email address to email my application to, I expect that your website works. Of course websites go down every now and then, but this particular site was offline for weeks. I’m looking at you, NASA. Needless to say, I won’t be applying to work, as a software engineer, for a company that fails to keep its website online.

Keep to your own deadlines

This goes back to my opinion on appointments. If you tell me that you’ll have an answer by Monday, take responsibility for that appointment. Don’t send me an email the next Friday. The least you could do is write me an email saying you don’t have an answer yet. Don’t expect me to be waiting for your email desperately.

Don’t make candidates do pointless mechanical work just to filter out the motivated ones

The initial part of most applications consist of three parts:

Upload your CV

Upload a motivation letter

Fill in a few hundred text boxes with the information that was on your CV anyway.

There are two problems here.

If you expect me to spend hours on my CV and a motivation letter, you had better spend more than seven seconds looking at them. The good candidates, the ones you want to hire, have a better sense of time management than to spend hours filling out your application form.

The same holds for all the informational text boxes. I get that you want to filter out all the people who aren’t motivated enough to do these menial tasks. Unfortunately you’re also filtering out the people that aren’t desperate enough because they have other options.

After having built a working system that I could use, Now I wanted the Super User Spark to be extremely safe and correct. Types had already helped me a lot. Now I turned to testing, rigorous testing.

Hspec

For the testing framework, I chose hspec. Hspec allows for integration with Quickcheck and HUnit and has you write a friendly DSL to define the tests.

Small-scale testing

Unit tests

When I first tried to implement tests for my code, I noticed that most of the code wasn’t very test-friendly. I used a unwieldy monad transformer stack and hardly any code kept out of IO. Piece by piece, I refactored out as much pure code as I could and started to write some unit tests.

eol
succeeds for a line feed
succeeds for carriage return
succeeds for a CRLF
fails for the empty string
fails for spaces
fails for tabs
fails for linespace

describe "eol"$do
it "succeeds for a line feed"$do
shouldSucceed eol "\n"
it "succeeds for a carriage return"$do
shouldSucceed eol "\r"
it "succeeds for a CRLF"$do
shouldSucceed eol "\r\n"
it "fails for the empty string"$do
shouldFail eol ""...

Property tests

I started with parser tests and I quickly noticed that writing unit tests for parsers is incredibly boring, especially for combinations of parsers. Property tests offered a nice shortcut. Now I could test the linespace parser for an arbitrary number of spaces and tabs instead of just the few unit test cases I would write.

linespace
succeeds for spaces
succeeds for tabs
succeeds for mixtures of spaces and tabs

Tests for impure functions

The most important part of spark is of course the deployer. In other words: the part that does something. These are arguably the most important parts to test.

I’d rather not test impure functions at all, but because I do have to, I refactored the impure code to pure code that outputs instructions for what to do when IO is available. Then I could test the side effects on a per-instruction basis. For example, here are some snippets from the refactored code:

Regression tests

I found quite a few bugs while testing spark. I added a regression test for all the bugs I found. Some of these look somewhat funny if you don’t know their story.

Somewhere in the deployment process, directories and their files needed to be hashed recursively. I naively implemented this with lazy ByteStrings. As a result, I got this error:

resource exhausted (Too many open files)

Apparently the implementation of lazy ByteString keeps files open until the contents are used. After I replaced the lazy ByteString implementation with strict ByteStrings, all was well. Now there is a test that gives you the following output:

hashFilePath
has no problem with hashing a directory of 20000 files

Automatic black-box tests

To lower the bar of entry for people who’ve found a problem and would like to contribute, I implemented some automatic black-box tests.

Binary black-box tests

For the parser and the compiler, there are some binary tests. These tests pass or fail based on whether the parser/compiler succeeds or fails. They only require you to add a source file to the appropriate directory.

Moving away from Taskwarrior

To my surprise, I didn’t move away from Taskwarrior because I was making things too complicated. I moved away from Taskwarrior because I wanted everything productivity-related in one place. Org mode handles tracking progress/history on and keeping notes for projects much better than Taskwarrior does. That is, if you use Taskwarrior the naive way.

Of course I missed the fact that Taskwarrior is much more easily programatically controlled as I was trying to automate.

Bad practices

As it turns out, removing a lot of bad practices from my workflow made it much easier to go back to Taskwarrior.

Too much stuff

Part of GTD is to keep everything safe in you system, so you can trust the system. I was keeping all notes on a project in a single file project.org. There was no distinction between the tasks of the project I was committed to doing at the moment and the tasks I wanted to do eventually. For regular projects this doesn’t make sense at all, but for software projects this is the natural way to do it.

Waiting

The next problem was that event hough I had a way to construct a waiting-for list, I neglected to keep it up to date. None of the items on the list reminded me of the list enough to check them off once the waiting was over. The items on the waiting-for list were distributed across multiple project.org files. I would have to manually go over the waiting-for list every week to keep it up to date. This made I/O bound projects unmanageable.

Moving back to Taskwarrior

Someday-maybe and Notes

To move back so Taskwarrior, I realized I was going to need to keep my notes per project. For starters, I wrote this tiny zsh script:

Now I can type n project to bring up the notes for any project. This way I can keep notes on every project and still use Taskwarrior.

The most important change is that now I only keep my actions on taskwarrior and keep all the someday-maybe actions for a specific project in the project.org file. Keeping the amount of tasks in Taskwarrior small is essential to being able to manage them. It’s good to keep every (eventual) task in the system, but put them in the someday-maybe list, not in your regular task list.

Automatically up to date projects

Now I could take advantage of the fact that taskwarrior can be accessed programatically. Here is a little script that tells me what projects have no +next or +waiting action.

Programming has been inspired by mathematics ever since the concept was discovered. In this post I propose some math notation inspired by functional programming.

Mathematical notation has the useful and complex property that it is only ever read by humans. Humans that are generally good at accurately guessing what the author meant without the need to parse or compile the expression.

Because computers generally don’t have this ability, programmers have to be extra clear about what exactly they mean. As a result, higher order functions have become much more common in functional programming than in mathematics.

I propose to bring these common higher order functions to mathematics to ease the human ‘parsing’ effort that is required when reading mathematical notation.

Map

First off, the map :: (a -> b) -> Set a -> Set b function for sets. In mathematical notation, we often find set comprehension of the following pattern

\[\{ f(a) \mid a \in A \}\]

In words: the element-wise applications of a function \(f:\ A \subseteq dom(f) \rightarrow B\) to a set \(A\).

I propose the following notation:

\[\overset{f}{\Box}A \quad\equiv\quad \{ f(a) \mid a \in A \}\]

It should be pronounced as “\(f\), mapped over \(A\)”, “map \(f\) over \(A\)”, or “\(A\), under the element-wise application of \(f\)”.

A direct consequence of this notation is that we can write subsequent element-wise applications of functions as follows:

In the spring semester of 2016, I will be a teaching assistant in the functional programming course at ETH, Zürich. In preparation I have been teaching Haskell to a good friend of mine. He’s a mathematician. I looked forward to both my first experience teaching and to seeing how a mathematician would learn a functional programming language.

Note that he knows about programming. He has programmed in Java and C++, but paradigms other than object-oriented programming were entirely new to him.

Category theory

You would think that the most logical starting point would be to teach him category theory. Seeing as he wasn’t already familiar with category theory, I opted not to do this. Instead, I started by introducing to the concept of types. Just like for most other people starting out with Haskell, there was no need to start with category theory.

Abstract concepts

Introducing types on an abstract level made us aware of the fact that values in Haskell be can only of a single type at the same time. This is great from an implementational point of view, but abstractly not really necessary from a mathematical point of view.

After a week long discussion and a blogpost, he finally acknowledged the existence (and usefulness) of partial functions. After that, most abstract concepts were very easy for him to understand: values, types, functions, immutability.

Typical concepts from mathematics weren’t new to him and didn’t require any more explanation: function composition, associativity, monoids, … I was even able to explain the concept of currying to him in a single sentence: “The -> operator is right-associative.”.

Easy concepts

Some concepts don’t exactly appear directly in mathematics but were still easy for him to understand.

Lists are a simple concept, they are like sets but ordered and without the requirement of unique elements. Type-classes with their laws are a little bit like algebraic structures with their axioms. ‘An instantiation for a type class is then just an explanation as to why a type can belong to a certain algebraic concept’, as he so eloquently puts it.

Strangely difficult concepts

Some concepts were easy for him, other concept were strangely harder. These concepts are rather easier for non-mathematician programmers than they were for him.

Lists also don’t require an inherent equivalence relation defined on the elements. Because sets have the inherent requirement of their elements to be unique, the elements have to have an equivalence relation defined on them. Lists don’t have this requirement and can therefore contain elements without there needing to be such an equivalence relation defined on them. As a consequence, mathematicians sometimes can’t imagine that you would ever need to think about element without being able to assume that an equality is readily available. Simpler put: There’s no Eq in mathematics, so he sometimes looks at functions a -> b as Eq a, Eq b => a -> b.

The fact that 5 and Just 5 are of different types was strange to him. In pure mathematics, 5 is both an element of the set of integers \(\mathbb{N}\) and of \(\mathbb{N} \cup \text{Nothing}\). Note that c++ also has you believe that 5 and optional(5) are equal due to the fact that their assignment operator are used in the same way.

Monads weren’t as notoriously difficult to him as they are to regular programmers, he picked up an intuition fairly quickly. The do notation, however, was strangely bizarre to him. The fact that do a ; b is syntactic sugar for a >>= \_ -> b seemed arbitrary.

Total functions

To get him familiar with working with monads and the do-notation, I had him implement a small expression evaluator. (Something that turns "5+7" into 12.) In less than an hour, he put together a badly-named function doEverything :: String -> Int. As you can see from the type, this was not a total function.

It was strangely difficult to explain to him why it was important to make this a total function doEverything' :: String -> Maybe Int. It became even harder once he noticed how much more complicated it would make his code. At first, that is. Once he’d implemented doEverything' to be a total function using a lot of case ... of expressions, we refactored the entire thing. First we changed most case ... of expressions to use >>= and lambda expressions. This was by far the hardest part in the learning process. Finally we rewrote the entire thing again, this time with the do notation, using Maybe as the Monad it is.

Thank you

A big thanks goes out to my math-friend who I will not name for privacy reasons: Thank you for giving my first ever teaching experience and for patiently sticking with me through some of the initial struggles.

Few decisions in my recent past have been as controversial as the decision not to go the most classes at university. This post describes my personal reasoning behind this decision.

Note that these arguments concern university classes for mathematics and computer science courses.

An entirely outdated system

One person standing in front of a class of 25-300 people speaking on a subject they have more expertise in. That concept is hundreds of years old and it has barely changed.

The concept of one-to-many teaching is massively outdated. Not to mention that getting information from just that one source is an anti-pattern. The education system is in dire need for an update.

The right pace

This configuration of teaching has the inherent problem that the teacher can only be at the right pace for at most one student, assuming that everyone learns at a different rate. This means that I am usually either bored in class or hopelessly lost, but rarely following along.

The university problem

No-one has ever really explained the intended function of a university to me.

I’ve gotten as far as this: To provide higher education, experts in their field are required to explain what only they know well enough.

In recent years the work pressure for these professors has increased massively. As a result, a lot of professors don’t have time to, or don’t like to teach.

I’ve been in classes where the professor was just reading the slides and ignoring every student. I’ve been in classes where the professor quit teaching after half of the class, running out as if from a fire. These were bad, but the worst part is that most professors don’t seem to make any effort to improve their didactic skills.

As a result, classes are generally of bad didactic quality.

Maybe you’ll miss something important!

No. No I won’t. Mathematics and computer science both have two inherent advantages.

Exams are usually graded in an objective manner. Any solution is either correct or incorrect, there is little discussion possible and no opinions are involved.

All the course material is plentifully available online.

stackoverflow, the math stack-exchange and Coursera are abundant resources of knowledge and inter-personal learning. If that wasn’t enough, for any recent subject, the best universities in the world publish all their lecture material online. This gives you plenty of sources of learning material and, in the case of recorded lectures, lets you learn at your own pace (e.g. 2x speed hamster-like sounding professors).

Conclusion

Now you know why I personally don’t attend classes. For the record: I do not intend to persuade or encourage anyone else to start skipping their classes.

Classes as they currently exist are becoming redundant. I personally predict massively distributed one-to-one (not necessarily human-to-human) learning via the internet, combined with small-scale many-to-many educational gatherings. This allows anyone to learn at their own pace from a myriad of sources while automatically encouraging better teaching.

I am currently on an Erasmus exchange, a trip I anticipated for years. I am somewhat disappointed and I want to present future generations of students with my story so that they may make an informed decision about a year abroad.

Anticipation

An Erasmus exchange had been on my mind ever since I started studying. I would get to go to another country for three to nine months and study at another university. I would get to expand my world view and meet amazing new people.

Less than a year before I’d go, I went to a information lecture where the Erasmus coordinators of my university explained the entire process. On the list of possible destinations, I looked for the best university. I figured I’d be able to get a great education for a few months, after which I’d have to go back as planned.

I intended to be a good student and not just go on the exchange to party abroad. I got my parents to agree to pay for an exchange in one of the most expensive cities in the world.

After a suspenseful nomination procedure from my university that would decide who would get to go, I got to wait some more until my application was reviewed by ETH. More than six months after I’d gotten the list of possible destinations, I finally got confirmation that I was clear to go to Zurich, Switzerland.

After spending a month in stress with a family that kindheartedly took us in, I found myself in a nice apartment by night, attending a good school by day.

The good

ETH is a better university than KU Leuven and not only on paper. Of course I cannot say anything about the research that’s being done at ETH but the university is better organized and the systems are more sane towards students.

Students have a much freer choice about which courses they take, there are more specializations and they are more varied. There are world experts teaching the courses. I even got to take a ‘Software Verification’ class from Bertrand Meyer himself!

At ETH only about one third of the applicants gets in whereas at KU Leuven everyone gets accepted automatically. Not only does this mean that the average student is more competent and thus more fun to work with in group projects, the students are generally much more motivated and accomplished.

The bad

Courses and workload

Even though ETH is a better university toward it students, I could only partially enjoy that.

One of the rules of the exchange was that every course that I took at ETH had to exist at KU Leuven as well or else I could not take it. I didn’t not know this beforehand. It defeats the entire purpose of an Erasmus exchange. All the courses that seemed interesting at ETH now weren’t available to me.

Another problem is the workload. It is hard enough to move to another country, find a place to live, get a few dozen hours of paperwork done. Then you still have to start studying. At my home university, taking 30 credits per semester is already an equivalent workload to a full-time job, but it is expected and a student tries by default. At ETH, taking 30 credits per semester is almost unheard of. Most computer science students take less than 25 credits per semester because it’s just too high a workload.

Finishing my masters degree in the expected two years requires me to take at least 30 credits on average each semester. I would have to work extraordinarily hard to get through this year just because I am on exchange.

As if that wasn’t bad enough, because I was restricted to courses that exist at my home university, I’ve had to combine courses that no sane student would try to combine in one semester. As a result, I’ve had more than 10 group projects this semester. Sleepless nights were ensured from the start.

To get the more than 30 credits that I committed to, I had to overcome a workload equivalent to almost two full-time jobs.

Hold on, because the worst is yet to come. At the start of the year I got a letter from the student exchange office. It said that if I failed to complete the courses I had set out to do, I would have to pay back my entire scholarship.

No stress…

Living costs

Now it is not as if I would have been able to party in Zürich all year long otherwise. Zürich is in the top three most expensive cities in the world (even the most expensive, depending on the source). With what we paid for an apartment in Zürich, I could have lived in a 400m² villa in Leuven instead.

“But you got a scholarship!” you may be thinking right now. That is true, but even without the strings attached, that would’ve gotten me through less than two months of rent and nothing else, instead of ten months of studying. Even with a part-time job as a teaching assistant, I could only pay for food. A big thank-you to my parents, without whom this exchange would certainly not have been possible.

The ugly

An Erasmus exchange was described as a life changing event. I was told you could study new subjects that would never by covered at my home university. They obviously weren’t acurately describing what was going to happen.

While the exchange has been amazing from a personal perspective, it has been no better than staying at home from an academic perspective.

Conclusion

If you were planning to go on an Erasmus exchange, I hope you consider that maybe you haven’t been told everything. If you would like to study abroad, go and study abroad, but don’t go on an Erasmus exchange.

If you really want to go on an Erasmus exchange, don’t go to study. Find a nice, cheap, warm country with a university where you can pass courses easily without much work and take a year off, partying at the beach.

I’ve recently been teaching Haskell to a mathematician who’s interested in programming. He never fails to impress me with how easy it is for him. More interestingly, as similar as I find Haskell to be to mathematics, he shows me the differences.

It’s one of those differences that I would like to discuss in this post.

Sets

To properly set this discussion up (pun intended), I first have to go back to sets for a moment.

As sets are defined to contain only unique elements, never the same element twice, there must exist an intrinsic equivalence defined on its elements. For any two elements of any set, they must be comparable for equality.

In Haskell, there is the Eq typeclass that contains all types whose values are comparable for equality. Interestingly enough, not all types are in this typeclass.

Functions

In mathematics, a function is defined to consist of a codomain, a corange and a one-valued relation. Equality is defined to hold when all three of these parts of two functions are respectively equal. That means that any two functions can be compared for equality.

Most notably, in Haskell, functions are not in the Eq typeclass (in general). Not any two functions can be compared for equality in Haskell.

This got me thinking. If Haskell is so similar to mathematics, what causes this discrepancy?

I’m ignoring \(\bot\) for the sake of simplicity. \(\bot\) causes some obvious problems but they are not the focus of this post. I’m also ignoring side-effects like IO functions. The focus is really on functions that also exist in pure mathematics.

We assume that there is a mapping \(\phi\) from Haskell functions to mathematical functions. The objective of this post is to discuss how we could, given two Haskell functions \(f\) and \(g\), check whether \(\phi(f)\) equals \(\phi(g)\).

Instantiating Eq for functions

While it is not generally possible to instantiate Eq for functions, there are some things we can do.

For example. Functions with a boolean corange and a codomain that instantiates Eq could have an Eq instance as follows:

There isn’t anything special about Bool, of course. In theory we could do this for any function with a finite corange, right? Any Bounded corange should do. Well, the idea here is to compare the output of the functions for every possible input. To construct every possible input, that is construct every value in the type of the input, it has to be enumerable (Enum) too.

It is easy to see that this approach is only feasible for very small input types like Void, (), Bool, Ordering, Char, etc…

Other failed attempts

My friend also suggested some other approaches that, he thought, would also work on functions with big coranges.

Comparing ‘references’ to the functions: This doesn’t work for identical functions that are in different places in memory.

Analytical solutions: This may work nicely for continuous numerical functions that have a nice definition and aren’t just bags of random tuples, but it doesn’t work in general and it’s not at all trivial to implement.

The actual problem

For infinite functions there is no way to compare them for equality using a computer. Computability theory explains why.

For any non-trivial property of partial functions, there is no general and effective method to decide whether a Turing machine computes a partial function with that property. - Rice’s theorem

The formal proof involves showing that a method that can compare any two functions for equality can be used to build a method that decides whether any Turing machine will halt. Given that the Halting problem is undecidable, we know this is not possible with our computers that are equal to Turing machines in terms of theoretical computing power.

Conclusion

If you ever want to compare functions for equality, consider what information you’re actually looking for. In reality you will most likely only be interested in the output of a function for a select few inputs.

Applications

A description of the computer system you will be using. (1. Operating system, 2. whether it’s a phone, a laptop or a desktop, 3. whether it’s yours personally)

These pieces of information are only for me to better tailor the way I explain the material to the student. There is no requirement to have any background in either maths or computing. We can work from the ground up if need be. I happen to also like to teach maths.

I do not need to know:

Who you are.

Your race.

Your gender.

Your veteran status.

Make sure the subject of your email is [Programming Student Application]: your name here

The idea for this project came to me when I published my second project suggestion on this website. Most programmers have a lot more ideas than they can ever work on.

“The best way to have a good idea is to have lots of ideas.” ― Linus Pauling

Moreover, it is hard to find out whether a given idea is worth working on.

What if we had a way to share these ideas and figure out whether they were worth working on?

The idea

The idea is to build a web platform where programmers can share their project ideas and find other people to work on the projects together.

There would only have to be two buttons on every idea. One that says ‘I would like to work on this project’ that would take you to an application page and one that says ‘This project would have a positive impact on my life’. Maybe a ‘WTF were you thinking’ button could also come in handy.

Programmers could share their ideas for anyone to work on, they could find other developers to work with and they could find out whether their idea is worth working on.

Ideas could be entirely new systems, extensions or improvement to existing systems but they would have to be open-source projects.

Requirements

OSPIP has to be free and open-source.

This is all about free and open-source software. The platform would have to communicate very clearly that, in sharing your ideas, you would give others the permission to act upon them as well. A legal-person go over the details of the ‘ownership’ of ideas before this platform could be built.

The focus has to be on making good ideas a reality, rather than making money off them.

Suggestions

I am a big Haskell fan, so I would suggest yesod or something similar, but there are far more experienced web-developers out there that I would gladly take advice from.

I’ve been thinking about how to determine what it is I should be doing at any given moment. As Julia Evans puts it:

I’d rather spend time figuring out which work is important than do something that doesn’t matter.

Now, I haven’t found a solution. I don’t even think even close to one, but I have recently been in a situation where it was clear how I could figure out what I should have been doing.

An uncomfortable situation

On Monday 2015-12-14 I had my first exam at ETH: Software verification. I hadn’t taken a lot of time to study for this course and the exam was before the holiday rather than after. I had three days to make sure I wouldn’t fail this exam. Note that if I failed my exams I would have to pay back my scholarship so the pressure was on!

Figuring out what was important

I knew I wouldn’t have time to study all the material the way I would like to have so I had to optimize for time. I was looking for a way to figure out what exactly I should be focusing on. I started by looking at the previous exams that the Professor had published.

Under the assumption that exams are usually similar to last year’s exam, this gave me an indication of which topics would be important. ‘Code reuse’, for example, seemed like something I could skip on first reading. ‘Axiomatic semantics’ looked like it was important enough to definitely study.

Then I noticed that the exams also mentioned how much each question would be graded for. That could give me a quantitative indication of importance!

Now, this is a good indication, but older exams shine through way too much. Obviously, neither ‘Code reuse’ nor ‘Component design and testing’ would be on the exam.

I started by giving older exams a linearly decreasing importance assumption per year. I also tried giving older exams an exponentially decreasing importance assumption per year. Here are the results: (Rounded down to integers.)

This looked like a better indication. The bottom three topics are not indicated as relevant and ‘Separation Logic’ was deemed more important by the results on the right because last year it was more important than ‘Axiomatic Semantics’. The results on the right are the ones I trusted in the end.

I studied for three days focusing, in that order, on ‘Separation Logic’, ‘Axiomatic Semantics’, ‘Model checking’, ‘Software Model Checking’ and ‘Data Flow Analysis’ and went to the exam on Monday.

Reflection

Notice that I all the judgments of ‘better indications’ are entirely intuitive. In hindsight I should have tried to predict the grades for last exam and judged my models based on the result there. To be fair, I would have made the same decision in that situation, but it would have been more scientific.

This entire endeavor only started because of an unlucky situation. I fully realize that it was risky and that it would have been better to have studied the entire course.

The results

I did well on the exam. My grade was excellent but it’s not really relevant here.

Let’s have a look at which topics were covered on the exam and how the grades were distributed:

To give you some objective numbers, the models had RMSE’s of \(6.49\), \(5.45\) and \(4.47\) respectively. These statistics are nice of course, but most importantly, only the topics I focused on were on the exam and I only focused on those.

I needed some graph visualizations for the chapter on logic and computability in The notes and I really didn’t want to write about 20 pieces of repetitively constructed Graphviz code. Less than one week later, Haphviz allowed me to generate those graphs with only a few lines of Haskell code.

Disclaimer: This post assumes that you know how Graphviz’ Dot language works. It is written at the time of Haphviz 0.1.4.

Demonstration

Divisors

Ever since I’ve learned about lattices, I’ve wanted to generate a Hasse diagram of natural numbers with ‘divides’ as the partial order. Of course it’s impossible to generate an infinite diagram but I would settle for a parametric arbitrarily big diagram.

We’ll generate a node in the graph for every natural number starting from \(1\). Now, as far as the maths go, there should be an edge between two nodes labeled \(a\) and \(b\) if \(a\) is divisible by \(b\) and there doesn’t exist a node labeled \(c\) that has edges from \(a\) and to \(b\).

As the math is not the focus of this post, let’s see how you would generate code to visualize this graph with Haphviz.

Here the primary :: Integer -> Integer -> Bool function determines wether there should be an edge between two nodes. That wasn’t so hard, was it? Running dot on the generate graphiz code with n = 10 yields the following image.

Divisors graph

Finite state automata.

Having a Turing-complete encoding system for graph visualization means that we can simplify the process of visualizing graphs with a predictable structure.

Haphviz has a module Text.Dot.FSA with a single function fsaGraph that allows you to easily generate graphs for finite state automata.

The following code generates Graphviz code for a simple finite state automaton.

Design

The design of the internals of this library is based on the design of HaTeX internals. A single data type Dot represents the contents of a graph. Generating graphs by generating a Dot structure is certainly possible but it is a tad tedious.

The DotGen monad allows you to generate graphs in a simpler way. Now you only have to declare how you want to the graph to look and let the combinators take care of constructing a Dot graph.

Further work

Further extensions of this libraries are certainly possible. Here are some of such extensions I propose. Feel free to have a go at implementing them if you need them.

More predictable graph generation

As far as predictable graph generation goes, there is, at the time of writing, only support for finite state automata visualization in Haphviz For The notes, I made a similar piece of code that allowed me to generate Store-Heap model visualizations.

In future work on this library, code could be written to make visualizations of other predictable graphs easier:

A Graph type class

Data.Tree is just one example of a data type that could be represented as a tree. Others may well be visualizable too.

I propose a type class Graph a with a single function graph :: a -> DotGen () that generates its visualization.

A DotGen Monad transformer

DotGen is just a monad. It’s currently not possible to do IO while generating a graph.

Writing a DotGenT m monad transformer would allow you to compose the graph generation monad with other monads like IO. This would be fairly trivial as DotGen is already a type synonym for StateT State (WriterT Dot Identity).

After building a web scraper for a university project, I decided I would build my own little web scraper for the single purpose of finding as many email addresses as possible. Eventually I could then send a message to each one of them, explaining that their email address was publicly visible a given url and how they should probably obfuscate it. I didn’t quite get to the second part but I certainly found a whole bunch of email addresses.

The crawler pipeline

As it turns out, a crawler resembles a pipeline quite well. This immediately made me consider the pipes library.

Because there are loops in the pipeline, using vanilla pipes would not suffice. Luckily pipes-concurrency was well-equipped for this use-case.

pipes-concurrency makes use of thread-safe buffers to share data between pipelines. This allows for the architecture with loops as well as multiple concurrent fetchers.

This looks like a nice architecture in theory, but how well does it translate to actual code? Think about it, how would you implement this in an imperative, object oriented language?

In Haskell, the pipes library takes care of the hard work. Once you’ve written the pipes, you can just stitch them together with >-> and have the library do all the work.

Inside a fetcher

The only thing a fetcher needs to take care of is transforming a URL into a (URL, Content) pair, possibly using IO.

Internally, the fetcher is made out of a bunch more pipes. Each of them taking care of a small part of the pipeline. Because finding email-addresses is all about recall and not as much about precision, we can just discard anything that presents a problem.

requestBuilder takes a URL and produces a (URL, Request) pair and passes it on.

prefetchRequester and fetchRequester both fetch the page, the former using a HEAD request and the latter using a GET request. They take a (URL, Request) pair, produce a (URL, Response) pair and pass it on.

headerFilter throws away any (URL, Response) where the content type isn’t text. This ensures that we don’t look through binary data for email addresses.

contentExtractor just takes a (URL, Response) pair and emits a (Url, Content) pair.

As you can imagine, this makes for very easily composable code.

Memory footprint

A crawler has an inherent memory problem. Because there is generally more than one link on a web-page, keeping track of all found links in a queue will make for an exponential memory footprint with respect to runtime. This cannot be solved without throwing away links.

HESS also suffers from this exponential memory problem. It keeps all found links in memory and has to be killed after a certain amount of time as a result.

More intelligent fetching

The URLs that are found on a page are put in a simple queue. No effort has been put into making sure that this queue is emptied in a sensible manner.

In a possible future extension, the URL queue could be stored in a database and the fetchers could then ask for batches of URLs from a controller to this database. The controller could then make sure that the same domain isn’t crawled too often and maybe even keep track of which domains are better to find email-addresses on. This would also be a better way to handle the memory problem than just keeping the queue in memory naively.

Weird addresses

RFC 2822 concisely describes what constitutes a valid email address, but not all valid email addresses according to this standard are real email-addresses. Images like github-logo@1200x1200.png are often found to be email addresses.

HESS could be extended with the (expensive) intention to also try and verify whether an email address is real. It is not provable that an email address is real. What does ‘real’ even mean here? We can find evidence however. Possible pieces of evidence include:

Of course these tactics have been used by spammers in the past, and will therefore probably end up having some less-exciting consequences like getting your IP-address banned from the SMTP servers.

Counteracting obfuscation

No effort has been made to counteract email address obfuscation. Because of the pipes architecture, it would be really easy to modularly add different ways to counteract specific obfuscations.

Some of these un-obfuscation techniques could be very expensive and are therefore probably not worth it. How would you un-obfuscate address<span style="display:none">muhaha</span>@example.com ? Lucky obfuscater!

Still, it could be interesting to try it out.

Results

The results depend a lot on the seed URL, of course. For generic seeds, I got up to one thousand possible email-addresses per minute. For really good seeds, that shot up to six thousand.

I invite you to replicate these results.

Conclusion

There are still a lot of unsolved problems in this area. I only spent a relatively short amount of time on this project and don’t really intend to spend any more. It was fun, but I really don’t have any use for a hard drive full of email-addresses.

Looking at developer’s tool and having written some myself, I noticed that developers often seem to struggle with the design of the configuration of their tool. In this post I would like to summarize some design considerations, as well as give examples of good and bad configuration design.

The need for configuration

Configuration, /kənˌfɪɡəˈreɪʃ(ə)n,-ɡjʊ-/: an arrangement of parts or elements in a particular form, figure, or combination.

Configuration is generally used to accomplish at least these three goals:

Generalized implementations (for maintainability)

Code often contains fixed numbers and default values for certain parameters. Making the implementation general with respect to these values makes for healthier and easier to maintain code. A constant like MAX_ITER = 5 is an example of such a configuration.

Personal Customization

The workings of a tool are often customizable for a given user. This allows individual users to make the most out of the tool and the programmer to leave decisions about those configurations to the user. Changing the color of output is an example of such a configuration.

Different outcome

Sometimes tools need to work differently in different scenarios and it’s not always possible for them to figure out how on their own. That’s when outcomes should be configurable by the user. A --force flag is an example of a different outcome achieved by manual configuration.

Design decisions

Configurations design can take at least three forms: constants in code, command-line flags and configuration files. These forms don’t generally each correspond with one of the above goals, but the goal of a configuration can definitely give an indication as to which for to use.

Configurability is generally desirable. Be sure to err on the side of Configurability. When in doubt, make it configurable, either with a configuration file or a flag.

Constants

Replace all ‘magic’ numbers with constants that describe their use. This will help you to better understand the semantics of those magic numbers. For example; 1 doesn’t mean the same thing everywhere. Sometimes it’s the LARGEST_BINARY_DIGIT but other times it is the UNARY_BASE or the MULTIPLICATIVE_IDENTITY.

Wherever possible, use constants defined by library.

Time libraries often export constants that involve time. Use those instead of defining SECONDS_IN_AN_HOUR yourself.

Don’t define a constant if it’s not really a constant.

Use a flag instead if it’s not really a constant. Example: DECIMAL_BASE = 10 is a good constant but NB_RETRIES = 3 is not. Use a --nb-retries flag for the latter.

Don’t make real constants configurable.

Example: Don’t make a --decimal-base=INT option. This will only confuse users and is of no value.

Don’t use a constant if its name would only refer back to the formula.

Example: discriminant = b ^ 2 - 4 * a * c is acceptable as is, as long as you make a comment about it. There is no need to change it to D = b ^ EXPONENT_OF_B_IN_DISCRIMINANT_FORMULA - FACTOR_OF_SECOND_TERM_IN_DISCRIMINANT_FORMULA * a * c.

Command-line flags

Use the right format for command-line configuration.

Use words or their substrings for commands.

Use a single dash - for short (one character options).

Use a double dash -- for long options. Use kebab case names that look-like-this for long options.

Don’t put commands in flags.

Commands change the fundamental use of your tool while flags should only change configuration. The line here is blurry, and will require the programmer’s judgment, but the way gpg does it is definitely a bad example.

This has exactly two exceptions. --help should only display usage information and --version should only output the version number.

Don’t use short flags if they’re not obvious.

Example: -f for --force and -i for --interactive are okay, but -l is not a good abbreviation of --files-with-matches (grep).

Configuration files

Make configuration -files human-readable.

Configuration files are for external consumption. Making configuration files manually editable is essential to a good user experience.

A configuration file that is only editable via the program is not a configuration file but a data file, even if it is used to configure the program. This does not mean that configuration files must not be modifiable internally, for example with a GUI.

Make sure configuration files are modularizable.

This means they must support recursive includes of both relative and absolute files.

DRY is a powerful concept that is entirely negated if configuration files are not modularizable. Copying parts of configuration files makes for a very bad user experience.

Be considerate when deciding where to put your configuration file.

The program has to make assumptions about where to go looking for the configuration file. By default you don’t want to make the user specify the location of the configuration file, so make sure to have a sensible default.

Make the location of your configuration file configurable with a flag.

This is essential for users that have more than one configuration file for different occasions. Having to move configuration files around to use different one makes for a very bad user experience.

Have the program look for the configuration file in more than one place.

Having a sensible default for the location of the configuration file is one thing. If the program has got something to do with files in specific locations, having it for a configuration file recursively upwards in the directory tree can make for a nice user experience. See Stylish Haskell for an example of such a case.

When possible, stick to values that could appear in a JSON object.

Don’t use custom objects that you will have to parse with a custom parser. Stick to numbers, booleans, strings, etc.

If you must define a custom format, make it a full-fledged language. See the Super User Spark for an example of such a case.

Deciding between putting a configuration in the configuration file or in a flag

There is a simple heuristic to decide whether a configuration should be put in the configuration file or in its own flag: “Frequency of configuration”. How many times does the user have to manually configure this?

If the user is deploying the program as a system, use a flag. The configuration will most likely be saved in a startup script any way.

If the user uses the command-line manually to interact with the system, put the configuration in the configuration file. Having to retype a --really-long-command-line-option often makes for a very bad user experience.

Preliminary notes

Note firstly that \(A\) and \(B\) are included in the definition of a function \(f:\ A \rightarrow B\). This also means that the equality of two functions is defined as conjunction of equalities between the respective \(A\)’s, \(B\)’s and \(f\)’s.

Note also that the domain of a function \(f:\ A \rightarrow B\) is equal to \(A\) while the range of that function is not equal to \(B\).

Lastly, because \(B\) is not equal to the range of the function, \(B\) can be an arbitrary superset of the range. There is no connection whatsoever between \(B\) and the set of tuples \(f\).

This codomain \(B\) is only used to define things like surjectivity or in theorems like, for example, the isomorphism theorems.

Problems with this definition

That was a lot of theory that any mathematician should have known by heart for years.

Ugly

The first problem with this definition is that it’s ugly. The sets \(A\) and \(B\) are baked into the definition of a function while \(f\) could just be a single-valued set of tuples! The domain and range definitions would stay the same because they are inherent to \(f\) and can be defined irrespective of \(A\) and \(B\).

No partial functions

The second problem is that it doesn’t allow for non-total functions.

Most mathematicians often have the luxury to only have to think about total functions. Ironically, people like information theorists and computer scientists often use the more abstract notion of partial functions.

To remind you, partial functions are functions where there isn’t necessarily an output defined for every input. I would say \(A\) is not equal to \(dom(f)\) if the above definition hadn’t disallowed that!

In the above definition of functions, there is no way to define non-total functions and that limits our thinking. Powerful mathematical concepts like Turing-machines can’t be defined unless we allow for the more abstract notion of partial functions.

Asymmetric

Now, suppose you really want to define a codomain each time, then there is a third problem. The definition is now asymmetric:

\[ f:\ dom(f) \rightarrow img(f) \subseteq B \]

I hope it’s obvious that there is something missing here. Much nicer would be the following:

\[ f:\ dom(f) \subseteq A \rightarrow img(f) \subseteq B \]

We can’t do this, however, because the above definition of a function dictates that \(A\) must equal \(dom(f)\).

A new definition

Now clear your mind and have a look at this new and improved definition:

Let \(A\) and \(B\) be sets and \(f\) a set of tuples of elements respectively in \(A\) and \(B\). \(f:\ A \rightarrow B\) is a function if \(f\) is single-valued:

Advantages

\(f\) could (possibly) be defined independent of a corange and codomain, though that would still require another definition of equality. This definition is not as ugly as the last one.

Because the corange \(A\) is now different from the domain of \(f\): \(dom(f) \subseteq A\), \(f\) is no longer necessarily total. This means that a function can now be partial and still be a function. This is precisely the case when \(dom(f)\) is a strict subset of \(A\).

The definition of a function is now symmetric:

\[ f:\ dom(f) \subseteq A \rightarrow img(f) \subseteq B \]

… and as an added bonus, this new way of defining functions requires you to acknowledge the existence of partial functions.

Feedback

While suggesting this idea to mathematicians, I have often been figuratively pelted by vegetables. However, they’ve never been able to tell me why it was that they couldn’t be open to other definitions. After all, there is no such thing as a true definition.

I hope that, if there are any other mathematicians that feel deeply and personally offended by this, they will be able to explain to me what is mathematically (!) wrong with this new definition. As of yet, I have not been able to find any flaws.

I’ve recently managed to muster up the courage to try out template Haskell when I noticed I was writing boiler-plate code. As it turns out, Template Haskell is really cool.

I’m translating my notes to English and rewriting them at the same time. This time I’m not using plain LaTeX but rather the Haskell library HaTeX. It allows me to write code in Haskell that generates the appropriate LaTeX code for the book. (Don’t face-palm just yet.)

Boiler-plate Haskell (?!)

Haskell is not known for being very verbose but I noticed I was writing the same code over and over again.

For any term I define, there are five functions. In the case of the definitions for a mathematical relation, these are:

relation': emphasized (bold) and indexed version

relation: indexed (but not emphasized)

relation_: indexed with reference to the definition in a footnote

relationDefinitionLabel: Label for the definition of a relation (required for referencing)

In case you’re interested, this Haskell code produces the following LaTeX code. As you can see, the haskell code is currently a lot longer because of the boiler plate functions: relation', relation, relation_, relationDefinitionLabel, and relationDefinition.

Fixing it with Template Haskell

What if I told you Haskell could generate Haskell code during compilation and use it immediately after. That’s exactly what Template Haskell is for!

Don’t confuse the ‘template’ in ‘Template Haskell’ with the ‘template’ in ‘C++ templates’. C++ templates are nothing like Template Haskell’. Template haskell is more like advanced in-AST macro’s in Haskell. Instead of macro-ing text with a macro-language that then gets parsed into an AST, you macro the AST itself in Haskell!

I won’t go into the nitty gritty details of how exactly you implement the generation of this code, but the high level concept looks as follows.

You define a list of Decs (Declarations) in the Q monad and then you can just put that function at the top of a Haskell file to put the generated Haskell code in there with the rest of the code.

For example, getting the hostname of the machine that compiled the code would be impossible without a compile-time reference. You could use template-haskell for this. For example, you could define a function host :: Q [Dec] that generates code for hostname = "<compiling-machines-hostname>" at compile-time. Then you would only have to add host at the top of your module and the rest of the code will have hostname at its disposal. (Make sure to add {-# LANGUAGE TemplateHaskell #-} at the top of that module and define host in a module other than the one where you want to use it.)

This probably looks like magic to someone unfamiliar with Template Haskell (I know it did to me!) If you would like to learn more, I suggest you try it out yourself and have a look at the excellent Template Haskell documentation. Don’t be scared of all the constructors. They will make sense once you understand what the abbreviations stand for.

Of course if I don’t go into the details of this simple function, I won’t go into details of the function makeDefs that generates the boiler-plate code I mentioned before. You can find the full code in the notes repository.

Suffice it to say that I no longer write this boiler-plate code. I now just write makeDefs ["relation"] at the top of the module and the boiler-plate relation', relation, relation_ and relationDefinitionLabel is just generated for me at compile-time.

Reflection

Template Haskell is amazing, but other than the inherent geekyness of generating Haskell with Haskell, are there other advantages? Absolutely, if I made a typo in relation, before it would have shown up somewhere inconsistently, now it is either consistently correct or wrong everywhere. Automatic consistency is not the only advantage. Code-size (before compile-time) is smaller and less error-prone without sacrificing any type-safety. Granted, Template Haskell can generate non-type-safe code but then that code will not compile.

While trying to engage in meaningful, insightful discussions, I have often caught myself not taking the other person seriously. I’ve been trying to pin down why this would be the case, so that I may reflect on the matter.

Keep in mind that the greatest problem with these examples is that there is no good way to figure out the real meaning of what is said. One would have to make assumptions that are detrimental to the discussion if the following points were ignored.

Before you read on, I would like to clarify that my intention is to understand what my conversation partner is saying. I am genuinely interested and my intentions are friendly. It is precisely not my intention to be purposefully annoying.

Here is a list of ways to not be taken seriously.

Use meaningless words/buzzwords.

After the post about definitions, it quickly became clear to me how few words have a good definition and how many words are used without them being defined at all.

Words without a definition don’t have a clear meaning. Because in discussions we try to convey ideas and information clearly, one could argue they have no useful meaning at all.

Use words with inflated semantics.

Using words generously too many times will diminish their meaning. In meaningful discussions, using words that have gone through this process can confuse your conversation partner as they cannot tell whether you are using the word in the true, original sense or in the new, meaningless sense. One then has to assume that their conversation partner is trying to use the word in the original meaning of the word and that will come with great annoyance if they are not.

Use sentences that are manifestly false.

The implication of using a sentence with a universal quantifier \(\forall\) is that one only needs to provide a single counterexample for the entire sentence to be false.

Examples of such sentences:

Everyone has two hands.

Nobody thinks that the earth is flat anymore.

It always rains on November 2!

Speak depth-first.

An argument naturally follows a tree-structure. That is why we use sections, subsections and subsubsections as we do.

The way we traverse that tree is a crucial part of transferring the information. Speaking in depth-first order is a surefire way to confuse your conversation partner.

Coming up with a good example of this point is hard because this usually only happens in speech. A good sign that this is happening is that the discussion seems to go completely off topic after a few sentences while the speaker still thinks they are explaining themselves.

Use words with a precision higher than you can support.

Again, one has to assume that their conversation partner is saying what they are on purpose. Using words that indicate a higher precision than the speaker is willing to commit to, will case the conversation partner to wrongly assume that higher precision.

Examples:

using ‘in two days’ to mean ‘soon’

using ‘90%’ to mean ‘most’

using ‘at 12:00’ to mean ‘around noon’

Use examples if you cannot word the abstract idea.

Making a convincing argument requires you to be able to express the core idea before you give any examples. Giving examples first, or only, can confuse your conversation partner because examples are rarely generally applicable enough to get the idea across. Moreover, they are usually much more easily contradicted or their point circumvented.

This situation can be recognized by hearing the equivalent of “Oh, but you know what I mean!”

Using logical quantifiers and connectives correctly is vital if you want to engage in intelligent discussions. Using them wrong makes it seem as though you are either ignorant or too emotionally unstable to concentrate on the discussion. Your conversation partner then has to correct your logical mistake, or ensure you meant something other than what you said otherwise, which distracts from the discussion at hand.

Example sentences:

“I always bring an umbrella when it rains, but it didn’t rain so I didn’t bring an umbrella.”

“All birds are not penguins.” (instead of “Not all birds are penguins.”)

Now that the Super User Spark exists to keep your dotfiles safe, the only thing you need to do is make sure that you have your dotfiles in the right directories and your spark cards are up to date.

The Super User Charger could take care of that as well.

The project I suggest is an extension of the Super User Spark that automates the rest of this dotfiles hassle. There are two aspects to this project.

Status report

The first part of the project is a new subcommand status that would allow the user to get a clear view of the current situation with respect to dotfiles.

This subcommand should be able to generate a report that describes how up to date your SUS depot is by answering these questions:

Are there any dotfiles that should (probably) be secured in a SUS depot?

Are there any files in your SUS depot that aren’t configured to be deployed in any spark card?

Detecting dotfile suspects

This subcommand would have to be able to assess whether a given file is a dotfile or not. There are a few options:

Fixed names: .bashrc is always a dotfile.

Fixed rules: If a text file starts with a dot and doesn’t end with .sw[op], it’s probably a dotfile.

Configuration: The user can configure rules for dotfile detection themselves.

These ‘guesses’ would have to be accompanied by a confidence measure.

Spark card checking

Checking whether a dotfile is configured to be deployed should be done for compiled cards, whether it’s online compilation or not. Only for compiled cards can we be absolutely sure that we can answer the question ‘Will this dotfile be deployed?’ correctly? This would however require an argument so that spark knows in which (compiled) card to look for deployments.

Automatic storage

A natural next step would be to add a subcommand charge to further increase the automation capabilities. This subcommand would get a SUS depot ready with minimal user intervention.

It should use the detect-unsecured-dotfiles feature from the previous step, secure them automatically in a dotfiles directory and generate a spark card that would deploy all of them.

Ideally the dotfiles would be secured automatically but deployed manually (by default). spark can of course never be sure whether it has detected the right files as dotfiles. It would create a dotfiles directory that is entirely ready to deploy from.

]]>Sun, 08 Nov 2015 00:00:00 UThttp://cs-syd.eu/projects/suggestions/super-user-charger.htmlTom Sydney KerckhoveGrading a small programming competitionhttp://cs-syd.eu/posts/2015-10-30-grading-a-small-programming-competition.html
[ERT: 2m26s]
This year I co-organised and co-judged the first ever programming competition at my home university in Leuven. For the sake of honesty, transparency and fairness, here is an account of how I graded the questions that I contributed to the competition. I took this entire thing as a fun little bash scripting challenge.

Let’s see how far I got.

Rules

The competitors …

… got the question in the form of a pdf file.

… got the all the input files (*.in)

… got the sample fields (sample.in and sample.out)

… had to send me an email with subject [<QUESTION>] <team name> containing their output files (*.out) and their code.

Luckily team names where distinct. Sadly there were no rules against really annoying team names. There was one team named '; DROP TABLE Participants;. Let’s just say that I ended up not liking them very much.

Collecting the data

At the moment I just have a mailbox full of submissions. They don’t even all conform to the format as laid out in the rules. They will be ignored. Too bad.

I wrote a script to get the right emails out of my mailbox and to each put them in a directory that would later house the submission files:

Note that I couldn’t write for t in $(ls -1) because of '; DROP TABLE Participants;. I had to store the teams in a file and get them out line by line to make sure that the unescaped control characters didn’t mess up the script. It took me a few tries to get this to work correctly, so I’m very glad they didn’t name their team '; rm -rf ~;!

Moving to Switzerland has made me realise that a lot of my frustrations concerning appointments have been mostly a consequence of the culture I was surrounded by. I have been in countless discussions about people being on time for their appointments. So many that I think it’s worth explaining where the frustrations came from.

I have to stress that this post is about my personal concerns with people being late in our appointments. I am trying to clearly communicate what my expectations are concerning appointments. I do this for the sake of transparency and the prevention of needless further arguments. Feel free to have your own expectations and to ignore mine entirely.

I will purposefully not go into the personal consequences of being late. How others handle their life is none of my business. Stealing my time on the other hand, that is an issue that involves me. As such I will explain why it bothers me.

A perception of tardiness

appointment (/əˈpɔɪntm(ə)nt/) noun, an arrangement to meet someone at a particular time and place.

Let’s you make an appointment to meet your friend at time X at place Y. You both take time out of your lives to be at that particular spot at that particular time.

If you are late, you are forcing your friend to spend extra time. Time that is not spent in a useful manner. Usually just waiting for you.

This is a word for this behaviour:

steal (/stiːl/) verb take (another person’s property) without permission or legal right and without intending to return it.

It is stealing. Time is the most valuable thing any of us will ever posses. (In fact one could argue it’s the only thing a person will really posses.) Stealing time is even worse than stealing money because you have a chance to recover money but you will never recover lost time.

This whole problem seems to be very culture dependent. I’m not quite sure what it depends on but it seems to be worse in some place than in others. In Switzerland it’s part of the culture to be on time. The amazing public transport is just one example. Action has been taken to ensure that people are on time. For example, classes start at quarter past the hour instead of on the hour. This helps people to be on time for class.

Quick replies

Answers to frequently discussed questions

It’s always possible that I am late due to external factors. Surely I shouldn’t be blamed for others’ mistakes? Trains could be late, busses could be canceled, etc…

Of course you could be unlucky using whatever mode of transportation you have chosen, but that does not exempt you from the responsibility of the appointment. If you aren’t willing to accept the risk of using externally gouverned transportation, you should not make the appointment in the first place. You could also just make better arrangements. Bringing external factors into consideration requires the contemplation of the risk they bring with them. Take responsibility for the risks you take and don’t blame someone else if they don’t work out. Most of these risk can be mediated by taking the earlier bus or the earlier train.

In the same way, I will take the responsibility for the risk I take by making an appointment in the first place by not arranging any more appointments.

If you know I’m going to be late 10 minutes every time we meet, why not just show up 10 minutes later?

First of all, I will not accommodate for your disrespect. If your tardiness is this bad, I will just stop arranging appointments with you. I value my own time more than an appointment with someone who shows this kind of disrespect to me. Second: If your tardiness is this predictable, why not come 10 minutes earlier and be on time?

Moreover, what you are describing here is a non-cooperative game. If you don’t come on time, that gives me an incentive to come later too. That will, in turn, give you more of an incentive to come late. This effect has been greatly studied and the result is a Nash equilibrium where no-one ever comes on time and it becomes impossible to make appointments anymore.

Basketball practice starts at 3, you are late as of 2:55 - Coach Carter

When I moved to London in June, I didn’t bring my desktop with me. I only brought my laptop instead. Both systems run Arch Linux. I moved to Zurich last month and got my desktop back last week. As it turn out, updating an Arch Linux system after three months is not without danger.

I had already backed up my data from the desktop before I left because I had a feeling that something like this would happen. When I got my desktop back, the first thing I did was let pacman update the system.

Everything seemed fine until segfaults started to show up. They showed up in my R scripts, in vlc, in evince, in xdot,…

Segmentation fault (core dumped)

I didn’t find anything in the archlinux.org news but apparently segfaults on random programs are known as the early symptoms of failing RAM. I figured failing RAM would not segfault on the same programs every time but I had no other leads.

After some googling, I found out that this may be caused by the fact that Intel microcode is no longer loaded automatically. I’m still not sure why. Apparently the only thing I had to do was rebuild my grub config to make sure that the Intel microcode would be loaded during boot.

This post describes the last two major features of the Spark language. To understand this, it is probably useful to read the previous two posts on the subject here and here.

Blocks

Up until now, all deployments came from a single directory of dotfiles.

Blocks allow you to categorise your dotfiles into different subdirectories. A block is declared between two curly brackets: { }.

card spark-card {
# This is the top-level block.
{
# This is an inner block.
}
}

Abstractly, any non-deployment declarations in a block are local to that block. If you put an outof declaration in a block, after that block it will not be in effect anymore. This is useful since into, outof and alternatives declarations compound. As such, blocks temporarily encapsulate context.

By default, spark will deploy only the first card in the file but we can also deploy others. (Note the required double quotes.)

$ spark deploy "cards.sus card2"

All into, outof and alternatives declarations are wholely reset in a new card. This makes cards fully modular.

Sparking off other cards

Using multiple cards is not only useful to seperate deployments logically, but you can also spark off other cards. This means you add the declarations from the specified to the current deployment declaration without the current context.

Running spark deploy spark.sus will deploy the first card, which in turn will spark off the other cards and, in doing so, deploy everything. Running just spark deploy "spark.sus bash" will only deploy the bash dotfiles.

This creates a duplication of efforts. The bash directory is a commonality between the sources of these deployments.

We can solve this using Sparks outof declaration. After an outof declaration, every source is prefixed with the given directory. The card can then be rewritten like so:

card bash {
into ~
outof bash
.bashrc
.bash_aliases
}

This is completely analogous to the into declaration of course.

Alternatives

Up until now we have only considered one system. Suppose you have multiple systems with each their own dotfiles. Usually most of these dotfiles will be somewhat similar.

With the Super User Spark, there is now an easy way to share these dotfiles across systems while still using separate specific dotfiles where necessary. The alternatives declaration creates multiple options for the source of a deployment.

Let’s say one of your systems has alpha as the hostname and the other has beta as the hostname. Let’s say that alpha is a very general system with the regular shared dotfiles and beta uses the regular .bashrc but needs a more specific .bash_aliases. You could have a directory structure like this:

Notice that $(HOST) is a Spark variable that will be resolved from the environment during deployment.

When spark deploys this card on the alpha system, it will use the files in the shared directory because it can’t find any in the (nonexistent) alpha directory. On the beta system, however, spark will look in the beta directory first and find the bashrc file to deploy to ~/.bashrc. Because it doesn’t find bash_aliases in the beta directory, it will use the bash_aliases file from the shared directory.

Note that, an outof declaration is equivalent to an alternatives declaration with only one directory.

This allows you to make a single dotfiles directory to share across all your systems.

Multiple subdirectories

To use more than one subdirectory for different categories of dotfiles, you will have to use blocks. For a more modular Spark configuration, you can use multiple cards. More on blocks and cards in the next post.

This post motivates and introduces Super User Spark, the Spark language and the spark tool. Assuming no previous knowledge, this post demonstrates how a beginner could use the Super User Spark.

The Super User Spark is a tool that allows you to manage your beautiful and precious system configuration accross multiple systems and failures. The Spark language is a domain specific language in which you can describe how you want to manage your dotfiles. spark is the command line utility that allows you to parse, format, compile, check and deploy your spark files.

Installing spark is as easy as running cabal install super-user-spark.

Demo

Imagine you are configuring a completely new system. The first thing you do on your new system is create some aliases in a new file: ~/.bash_aliases.

alias please='sudo'

These aliases need to be sourced from .bashrc of course, so you add this line to your .bashrc file.

source ~/.bash_aliases

You’ve now put some work into configuring your system. All of this work would be lost if you happen to have to reinstall the system because you broke it. To keep your dotfiles safe, you store them in a dotfiles repository:

This works, but there is a problem. If you change any of these dotfiles, you have to copy them into the dotfiles repository again. Even worse, when you bring the dotfiles to a new system, you have to copy all the dotfiles out of your dotfiles directory to the right places. You decide to make symbolic links instead.

~ $ ln -s /home/user/dotfiles/.bashrc /home/user/.bashrc

Again: This works, but there is a problem. Making all these links is tedious. You could write a bash script but that gets tedious as well. There are a lot of edge cases to consider (for example if the destination already exists in some form) and a lot of the paths have commonalities.

This is where spark comes in. You can write a Spark card to configure where you want these dotfiles to be deployed.

You can probably guess what’s happening here. This card is named bash. All the deployments go into the home directory. The ~/dotfiles/.bashrc file is linked to ~/.bashrc and the ~/dotfiles/bash_aliases file is linked to ~/.bash_aliases.

Running spark parse bash.sus will check the card for syntactic errors and spark format bash.sus will format the card nicely if you are too lazy to do that yourself. Running spark compile bash.sus will show you exactly how the dotfiles will be deployed:

Finally, running spark deploy bash.sus will perform all the linking you expect. It is possible that spark deploy will tell you that the destination files already exist. In that case, spark doesn’t assume anything and it won’t do anything. You can run spark with the -r/--replace option to override the existing files/links.

Syntax

As you have probably noticed, writing .bashrc -> .bashrc is a bit tedious as well. spark has a shorthand syntax for this deployment:

card bash {
into ~
.bashrc
.bash_aliases
}

Dotfiles are often hidden when you perform ls without the -a/--all option. You could store your dotfiles without the dot: bashrc and have it be deployed to .bashrc as follows:

card bash {
into ~
bashrc -> .bashrc
bash_aliases -> .bash_aliases
}

Of course then you’re stuck with the long-hand syntax again? No you are not! Because this is such a common use-case, you can just use the previous syntax again. spark will first look for the file with a dot and then for the file without a dot. Just make sure you don’t also have a file with the dot in the name.

The final card could look like this:

card bash {
into ~
.bashrc
.bash_aliases
}

Workflow

You can now keep your beautifully configured system up to date and restore it after a breakage with one simple deployment. Your workflow concerning dotfiles could look like this:

My first night in Zurich went from stressful to horrible. In retrospect, I could have prevented it.

The story

I was going to work in London until Friday 11 SEP in London. The next Monday would be my first day of university at ETH in Zurich, Switzerland. This meant that I had to find accommodation in Zurich remotely.

We had been looking for accommodation for two months when finally things began to look up. My girlfriend had found a post on facebook saying there was this woman in Zurich with a room for rent. She sent me her contact details and I began communicating with this woman. I had chatted with the woman via skype and exchanged emails. She was known as Nerea Sanz and was of Spanish origin.

She sent me a contract and after we both signed it, I transferred the first two months of rent and the deposit. Because her father was living in the UK, I transferred the money in pounds to a UK bank account. We chatted some more afterward and all was well for me to arrive at the flat. We had agreed to meet at 18:00 at the flat.

On Saturday I flew to Zurich with my three big pieces of luggage. At the airport I took a taxi to the flat. I arrived at a big building with hundreds of rooms but there was nobody there.

I had no Internet connection and no cell service because I was new to Zurich. After ten minutes of looking around in confusion and twenty minutes of ringing the apartments bell I started becoming very frustrated. Someone who lived in the building was kind enough to let me in past the front door into the lobby.

The building had WiFi, so I started mailing Miss Sanz and went to her door. I started knocking on the door but nobody answered. I knocked on the neighbor’s door but they told me they’d never seen anyone living in the apartment.

It was at that moment that I noticed that my wallet was gone. I had left it in the taxi. I had nowhere to go at this point. I didn’t have my ID, nor any bank/credit card and no money.

I had become desperate. The neighbor was kind enough to bring me to a youth hostel and made sure I could stay there for the night. He had saved my day. At the hostel I found out he was a Googler. What are the odds!

The next day I went to the police to report the scam.

Reflection

The entire situation made me feel very stupid. There are definitely ways in which I could have prevented this situation. I find it important to reflect on them.

Taking no time to find accommodation and to rest between working and studying seemed like something I would just have to put up with if I wanted to do both. It may still be, but it caused a very stressful period where I was vulnerable to being scammed. I had to find accommodation urgently, I was not around for any viewings and I was desperate to get it over with.

I don’t have a facebook account. My girlfriend sent me the information about the post. At this point I could have already known that this was going to be a scam. The information about ‘Nerea’ was entirely different from the information on facebook. On facebook she was known as Bouzidi Soroya. Of course I didn’t find out about that until afterward.

In a skype chat, she told me her webcam and microphone were broken. This is not necessarily a red flag but it should definitely have warned me.

This is a screenshot of her skype profile. Needless to say I didn’t have a close look at this profile before I noticed it was a scam. Let’s see if you can find what’s wrong with it.

Geneva, Swaziland?! If that wasn’t a giveaway, look at the phone number. It’s 14 digit’s long! There are no phone numbers that long. The biggest red flag here is the ‘1 contact(s)’. It should have stopped me immediately. The profile was clearly created just for the scam.

Looking her up online, I should have noticed that ‘Nerea Sanz’ is nowhere to be found online. There are no digital records of her whatsoever.

Conclusion

I lost a lot of money during the scam and a lot of time afterwards. I don’t think something like this will happen to me again in the near future and I hope this post will make other people more suspicious as well. I am very thankful for everyone’s help, especially the Googler that got me to the hostel and the family I’m staying with right now.

Mathematics courses are hard. Exams are usually more difficult than you expected, even if you expected them to be tough. Usually people think that you have to be really smart to understand mathematics and that most people could never do it.

I’m here to show you that there is a way to study mathematics that requires no intuition whatsoever, just a lot of hard work. Of course this is coincidentally my personal study method.

A brute force approach

If you are the kind of person that doesn’t need to study a lot to pass the exams for mathematical courses, this post is not for you. Go and enjoy yourself otherwise! This post is for the student who is struggling with mathematical courses but has to pass them nonetheless. It is probably best used as a last-resort study-guide.

Myself and mathematics

I absolutely love mathematics but I don’t have any ‘native’ intuition for it. Everything I know has to be explained carefully and exactly before I can start to comprehend it. I don’t consider myself a pure mathematician but I like their attitude towards pureness and proofs. Compared to mathematicians, at least at my university, I am usually more curious about the material but a lot slower at comprehending it.

Going to class doesn’t do it for me. Classes usually go too fast for me to keep up with them and in exercise sessions, teaching assistants tend to skip over too many steps at once for me to follow what is happening. I struggled with this kind of course for a while. I needed to find another way.

Goals

First things first, what are the goals here? There could be several goals to achieve when considering a math subject.

Passing the class

Getting very good grades

Studying mathematics purely

Satisfy the personally need for knowledge on the subject

Being able to put it on my CV

Making your parents proud

Impressing the teaching assistant

…

Mine are usually the first and the fourth. Whatever your goals may be, it is important to make note of them.

Structure of the course

Usually a mathematics course will consist of at least one lecture a week and perhaps some exercise sessions. I don’t necessarily recommend going to any classes but they may be more useful to you than they are to me.

Professors commonly use self-written course material that is available at the start of the course. Usually professors don’t get along with me well as I have a nasty habit of asking questions that seem trivial to anyone with a significant amount of intuïtion in the course.

At this point, it might seem as though all the odds are against me, but there at least one positive point about the structure of mathematics courses: the exam. Exams are usually open-book, in the best case the exam is even an all-you-can-carry-open-book exam. Further more, last-year’s exam questions are mostly made available by last-years students.

On to the hard work!

I want to give you one last warning: This is going to sound like a lot of work. That’s because it is.

Structure of the course material

Out of personal experience, this is how the course material is structured:

The book consists of chapters that are sorted by increasing complexity and grouped by subject.

A chapter consists of sections that build up to the main results of the chapter

Chapter/sections contain the motivation for the chapter/section, definitions, lemma’s, theorems, propositions and exercises.

Important to note here is that good books only use information that has already been provided. This is usually worded as “the book builds the theory up from a solid foundation”.

This method will make heavy use of the structure of the course material to describe a studying algorithm.

Studying algorithm

The studying algorithm is based on the assumption that you will create a ‘database’ of the work you’ve done for the course. You will keep every bit of work and it’s essential that you become proud of the work you’ve done. Your notes will be neat and you shouldn’t feel the need to throw away any of them.

For every part of the course-material you will perform the following steps (in this order). You don’t have to do every step of one section before you go onto the next, but you do have to do the steps sequentially on a per-section basis.

The algorithm assumes that you write your notes in such a way that new material is easily added in between older parts. Digital notes (see my examples at the bottom of this post) are a perfect medium for this. The notes should ideally become so complete that someone can study the subject from only your notes.

Step 1: reading

Read the text, focusing on discovering the goals of the section and marking every section that has a future action attached to it.

Step 2: consolidation

Copy the definition to your notes, as well as the lemma’s, propositions, theorems, etc… Don’t just stare at the symbols like a tourist stares at Egyptian hyroglyphs. Try to understand what you’re copying but focus on having a complete collection.

Step 3: proofs from the material

Try to build the proofs in the material from scratch. Use the proofs in the materials if necessary. Again: It’s important that your notes become a complete collection. Make sure that no gaps are left in the theory. If there are proofs missing in the book make sure you make them yourself and add them to your collection.

If a proof is skipped because it’s outside of the scope of the course, make sure you note that and create a reference to the proof. Don’t just leave it out.

Step 4: exercises and extras

Make all the exercises. Every. Single. One. For every definition, if applicable, explain why every precondition in the definition matters. For every theorem, proposition, etc, give a counterexample of the theorem/proposition when you leave out one of the conditions. If you think of something that could be a theorem, prove it or give a counterexample.

It is important that you not only understand why you are ‘allowed’ to take the steps that you take but also that you reference the relevant theorems.

Step 5: exam questions

Find the exam questions from the previous years and make them. Make sure your solution is correct and explain it in great detail. Make sure not to skip over any steps in your reasoning. Add them to the collection.

Step 6: Open-source your work.

There’s no point in being selfish about your academic work. You won’t succeed more if you deny others your help. Share the fruits of your labor.

The idea

The goal of this project is to create a system that allows the users to create and maintain good habits and get rid of bad habits.

It requires the habit to track your habits for such a system to work. The system also needs to be designed so that it will become a habit for the user to track its habits.

Because there already exist so many web-based, GUI-based habit trackers, it is important that this system tailors to power-users and integrates well with their system.

Requirements

This program could be a mobile application but it must at least be a desktop application. Either way it must function offline perfectly. The desktop application should work on Linux systems.

The application’s source code must be free and open source. The application must be free of all advertisements and downloading it must be entirely free of charge.

The program should have a command-line interface. All the functions should be accessible via a command-line interface, both in human-readable and computer-readable format. This will allow the (power-)user to integrate the habit tracker with the rest of their system as they wish.

Habits are ‘global’ in the scope of a user. For the sake of total immersions, the application would benefit from additional realisations with a centralised data store. That’s a very complicated way of saying: a mobile application would be good too. The application should allow (power-)users to take the responsibility of managing that centralised data store.

The system should be extremely configurable. The configuration should be textual and human readable when stored.

Suggestions

This application, at least the local application, is a good starter-project for anyone trying to learn a new language.

Haskell seems like a very good candidate for a language to write this application in. The opt-parse applicative library is perfect for the user interface. The Aeson JSON library allows for easy serialisation to- and from JSON.

For communication with a possible server, Protobuffer protocols seem perfect.

I wanted to celebrate getting an internship at Google with something special. Because I didn’t use to live in an English speaking country most English idioms were unknown to most people. That meant I couldn’t make references to them. Now I was going to live in London for three months. The timing was perfect to finally scratch this item off the list.

Bucketlist: Lemons

I gathered some of my friends and my brother who were awesome enough to help me with this. We went to a market, bought one hundred lemons and headed to St James’ Park.

It turns out that handing out free lemons is not as easy as I thought. At first we just held out our hands holding a lemon and said “Lemon?” and people would look at us with a confused expression on their face or ignore us entirely. They would then walk past us faster than they could read what was on our shirts.

Handing out one hundred lemons started to look like a difficult task. We were determined to hand out all the lemons before we went home.

We started successfully handing out lemons when we realised that that only works if you’re very enthusiastic about it and allow people to take the time to read the tshirt. We had to have a very big smile on our faces, approach people head-on and slowly so that they had time to read and loudly, clearly and enthusiastically say “Would you like a free lemon, Sir?”

Even then we got very mixed reactions. Some people would ignore us, some people would just awkwardly take a lemon and walk on. Some people would say ‘no’ with an annoyed tone. One of my friends would tell them: “Well no lemonade for you then!”.

There were also more fun reactions. Some people would smile when they saw us coming and happily accept a free lemon. The best reactions came from the people who wanted a picture with us:

Bucketlist: Lemons

If have a lot more items on my bucket list but I’m very glad to have started scratching items off.

I’ve done it again. I’ve massively over-engineered a solution to a simple personal annoyance. This time it’s a build system.

I like solving project euler problems but I don’t like having to figure out how to compile my solutions. When solving project euler problems I want to focus on actually solving the problems. I don’t want to be bothered by the fact that I have to think about how to run the program.

Moreover, when doing a long-term project I want to ensure that the project stays consistent throughout the entire process. Lastly I really want to have some documentation on what’s happening in the solutions.

Enter EDEN. EDEN takes care of all the hassle of solving project euler problems. It can build, run, test and publish your solutions, libraries and writeups. Even better, all dependencies are automatically reduced to a minimal tree and resolved in parallel.

The idea for this project was the first one I ever tried implementing when I had just started learning how to program. Back then it was a non-version controlled, goop of spaghetti code that happened to function sometimes. I have since also lost the source code but I would like to rebuild this system, as it was of great personal use to me back then.

The idea

The goal of the project is to build a system that allows users to create incentives for themselves to do what they want to want to do in exchange of doing things that they like. That is a very abstract way to explain the idea so let me explain how this instantiated itself in my first implementation.

The program was an offline desktop application that displayed a clock. The clock did not show a point in time but rather an amount of time. At the time I wanted to start exercising and I liked gaming. The goal was to exchange exercise for gaming. I entered the exercises I’d done into the program and I would get more time on the clock. When I wanted to game, I would start the clock and I had to stop when it would run out of time. This gave me a strong incentive to exercise (a lot) more.

Requirements

This program could be a mobile application or a desktop application but it must be function offline perfectly. If it is a desktop application it should work on at least Windows, Linux and Mac systems.

The application’s source code will be free and open source. The application must be free of all advertisements and downloading it will be entirely free of charge.

The interface will be graphical but my objections to GUI’s should be taken into consideration. This means that there should be configurable keyboard shortcuts and the appearance should be heavily configurable.

The central concept in the application is that time is to be earned and spent. No other currency should be used, especially real currencies.

In my example I used exercise and gaming. Which concepts are used to earn time and to spend time should be entirely configurable. Not only the concepts but also the concrete ways should be configurable. In the example of exercise, it should be configurable that doing push-ups is a way to earn time and how much a push-up is worth should be configurable as well.

There is a soft requirement for earnables to change in value based on how frequent they are achieved. The way these values change should be configurable as well. Consider the example of exercise again. Doing a lot of push-ups should decrease their value and increase the value of sit-ups but shouldn’t decrease the value of running.

A lot of parts of this application seem to have to be configurable. The configuration should be textual and human readable when stored.

Suggestions

Because of the environment requirement, it seems reasonable to consider using a JVM language if it becomes a desktop application.

Update 2017-06-10 : Prototype Android App

I have built a very rough prototype in the form of an android app, and am currently looking for people who would like to join in.

“Figure out a way to journal” has been a task on my someday/maybe list for some time now. After a short search for a good system, I came to the conclusion that I would probably be better off making my own. I am now proud to present you “Chronicle, the command-line journal system”. It’s supposed to be a small tool that does one thing very well.

Requirements

I know that I have very specific personal requirements for my workflow systems and I know that they are often very different from other peoples’. My ideal journal system …

At this point, it might already be clear why I had to make my own system. I found only one command-line option: jrnl, but it already had the python dependency and I didn’t like the way it stored its files. Moreover, I was confident that I could build my own system relatively quickly.

A new system

Chronicle has a command line interface. You really only need to know the enter command to start using it.

$ chronicle enter

Chronicle will open your preferred editor and save the new entry when you are done.

Alias

To satisfy the transaction cost requirement, I wrote an alias:

alias j='chronicle enter'

This means that I only need to type a one-character command to start a new journal entry. That’s as low a transation cost I think I can get.

Dependencies

Chronicle is just a big bash script. The only dependency it has, is openssl, and that’s only if you use the encryption option.

File format and synchonisation

Chronicle uses text files and only one of them per entry. That means you will be able to read those files in 50 years if you decide to keep them. That also means that you are able to synchonise your entries easily without the possibility of generating conflicts.

Encryption

Chronicle has built-in support for encryption. This way your secrets will be safe for anyone without the password. If you would like an encryption algorithm that guarantees integrity of your files as well, you could set the ENCRYPTION_METHOD as necessary.

The name

I chose the name because of this definition of the noun “chronicle”:

chronicle: a factual written account of important or historical events in the order of their occurrence.

I’ve since realised that this name is far from unique for a program, but I’m sure you’ll find Chronicle on Github if you would like to use it.

The source

The source is of course freely available. Any improvements, suggestions, bug-reports and comments are very welcome.

On 2014-07-29, my first ever blogpost went online. That post is now a year old and I’ve written another post at least every week. Let me reflect on a year of blogging.

I started a blog to share interests, experiences and ideas, as well as to build a long term memory assistence tool. The sharing did happen and I do now have a collection of articles that I wrote some time in the past but these, in hindsight, are not the interesting parts of blogging.

Time

I thought I would save time by blogging. My reasoning was that I’d only have to write down my opinion on frequent subjects once and then I could give my opinion by referencing the post. That did not work out as expected. This solution looks like it scales very well (and it might!) but I don’t have a big enough audience to make it worthwhile just yet. As a temporary conclusion I’d say blogging does not save time.

Writing

There’s one objective I had before I started that I did make very good progress on: I wanted to write better. If I compare my first posts to my recent posts, I do seem to see a difference. To get more significant results though, I would have to get my articles reviewed by good writers.

Unexpected advantages

There are also some advantages to blogging that I did not expect at all. While writing, my own opinion often became clearer to myself than it was when I had it in my head. Explaining an opinion in text rather than in speech forces you to form a better founded opinion because it’s a lot harder to use ambiguity in your favor when writing than when talking. This means that writing my opinion (and even more importantly: publishing my opinion) forced me to have really clear and valid arguments.

Almost a year ago I wrote a program to synchronise and backup your dotfile called Super User Stone. I’m very pleased to finally deprecate that tool and announce the Super User Spark.

I realise that the name is somewhat unimaginative but I had to find a way to not have to rename my SUS depot.

After the installation of the Super User Spark, you will find yourself with a new binary in one of the directories of your PATH: spark. spark was essentially created for the exact same reason as the Super User Stone. spark allows you to synchronise and back up dotfiles. This way you only ever need one directory of dotfiles and deploy it on all your systems.

A quick demo

To give you a good overview of the power of the spark language, we will require a more complex example than the one I used to demonstrate the Super User Spark. This demonstration will not be a comprehensive overview of the usage of spark. For more information, see the sparkusage page.

Say you use both Bash and Xmonad. You might then have these dotfiles on your systems:

In this example, you’re using a different kind of keyboard layout on your desktop and your laptop. Because of this, you use a different set of key bindings for Xmonad that you define in two different Keys.hs files. Moreover, on your laptop, you use different aliases, which you define in a different bash_aliases file. You would then build a SUS depot as follows that’s shared among, let’s say, two systems: desktop and laptop.

The real difference between Stone and Spark is the file that you add to your depot. spark uses a domain specific language to allows you to specify how you want your files to be deployed. The full specification of the language can be found in the source code repository. The card will then internally be compiled to instructions for deployment. In this example the content of spark.sus, for this example depot, would look like this:

# Call the card "sus".
# This will only matter once you have more than one card.
card sus {
# First look for the file in $HOST.
# If the file is not found there, look in shared.
alternatives $(HOST) shared
# Any deployment will go into the home directory.
into ~
# A block (between braces) allows you to keep the 'into' and 'outof' declarations
# that are in effect but making the ones from the block local.
{
outof xmonad # From here on all deployments will come out of the 'xmonad' dir.
into .xmonad # This 'into' statement compounds with the previous to '~/.xmonad'.
# Deploy the xmonad file
xmonad.hs -> xmonad.hs
{
# Custom Xmonad library files
into lib
Keys.hs -> Keys.hs
}
}
# After this block, everything is as it would have been before the block.
bashrc -> .bashrc
bash_aliases -> .bash_aliases
}

This card will compile to the following deployments on the laptop system:

Reference

To see a more elaborate example of how spark can be used, have a look at my personal SUS depot. One important feature that wasn’t mentioned in this post are sparkoff’s. These allow you to really make your spark configuration modular.

This fifth part of the series on how to use Taskwarrior to implement GTD is on the most important part of productivity: Doing your work.

Up until now, how have you been deciding what to do? Even if you knew what to do, how did you know there’s nothing better for you to do at that moment?

GTD offers you a concrete method to make informed decision on what to do when you work.

Have everything you know you’ve decided you need to do ready to evaluate.

Narrow down the amount of tasks to choose between as much as possible.

Context

The most important step in choosing what task to work on is to realise that there are tasks you don’t even need to consider. If you’re on an airplane and you have some time to work, there’s absolutely no way that you’re going to be able to water your office plants. Ideally, tasks that lie out of your current context should not even present themselves in the range of opportunities.

Taskwarrior makes this part very easy.

Remember that in the last part I told you to add a context tag to every task? Now we’re going to use them.

First, Identify the different contexts that you work in. For example, at work I’m always at a computer connected to the internet with a phone next to me, so the +@computer, +@phone and +@online tags go together:

context.work=+@computer or +@phone or +@online

At home, I currently have no internet connection:

context.home=+@home -@online

This might not be the most practical example but you get the idea.

Because you’ve already tagged all your tasks, setting a context takes care of the rest:

task context home # At hometask context work # At work

Now Taskwarrior will no longer show any tasks that are not available to work on in your current context.

Note that I’m assuming that you’ve either synchronized Taskwarrior across your home- and work computer, or you’re using a laptop.

More narrowing down

You can take the ‘narrowing down the options’ step of GTD down a lot further than just contexts. Be wary however, this could increase the transaction cost of using your system if you’re not careful.

Brain power

Here’s another example. You’ve just done an exam and your brain feels like it’s toast. There’s no use in seeing a task like Write a review of Marc's paper on monoids in the category of endofunctors (wink). A task like Water the office plants would ideally present itself at the top of your task list.

You can use Taskwarrior’s used defined attributes (UDA) to accomplish this.

You can omit the default value if you’d rather be sure to enter it yourself. If you end up with a task without a brainpower attribute, it’s possible that you might run into some sorting problems later.

Using your UDA’s

To evaluate what task you should work on next, assess the state of mind you are in and estimate the amount of time you have right now. Let’s say you’re ready to do some heavy-on-brainpower work but have only 10 minutes before your next meeting starts:

task next brainpower:H estimate:10

The next report should now show you a significantly smaller amount of tasks to choose from. Even better, you are sure that you only see tasks that you can actually make progress on within the next ten minutes.

In the fourth part of this series on how to use Taskwarrior to implement GTD, I will show you the fourth step of GTD: processing your ‘stuff’. This is where the real heavy-on-brainpower work comes in.

Every ‘in’ item should be processed by following this flowchart:

That is at least the idea.

Processing requirements

Processing your inbox should be very easy to start with.

Processing is about making decisions, not about starting or finishing tasks.

Processing with Taskwarrior

To start processing your inbox, type task in. You should now see your inbox items if you’ve followed this series up to this point. For every task you see there, go over the following questionnaire.

Decide whether the item is actionable.

It’s not: Decide whether to keep note of it in your reference system, whether you want think it over of just delete it. (Remember, when using think, you should enter a simple yes/no question.) Then check off the task.

It is: go on.

Is there more than one action required?

Yes: Start up a new project. Figure out the desired outcome for the project and add the first +next action to it: Don’t forget to add the +next tag.

task add +next pro:new.project "Set up a new git repository for the fancy new project"

Also add as many tasks as you can possibly think of for this project. Then check off the task.

No: Decide what action the +in task represents and go on.

Decide how long the action is going to take.

It will take no longer than two minutes: Do it right now. Then check off the task.

It will take longer than two minutes: Estimate how long it would take to complete the action and go on.

Are you going to delegate the task?

Yes: Modify the task to be a waiting task and annotate it with instructions on how to check whether the task is done yet. Then delegate the task. Let’s say the task has ID n.

I added due:+1w, which means that Dave has a hard deadline of one week to complete this task and wait:+3d, which means that I can’t see this task until tomorrow so that I won’t pester Dave about it until at least three days from now.

No: Go on.

Defer the task

You know which project the task belongs to. Add your task to that project. If it’s the next action for that project, don’t forget to add the +next tag and check the in task.

task n done
task pro:gtd add Call Jamie to schedule a meeting.

Make sure the action is really an action. It must be something that you can start doing immediately without thinking about “how?”, “where?” or “why?” thanks to the thought you put into it at this moment.

When you get into the habit of asking yourself these questions, there should come a point where you don’t need the flowchart anymore.

Contexts

Later, when you finally get around to doing, it will be very important for your mental health to keep in mind the context in which you are working. Luckily, Taskwarrior makes it very easy to allow you to use your context to your advantage. For now, all you need to remember is to always add at least one context tag to a tag. Common context tags are +@office, +@phone, +@computer, @online, …

It might not look like it, but this is actually very important. I would argue it’s the most important meta-data on your tasks.

Advanced Applied Laziness

Research

Often the very next task for a project is just a whole lot of ‘looking into something’. For that reason, here is the rnd alias:

alias rnd='task add +rnd'

Because, for me, looking into something always means looking it up on the internet, I add +@computer and +@online to the alias. Moreover, it’s always a next action as well:

alias rnd='task add +rnd +next +@computer +@online'

Read and review

Reading something later, when you know very well what it is you want to read is called ‘read and review’. Ideally, you know exactly what you need to do, which drawer you need to open, which file to open, which link to point your browser to,… Taskwarrior allows you to keep this info in annotation with task annotate.

For me, read and review always happens on the internet. Enter the rnr alias:

If you’re not into figuring out what bash code does: Entering the following command into your shell will result in a new task with a +rnr tag with description ‘GTD with Taskwarrior, part 4: Processing’ and the link as an annotation.

In the third part of this series on how to use Taskwarrior to implement GTD, I will show you the third step of GTD: Using a tickler file.

A tickler file system is usually implemented using 43 file folders. 31 for the days of the month and 12 for the months of the year. Every day you open the folder for that day and receive the ‘stuff’ in your inbox.

I personally like a paper-based tickler file but Taskwarrior seems particularly well equipped to handler a digital tickler file.

Tickler file requirements

Tickle items should only be visible on (and after) the day you need to see them.

For every tickle item, you should know why you get it in your inbox (again).

For every tickle item, you should know when you put it in your tickler system.

The transaction cost of using a tickler system should be as low as possible.

Tickler file with Taskwarrior

Remember that a tickle item is something that has to end up in your inbox at a very specific time. When implementing a tickler system digitally this can be done much easier than using 43 file folders that you check every day. Your computer can check your tickler file for you and just put it in your inbox again. This way you don’t even need to develop a habit, which we all know is hard work.

Adding wait: metadata to a task ensures that the task won’t be visible until the date that you set this metadata to. For example, when you enter the following command, the task doesn’t show up until the following Sunday:

task +in wait:sunday Remind Dave to water his plants.

Of course we will use an alias to do this more easily. We used an in alias to add ‘stuff’ to your inbox. Tickle items are also ‘stuff’, so we are going to use that in alias in the definition of the tick alias.

This tick alias allows you to add new tickle items by entering something like this into your terminal.

tick monday Put the office plants into the sunlight

This way the task will only show up in your inbox the following monday. Of course you can also use full dates like 2015-06-30.

Thinking it over

Personally, I often encounter a situation where I need to think something over and decide what to do with it later. This really doesn’t have to end up on a task list because then there’s the possibility that I’ll see it before I’m ready to think about it. For precisely that situation, I made the think alias:

alias think='tickle +1d'

It is important that you don’t ever think something over twice. You don’t want to create a snooze button! A good practical tip is to make sure that every think item is a simple yes/no question.

In the second part of this series on how to use Taskwarrior to implement GTD, I will show you the first step of GTD: collection.

Collection allows you to capture ‘stuff’ and thereby freeing up your mind to do what it’s good at: creative thinking.

Collection requirements

Let’s look at the requirements of GTD’s collection:

The inbox is where you capture ideas and tasks as they occur to you.

The transaction cost of putting something in your inbox should be as low as possible.

If your inbox is not at zero, it has to be immediately visible.

You should need as few inboxes as possible.

Taskwarrior inbox

An item in your inbox is really just a “this-needs-to-be-processed-item”. As such, it is something that you need to do with the added semantics that it’s just a decision. There is no reason why Taskwarrior can’t also be your inbox given that it’s used correctly.

You can’t just add inbox-items to Taskwarrior just like you would add normal tasks. That would ruin the concept of an inbox as well as the rest of Taskwarrior. This needs to be handled with a little more care.

Adding ‘stuff’

We need to make it very easy to add an item to our inbox. I do this with an alias. The following line is in my aliases file.

alias in='task add +in'

Note that the +in tag is used to add the semantics of an inbox item to the task.

Now, when you want to add an inbox item, you just type in:

$ in Set up meeting with Dave

That’s two letters instead of twelve. You could bring it down to one, of course.

Ever-present stuff

We can now make use of the +in tag, by making sure that the +in tasks show up exactly when we need them to.

You need a way to see how may tasks are in you inbox. There are two ways to do this. You can use Taskwarrior’s built-in urgency system to have in tasks show up in your next report, or you can have the number of tasks in your inbox show up in you terminal’s prompt.

Urgency

To add urgency to an in task, we modify its urgency coefficient. You can do this by putting the following line in your ~/.taskrc file:

urgency.user.tag.in.coefficient=15.0

I usually recommend against this because it will clutter your next report later.

Inbox in terminal’s prompt

To add a the number of inbox items to your terminal’s prompt, you can modify the PS1 environment variable. You can add this to your shell’s ‘.rc’ file:

exportPS1='$(task +in +PENDING count) '$PS1

Mind the single quotes. Now your shell’s prompt will say how many tasks are in your inbox.

Report

Later, when you will process your inbox, you will need to see it. I have made a custom report to view my inbox. You can configure it by putting the following lines in you ~/.taskrc file.

This is the first post in a series where I’m going to show you how I use taskwarrior to implement GTD. I would like to put up a guide that shows how to use taskwarrior to GTD in great detail, as well as make a record of my usage for personal recollection.

This entire series assumes that you at least know what GTD is. If you have no clue what GTD is, you can check out the blogpost GTD in 15 minutes – A Pragmatic Guide to Getting Things Done, or just read the book, of course. The series focuses on implementing GTD, not explaining GTD, but you might be able to follow if you don’t feel the need to know why I do this.

In this post, I will show you what taskwarrior is, how to get it and the basics of using it. Please note: If you want to replicate this system, you will have to be familiar with using a terminal.

An intro to Taskwarrior

Taskwarrior is a free and open-source, command-line, task management program with options for synchronisation, automation and optimisation. I think you can already see why I use this and why I would recommend using it. There is a more extensive list on the taskwarrior website of reasons to use taskwarrior, but I think I’ve made my point.

A Taskwarrior system can be viewed as a giant list of all your tasks. Taskwarrior’s strength comes in the abundancy of ways to view, create, update and check off these tasks. In a way, it’s just a very efficient list manager.

Getting Taskwarrior

Taskwarrior’s task is a package in most Linux distributions. I would recommend cloning the git repository and compiling the program from source, so as to get the latest version. (Taskwarrior is still very much under development)

More details on how to get Taskwarrior can be found on the website as well. For me, installing task was as easy as running:

$ sudo pacman -S task

The basics

You can read the entire manual page for taskwarrior (man task), but it’s probably easier to learn as you use the system. The main concept to retain is that a task command is always of the same form:

$ task <filter> <command-name> <arguments>

The <command-name> part is obvious: You select which functionality you would use: adddonelist, etc… A task command, by default, is run on all your tasks, but you use the filter part of the command to filter out the tasks that you want to run the command on. The <arguments> part is different for every command, but you will get the hang of that soon.

The basic commands that you have to understand before you can start using your shiny new system are next, add and done. Try running task right now. You should see something like this:

$ task
[task next]
No matches.

Taskwarrior runs task next by default when you run tasktask next shows you a list of your most urgent tasks. A number of factors are used to determine urgency of a task. For now, just assume that Taskwarrior knows what’s best for you. You will probably use this command most often.

Adding tasks is very easy:

$ task add Read chapter 1 of GTD
Created task 1.

Tadaah, you’ve created your first task. Each task has an ID, this one has ID number 1.

Now, because you’re using GTD, you will want to add the task to a project. You do this by adding project:read.gtd to the command. Because Taskwarrior is made for efficiency, you can shorten project to any unique prefix, so you can also use pro:read.gtd. Taskwarrior also allows you to tag tasks. You add a tag to a task with a +<tag> argument.

In full, you would use something like this:

$ task add Read chapter 1 of GTD pro:read.gtd +read +@home

Lastly, you need to be able to check off tasks. Remember that each task has an ID? You use that ID as a filter when you done a task.

$ task 1 done

This way, you can check off multiple tasks at once by enumerating them in a comma-separated list 1,3,8,71 or a contiguous set 1-5, or both: 1,5-10,12.

There, now you know the absolute basics. If you want to read more on how to use taskwarrior, I suggest you read the 30-Second Tutorial on their website and the Best Practices.

Software always requires an interface (even if only for administration). We expect certain qualities from the user. Usually those include knowledge of the problem at hand and knowledge of the system that solves it. Often times we also unknowingly expect the user not to be an idiot.

I was in Professors Hughes class when he said this. It was in response to a student who asked something about how robust network protocols should be.

For a protocol to have any use, users have to do exactly what the protocol tells them to do. We expect some cooperation from a network’s users. In that sense, a stupid (or malicious, more likely) user might be able to break the network. This is, of course, not only true for network protocols.

The question at hand is about how far we should go in fool-proofing a system. Obviously a monitoring system at a nuclear plant should be more fool-proof than a music player, but there’s no clear all-encompassing heuristic, is there?

Given that it’s nearly impossible to build a completely fool-proof system, I personally think we should always continue fool-proofing the system until no user could ever do any harm. Really, what we want is to give users an incentive not to break the system and no incentive to break the system. We should make sure the user could never gain anything from breaking the system, for example by rendering it unusable if the user tries to break it. To a truly ‘stupid’ (non-malicious) user this won’t make any difference. That’s why we also have to make sure that a user can never do any harm by using the system.

Say you’ve made a mistake. Something has happened that you didn’t intend to have happen and you didn’t want to happen. Let’s say someone is kind enough to point out your mistake. What do you do?

You might not care that you’ve made the mistake. You can then ignore the entire situation and go on with your life.

Say, however, that you care enough to reply to the person that pointed out your mistake ever so helpfully. You can hold on to the nearest, cheapest reason that you can think of to explain why the mistake found its way into existence. After that, you can still move on with your life, having satisfied your remarkable need to attribute responsibility by either taking that responsibility, or giving it to someone/something else.

The mistake is still there though. If you haven’t fixed the cause by now, it might happen again. Are you going to have it happen again?

There is no use in finding the reason why your mistake took place if not to help you fix it now or to help you prevent a similar mistake in the future. If you are not planning to fix your mistake, the difference between finding fault and not finding fault is only time, wasted time. Not only your time, but the time of the person who was helpful to you. Now that’s not very grateful, is it?

Enough of my guilt tripping. You haven’t even necessarily done anything! What I’m trying to show you here is that the mistake, in this situation, is not a bad thing. On the contrary, it allows you to improve yourself through the helpfulness of the person that pointed it out. What I’m also trying to show is that the reason you’ve made the mistake does not matter unless you use it for reflective purposes.

]]>Sun, 03 May 2015 00:00:00 UThttp://cs-syd.eu/quotes/2015-05-03-dont-find-fault-find-a-remedy---henry-ford.htmlTom Sydney KerckhoveDo you think he plans it all out, or just makes it up as he goes along? - Becket's Officerhttp://cs-syd.eu/quotes/2015-04-12-do-you-think-he-plans-it-all-out-or-just-makes-it-up-as-he-goes-along---beckets-officer.html
[ERT: 18s]

So, what do you think? Does Captain Jack Sparrow plan everything out?

I think he doesn’t need to plan a lot out. He has this compass that points to the thing he wants most at all times. Anyone who knows me knows that my advice on anything starts with “What do you want?”. Imagine of what kind of value that compass could be. If you know what you want, or you know where to go to get it, you can make everything else up as you go.

Suppose you have a nasty free-loader on your personal WiFi. You could just block his MAC address via the router settings, but you want to mess with them. There are all sorts of things you could do, but I want to show you one option.

What I’m about to show you is fairly technical. If you know about networks in theory, you’ll probably enjoy trying this. One last note before we start, for anyone this might seem scary to: “This is all possible on any computer and there’s nothing illegal about it.”

The general idea

In this post, I will show you how to make any site show up in the victims browser when they request content. I will give a proof of concept by having my blog show up in the browser when an unsuspecting victim requests some content. You might want to make their browser show hasthelargehadroncolliderdestroyedtheworldyet.com when they request facebook.com or tinykittens.com when they request youtube. You will probably think of more fun sites to have show up in their address bar, but in any case, it is sure to confuse them

IP address of your router

The first thing you’ll need is the address of your router and your own IP address:

You’ll find your own IP address after inet. Usually you will find your router’s IP address by replacing last digits of your own IP address by a 1. In this case the router’s IP address would be 192.168.1.1. Also note the network interface you’re using, in this case wlp3s0.

IP address of victim

The next thing you’ll need is the IP address of your victim on the local network. You can try nmap-ing your network to see which IP addresses are registered.

This file will make any request to google, facebook or youtube go to the IP address on the left.

All that’s left to do now is start spoofing the DNS.

sudo dnsspoof -i wlp3s0 -f ~/hosts.spoof

At this point, the victim will end up at my blog when they request some of the content. Note that if the victim has cached DNS requests, it will already know the IP address associated to the domain and not ask you for it. DNS caches usually time out after a day, so you will have to see this through for quite some time for recently visited domains to show up differently.

]]>Sun, 05 Apr 2015 00:00:00 UThttp://cs-syd.eu/posts/2015-04-05-how-to-prevent-someone-from-using-your-wifi-or-at-least-annoy-them-a-little.htmlTom Sydney KerckhoveIf people do not believe that mathematics is simple, it is only because they do not realize how complicated life is. - John von Neumannhttp://cs-syd.eu/quotes/2015-03-29-if-people-do-not-believe-that-mathematics-is-simple-it-is-only-because-they-do-not-realize-how-complicated-life-is---john-von-neumann.html
[ERT: 58s]

Have you ever wondered about how many of the things you say on a daily basis are true?

Let’s only consider statements as questions don’t concern themselves with the truth before they are answered. For a moment, just forget about anything subjective or vague you’ve said like “I feel warm” or “The weather is good today”. Those statements can be thought of as both true and false because they haven’t been clarified: What is good weather? For the sake of argument, you can complete any statement to the full statement you meant as statements are often abbreviated.

Remember that there is nothing between truth and falsehood. A statement is either true or untrue. What are you left with?

It’s not a lot, is it? Moreover, it’s really hard to even speak of truth in this context. Most statements are not meant to be true, they’re meant to convey information.

Mathematics only concerns itself with what is true. If a statement has been proven to be true, it is true. If a statement has been proven to be false, it is false. If something has not been proven, it is not used to prove others, until it is proven. Note that a statement doesn’t become true when it is proven, it was always true, but we’ve only just discovered that. This is why we speak about discovering mathematics.

Further more, a true statement is true in every circumstance. The truth of a mathematical statement is not even dependent on the very existence of the universe.

I’ve heard a few people suggest that mathematics is not something universal. One argument I heard is that “one plus one is two for us, but it doesn’t have to be that way.”. If you don’t see what’s wrong with that argument immediately, have a look at the definition of our numbers.

It’s true that the way we write our numbers is not universal. This becomes clear immediately when we look at other numeral systems. If you’ve heard about binary digits, you know that we can write numbers in different ways. Usually a way of writing numbers is specified so that basic operations such as addition, subtraction and comparison of size are easily carried out.

A programmer’s view

You can imagine numbers as dots on a line. No matter how we name these dots, they’re still the same dots. The way we write numbers is just a way of naming those dots.

To get a programmer’s taste of how numbers are universal, I’ll define a base \(n\) number system. Programmers use this kind of reasoning in a number of ways. Only one of those is to prove that a particular set of objects is countable. If we can write every element of the set as a number in a specific numeral system, we know the set is countable.

The value of a number

Let’s have a look at how we write numbers. \(495\) means \(4\) times \(100\) units plus \(9\) times \(10\) units plus \(5\) units.

In general, if \(d_{i}\) denotes the \(i\)-th digit of a \(k\) digit number in a base \(n\) system the value of the number is calculated as follows:

\[ (d_{1}d_{2}\dotsc d_{k})_{n} = \sum_{i=1}^{k}n^{k-i}d_{i} \]

We don’t need to write numbers in an ordered fashion like this, but this is the way we do it and this way has some nice properties:

We can get an idea of how big the number is by looking at how many digits are needed to represent it.

Once we know how to write all the digits, we can write down the representation for any number.

There are also some advantages for programmers:

We can perform addition and subtraction in logarithmic time with respect to the value of the numbers.

We can perform multiplication and division in a logarithmic amount of additions with respect to the value of the numbers.

We can perform exponentiation in a logarithmic amount of multiplications with respect to the value of the exponent.

For an arbitrary number system, here is a function that gives the value of a representation of a number.

The written representation of a number

The conversion from one number system to another usually consists of finding the value of a number and then building a representation for it in the other system. In the previous paragraph, you saw a formula to find the value of a number given its representation. Suppose you have a number of value \(v\), how to we build a representation for it?

The amount of digit in the representation of a number is equal to the number of times it can be divided by the base before resulting in zero. The remainder of this devision is then the index of the digit in the numeral system of digits.

It surprises me greatly how many people are unmotivated. I have heard things like “that’s too hard”, “why would I?” and “but, that takes effort!” countless numbers of times. Why is it that we take motivation less serious than personal hygiene?

Just like hygiene, taking care of your personal motivation is your own responsibility. It is best to make it a habit that you can take care of yourself, but motivation through others is better than none.

The first thing to do is, as always, write down your goals. Don’t just think of them while daydreaming. Writing your goals down makes you take responsibility for realising them.

Suppose you have a perfectly organized, hierarchical schema of all your life’s goals sorted by estimated due date. It’s possible, although unlikely, that you’re still not motivated to do anything. Let me take this opportunity to tell you that it’s okay to seek help to motivate yourself. This is especially true if you’ve never had the habit of taking care of your motivation.

It’s okay to listen to motivational sound tracks. It’s good to look at the people who are where you want to be. It’s fine to have people help motivate you, However, ideally, you want to be able to motivate yourself just like you like to be able to wash yourself.

I argue that motivation is as important as personal hygiene, but that the habit is less easily taught. I’ll show you what got me started.

A programmer occasionally ends up in a situation where his program almost works. There is something slightly off with the program. One of the values is just one unit away from the desired value.

At this point, the programmer gets cocky and starts to shotgun-program. This is where they change something quickly, without thinking about it, and hope that that solves it. They add a ‘+1’ here and a ‘-1’ there, in the hope that after this, they will never have to look at that piece of code again.

Off-by-one hell

After a few such attempts, the programmer ends up in what is known as off-by-one hell. This particular side of hell can only be gotten out of by stepping back, looking at the problem again, preferably on a whiteboard.

Off-by-one hell can be caused by a few kinds of problems, one of which is working with matrices and their indexes. This post is meant as a big cheat-sheet for this particular kind of problem.

The matrix

First things first. You have to name the matrix.

I will call it \(A\).

\(A\) is an \(m\) by \(n\) matrix. (‘m’ comes first in the alphabet.)

\(m \times n\) means that \(A\) has \(m\)rows and \(n\)columns.

An element \(a_{i,j}\) of \(A\) is on the \(i\)-th row and \(j\)-th column.

\(A\) is indexed in a zero-based manner. (In programming this is usually the case. In mathematics this doesn’t matter.)

Reverse indexing.

Suppose we’re given the index of an element in the matrix, how do we retrieve the row and the column number? This depends on the way the matrix is stored, of course. At this point it is very important that you’ve used a zero-based system of indices. Otherwise you’ll just end up in another part of off-by-one hell. Suppose you have an index of a value. We can then iterate over the matrix with one for-loop, even if it is stored as a two-dimensional array.

In my post about time management I mentioned that I don’t watch TV anymore. People have asked my why a couple of times now. I thought I’d answer their question here.

I don’t watch TV anymore though the house I live in still contains a TV set. I used to watch TV for hours every day. Realising that watching TV wasn’t helping me in any way, I stopped altogether. I only started realising the flaws of TV afterwards.

Time warp

After months of not watching TV, I happened to end up watching a program while waiting at a friends place. I noticed something about TV programs that I had never noticed when watching TV was a regular activity.

TV programs compress a large amount of events into a small amount of time so as to give you summarized, interesting content. However, because the content is so compressed, it is not nearly an accurate representative of the actual events. It gives you a skewed idea of what it’s like to witness these events. If you’re watching TV a lot, you don’t notice this. You watch TV and feel like you’re involved in what you’re watching, especially if you’re watching something that doesn’t happen in your daily life.

Real life often requires a kind of patience and endurance that you seize to expect if you watch TV a lot. This ‘miscommunication’ can bring great disappointment to anyone that wants to achieve anything. Of course, this doesn’t present a problem to anyone who hasn’t grown up with TV and is aware of this.

The most extreme example I saw, was a show that featured a man who started bodybuilding and took part in a competition eight months later. As a viewer, you might start to identify with what you see and think that you could easily do it as well. However, those eight months were compressed down to 40 minutes. The viewer gets a wrong idea of what it takes and will be disappointed by the difficulty if he ever decides to try it for himself.

This example is, of course, more extreme than others, but even regular content can miscommunicate this.

A fixed schedule

Television is old. It comes from a time that there wasn’t much content to be broadcast. In order for people to know when to watch and what to expect, programs were scheduled.

Of course, nowadays, there is so much content that scheduling programs to appear at a fixed time doesn’t make sense anymore. Moreover, there are other media that allow you to find the content you want, when you want it. (An obvious examples here is youtube.) Lives have changed as well, we know what we want to watch and we want to see it when it is convenient to us, rather than the producer.

Advertisements

You pay for a television subscription, and then you still have to watch increasingly long advertisements that break up you favorite shows. There are better media available, where you get to choose whether to waste time on adds. Online you get to choose when you watch advertisements through, for example, adblockers and/or subscriptions.

Everyone gets exactly the same amount of time: 24 hours in a day and 168 hours in a week. As it is your life, you are responsible for what happens to your time.

Time management is essential to get anything done. At some point I had to figure out where my time goes. What I write here is an old story. This all started about three years ago.

Introspection

The first thing I did was to write down the time I was sure to spend. I was amazed by how little that was. If you spend 8 hours asleep, 8 hours at work and 2 hours on necessities (eating, showering, etc…), that’s still 54 hours that you haven’t accounted for on a weekly basis. As a student, I don’t work fixed hours, but if you’re already unsure about where more that a third of the time goes when working fixed hours, I could only imagine where my time went. Of course, I still spent those hours somehow, so I had to figure out where they went.

There was no way that I was going to write down what I had done for every minute every day, but I did it for one day to get an idea. My biggest daily time spenders were the computer and the TV.

Because I spent so much time at a computer, I installed Mind The Time to find out where my time at the computer went. Once again, I was amazed. Almost none of the time I spent at the computer was spent productively.

Realising that I am horrendously bad at estimating where my time goes, I start keeping a log of what I spend time on while working. I thought I was a descent worker. I was wrong again. If I only counted actual work, and not the break time, I worked about 40% of my work time. That’s a little over 3 hours per day. Again, I still spent 7 hours on work every day. Where did all that time go?!

Decisions

In this blogpost, I haven’t written about one of the most important steps in this process. This step involves thinking of and writing down what you want to spend time on and what you definitely don’t mind not spending time on. Of course that’s very personal, which is why I don’t think it’s very useful to you (the reader) to read from me. It’s not worth improving your time management if you haven’t done this step.

Fixes

After finding out that I was not only bad at estimating my time spending, but also bad at spending the time, I had to fix some things.

On the computer, I installed Leechblock to block the sites that I didn’t want to want to visit. I deleted my facebook account. That was liberating! Another hour saved.

I started using Emacs and Org-mode which allowed me to log the time I spent on work. Not taking enough breaks became a bigger problem around about this time. During work, I started using the pomodoro technique. This ensured that the time I spent working was actually spent on work and that I regularly took breaks too. The fact that I clocked my work on every task made my work very time-focused instead of focused on finishing task.

Now I use taskwarrior to handle tasks. This makes sure that I don’t try to clock everything anymore. Task warrior is more focused on finishing tasks (and has a CLI, yay!).

Changing the way I work has saved me countless hours. I now spend more than 75 procent procent of my working time (including breaks) on actual work.

Reflection

Looking back, I can’t imagine not having gone through this anymore. I have become convinced that it is essential to be conscious of one’s time to manage it. Being motivated to do good work is definitely not enough to spend your time wisely.

I still have 24 hours in a day, but I get more done and I feel less stressed.

Computers weren’t always as easy to use as they are now. (Take it from someone who still uses an ’80s interface.) There was a time that the windows on a screen were a very new and amazing feature of a personal computer. In that time, it was an engineering marvel to have those windows overlap.

Bill Atkinson was an engineer at Apple when it was still called Apple computer. He created the complex code to allow windows on a screen to overlap. More interesting than the code is that Atkinson only thought it was possible because he thought he had seen it during a visit at Xerox PARC. He succeeded in making a never-before-seen feature because he was convinced (by what was evidence to him) that it was possible.

He later admitted that, if he hadn’t been convinced that it was possible to make those windows overlap, he would have quit before it was done.

This story is a great reminder of the fact that you use people’s life’s work every day, and that even they could only do it because they thought they could.

Curse Truly ergonomic!

A few weeks after I started using the “Truly-Ergonomic Keyboard” several keys started malfunctioning. Some keys didn’t register any keystrokes at times and other keys registered the same stroke twice. To give you an idea of what that looks like, I will type the following paragraph with the broken keyboard.

I sent a reqquestt for customer’s service to te compannyyy. I gooooot an autooomatic respppponse: “Dear valued customer…” but never did I get an answer from a uman. I sent a few of tese requests. Eventually I sent a request to returnnn te keyyyboard (and have it fixed). Still no answwwewer. Tis time I didn’t even get an automatic respponse!

I gave up on this company. Needless to say, I don’t recommend the keyboard to anyone. It’s my own fault for confiding in such a young company, I guess.

Hello Kinesis advantage

Even though Truly-Ergonomic has failed me, I still like the comfort of an ergonomical keyboard as well as the mechanical keys. I bought a new ergonomical mechanical keyboard: the Kinesis advantage.

Of course I’m making a custom layout based on programmers dvorak. Let’s hope that the kinesis advantage lasts longer than 6 months.

Typing speed

For those of you who wonder how fast i’ve gotten on a dvorak layout (I still plan to reach a speed of 125wpm some day!): I’d reached a speed of 60wpm before the keyboard broke. Of course, with a broken keyboard, typing tests don’t give an accurate result. After only one day with the advantage, my speed had reached 70wpm. The new keyboard promises to be amazing!

Let’s see. Obviously the first and last expressions here are just incorrect. The first one gives you a value that is a hundred times to large, the last one gives you a value that is a hundred times too small.

What about the second and third expression. Are they written in percentages?

I’m guessing you said ‘yes’ for the second formula and ‘no’ for the third. That is what you’ve probably been taught in primary school.

The question is, of course (sigh), somewhat vague because ‘written in percentages’ is not an exact expression.

In this discussion, I argue that both of these expressions are written in percentages and the first one is counterproductive.

The meaning of percent symbol

The first thing I have to rant about is the meaning of the percent symbol. The meaning of the percent symbol is congruent with its pronunciation: \(n \%\) literally means \(n\) ‘per cent’ which comes from the Latin ‘per centum’, meaning “by the hundred”.

This means that if you write \(45\%\), it really means \(\frac{45}{100}\) (or \(45/100\) if you want to keep it on one line). There is absolutely no semantic difference.

The use of the percent symbol

Usually a percent symbol is used to indicate that the number is meant relatively. For example: ‘\(50\%\)’, or ‘one half’ of whatever whole is is relative to. This as opposed to an absolute value. \(0.5\) and \(50\%\) are both equal to one half, but the first value absolute and the second one is relative.

The semantics of the percent symbol therefore both contain the meaning of the factor \(\frac{1}{100}\) and the relativity of the value.

Back to the formula

Let’s look at the second formula and rewrite it according to the meaning of the percent symbol:

The value of the second and third formula are equal, but the third formula does not inherently entail the relativity of the value. One could argue that, because these value concern chances, these are always meant as a relative (to \(1\)) measure but that’s a happy accident.

My annoyance

You might have noticed that I’m taking this pretty far. My annoyance with percentages boils down to the combination of two completely independent pieces of semantics: relativity and some seemingly random factor.

The relativity of a value is a very useful piece of semantics. This part is great. It’s meaningful. I actually think there should be a symbol just for that.

The factor \(\frac{1}{100}\) that gets added to a value by the percent sign is, in my opinion, completely pointless. To imagine a percent, you tend to think of ‘one out of every one hundred’, but one hundred is no more useful than any other (small) number. One in twenty (a pervingt, if you will) is just as easy to imagine as one in a hundred. Most of us even automatically simplify \(50\%\) to one half and \(12\%\) to one eight and at that point the factor becomes useless at best. Even worse, because we’re adding a factor \(\frac{1}{100}\) due to the symbol, often we have to add a factor \(100\) to get a correct value!

Here’s what I propose: We drop the percent symbol altogether and indicate whether an expression is relative in words. If an expression is relative, we have to specify to what it is relative in words anyway, so an other symbol may not be necessary.

I consider workflow optimisation one of my hobbies. At some point, a friend of mine pointed out how much time I spend trying to optimise work. He pointed me to this quote, and I think it contains a message that people like me need to keep in the back of their head.

The quote comes from someone giving advice on how to write a play. Instead of focussing on planning and organising your work, it argues that we need to focus on doing the work and not giving up. This a friendly reminder to focus on the work rather than the work system.

This post contains my personal experience with a new sleep behaviour that I’ve tried. If you haven’t read the post about the setup, go read it first.

A notepad

Thinking paper is not just an abstract concept. Next to my bed, there is a notepad and a pen on my night stand. I’ve made it a habit to write anything I think of, while lying in bed, that I might want to remember, on the pad and tear of the piece of paper so that I’ve got a clean sheet again.

It’s come so far that I wake up next to few pieces of paper every morning. They contain a wide variety of pieces of information. This little notepad has helped me to recollect my experience with this experiment immensely.

There are often four to five notes on the notepad. Strangely, I don’t remember that I’ve written most of the notes. Usually two of them are useless, but the others aren’t.

First couple of days

The first 3 qdays, as I expected, I couldn’t sleep but I went to bed anyway. It was very important to let my body get used to the new schedule by having the discipline to keep to it.

After a few days, it begins to feel like everything is one long day. Usually sleep let’s us “increment the day counter” and complete a day. The border between one day and the next has become vague. For the sake of sanity, I have to accept that the qday is my new measure of time.

I’m teaching myself to relax very quickly so that I can fall asleep easily. The usual relaxation exercises help, but what also works is to pretend that my muscles do not respond anymore. If I keep telling myself that i cannot move my limbs, I won’t move them and they’ll relax very easily.

As time goes on, I notice that I can’t sleep on uneven qdays, but also that I ‘sleep in’ on even qdays. This is already better than not being able to sleep at all. I’m noticing that my body is adjusting.

A week in

After 26 qdays, I crashed. I had had some more exercise than usual and I ended up sleeping for six hours, messing up my entire schedule.

Sleeping in was a setback, but I went to bed at the scheduled time and I adjusted to the schedule again in only two qdays. Again, it was very important to let my body get used to the schedule by staying in bed during the scheduled sleep phases. There were times that I had to stay in bed even when I was not tired, and get out of bed even when I was.

Getting used to the schedule

At this point, time doesn’t feel like one long day anymore. Now it feels like separate (short) days: qdays.

I’m finally getting used to the new schedule and the results are amazing.

I get to do over ten hours of work on a daily basis, or about 3 hours every qday.

I never feel tired anymore.

I fall asleep really easily.

I dream more often and more vividly.

I am able to wake up very easily.

I am usually in a very good mood.

I procrastinate less often.

This last result has a peculiar reason though. Usually when I procrastinate, I think something along the lines of “I’ll do that tomorrow”. Now, “tomorrow” is at most 6 hours away. This is not far enough into the future to remove the stress of the task, so I won’t procrastinate. Procrastination any further into the future will fill like a mess anyway.

Frequently Asked Questions

When do you eat?

Every qmorning I prepare a meal for the qday, which I will be eating bits of throughout the qday. I do try to eat somewhat healthy, but I don’t really make a distinction between breakfast and dinner anymore.

Are you out of your mind?

Yes.

Conclusion

This experiment has been a fun experience, but I’ll be going back to my usual (polyphasic) sleep schedule. It is obvious that it is not possible to maintain a sleep schedule like this one, as well as social life. However, to get a lot of work done in a short amount of time, this schedule is truly amazing. I consider this ‘experiment’ a great success and I will go back to this schedule in the future whenever I can.

I’m in the middle of studying for exams as I’m writing this. This means that I’m in a very particular situation regarding social responsibilities. I don’t have to be anywhere regularly and I can (almost) ensure that I’m not disturbed when I’m studying in my room.

This is the perfect time to experiment with a new sleep behaviour.

A little background.

Most people sleep monophasicly. That means they sleep in one continuous block of time. The average sleeper sleeps around eight hours a day.

Now, I personally don’t know a lot about sleep from a research point of view, but it seems that even researchers aren’t sure of much.

“As far as I know, the only reason we need to sleep that is really, really solid is because we get sleepy.” - William Dement, retired dean of sleep studies, a co-discoverer of REM sleep, and co-founder of the Stanford Sleep Medicine Center after 50 years of research

We’re told that you need eight hours of sleep. While I object to such an arbitrary number, that is also an average, this is said about monophasic sleep. Polyphasic sleep isn’t even considered.

Polyphasic sleep is supposed to be more ‘natural’. That is, if you leave humans without artificial light, they will naturally start sleeping in two (or more) phases.

Polyphasic sleep allows you to rest quicker after ‘energy consumption’ so that you are rested more fully on average. This also means that you don’t need quite as much sleep and you’ll feel more energized throughout the day.

Why we don’t sleep polyphasically

In short, we don’t sleep polyphasically because we don’t sleep polyphasically.

The problem with polyphasic sleep is that your sleep schedule has to be more rigid. You can’t skip sleep phases and you can’t postpone them as long as you can with the one phase.

Our social system is not prepared for this. When was the last time you’ve had time to sleep for at least 90 minutes in the middle of the day? Most of us are ‘stuck’ at work or school without a bed or time to sleep.

There are places where people do sleep polyphasically, for example around the Mediterranean sea. People get up earlier and go to bed later, but they also sleep in the afternoon. Granted, climate plays its role in this situation as well, but that’s not something we can change. These situations are a prime example of how the social system shapes when we sleep.

The ‘experiment’

As I’m studying for exams, I have decided to do a personal polyphasic sleep ‘experiment’. This will not be representative for the average human and it will be highly unscientific. It is more a summary of my experience than an actual experiment. It will, however, be something fun to try out and beneficial if it works out for me.

Please note that I am a somewhat experienced polyphasic sleeper. This is a rather advanced polyphasic sleep behaviour and sleep it is not something to take lightly. Do not try this yourself if you’ve only ever slept monophasicly. If you would like to try polyphasic sleep, I’d recommend a biphasic sleep schedule.

The plan is to sleep for an hour and a half every six hours. For lack of a better term, I’ve started calling it the study-sleeping schedule.

As you can see, my ‘day’ will be divided into four quarter days. I will call them ‘qdays’ and I’ll call the sleep phases ‘qnights’.

At first, this seems like I’m wasting a lot of time sleeping, but keep in mind that this is two hours less than the average sleeper. It also immediately becomes apparent why most people don’t do this (apart from the fact that they’re not used to it). If I had a job or class, I would not be able to do this.

I’ll have two extra hours to spend awake each day. On top of that, I will be able to go to bed sooner after studying so that I can recover energy quicker as needed.

I expect that, at first, I will not be able to sleep during the first few qnights. It will be important to make an effort to stay in bed anyway. I also expect that I will try to sleep too long in some qnights. It will be equally important to get up at the right time.

Interruptions

Internal interruptions: You interrupt yourself. This might happen because you start daydreaming, or because you thought of something else you needed to do.

The first thing you will need to do to start single-tasking is to set up a space where you don’t get interrupted externally. The perfect place would of course be a personal office, but many of us are not afforded that luxury. You can also work in a not-so-private place if you have to as long as you make it clear that, as long as you are working, you are not to be interrupted. A tip is to wear headphones to signal that you’re busy.

Next, you will make it a habit not to interrupt yourself while you’re working. I personally suggest the pomodoro technique to get started. You work for 25 minutes and take a break for 5 minutes afterwards. You exercise your attention by taking note of how many times you were interrupted, both internally and externally. The next time you work, you will try to decrease that amount.

No more mindless browsing

Not everyone works at a computer all the time, but if you do, here are some more tips. I found I used to waste a lot of time mindlessly browsing facebook, twitter, reddit, etc…

The first thing you can do to get out of this (frankly ridiculous) habit, is to put a filter on those websites. Leechblock for firefox and Nanny for chrome let’s you choose when you want to not be able to access a certain website. You could start with limiting your time on the time wasters to a few minutes per hour. Even better. You can make it impossible to get on the time waster-sites during your work-hours. If you care to go a little bit more radical you could just delete your accounts.

Honestly, I can really recommend the last suggestion. Deleting, or even temporarily deactivation your account makes you realise how much you try to access the sites.

Granted, this doesn’t really involve single-tasking if you don’t visit these sites while you’re working, but it makes it a lot easier to start single-tasking.

The problem with windows

The last factor in single-tasking I will touch on, is the problem of windows. I don’t (necessarily) mean the operating system. I mean the rectangles on your screen that contain the user interface of a program. The fact that windows exist makes it ever so easy to start multi-tasking.

To really single-task, you should keep only keep the windows open that you use. Get rid of the chat windows that lurk in your task bar, ready to interrupt you and make sure your work fills the entire screen. (In fact, i recommend getting rid of the task bar entirely.)

The best suggestion I have for that last part is to get a tiling window manager. Of course, as a big Haskell fanboy, I recommend Xmonad.

]]>Sat, 03 Jan 2015 00:00:00 UThttp://cs-syd.eu/posts/2015-01-03-how-to-start-single-tasking.htmlTom Sydney KerckhoveEvery piece of meat I have is the best - Banzanhttp://cs-syd.eu/quotes/2014-12-28-every-piece-of-meat-i-have-is-the-best---banzan.html
[ERT: 47s]

This quote comes from a story in the tradition of Zen Buddhism. It’s the story of Banzan at the butcher’s shop.

Before he became a great Zen master, he spent many years in pursuit of enlightenment, but it eluded him. Then, one day, as he was walking in the marketplace, he overheard a conversation between a butcher and his customer. ‘Give me the best piece of meat you have,’ said the customer. And the butcher replied, ‘Every piece of meat I have is the best. There is no piece of meat here that is not the best.’ Upon hearing this, Banzan became enlightened.

Honestly, it took me a while to get what Banzan understood, because it definitively wasn’t what the butcher meant. I’m guessing the butcher was just trying to sell his meat, but in that moment, Banzan understood something.

The story is trying to explain that no two items are as comparable as we take them to be. Any piece of meat is unique and therefore the best of its kind.

Now, your ambition is probably not to become a great Zen master, but you can still take something away from this story. Whenever you feel inadequate, remember that if you were ‘better’, you would be different and you might not want to be different from what you are now.

I’ve noticed people getting strangely annoyed when they receive an email. They complain about mail being old-fashioned, unhandy, stressful, etc.. When I then look at their mailclient, I see something like this:

Honestly, if that was my inbox, I would be stressed out too. I’ve since been trying to find a way to make an email-system stress-free, organised and efficient.

Getting it out of your inbox

The first step is to start seeing your inbox like you view your physical mailbox. You never leave anything in there. As soon as you get any physical mail, you take it out of your mailbox, and decide what to do with it. That’s exactly what you need to do with electronic mail too.

Even if it’s just to empty your inbox, make another folder called “not-my-inbox” and drag your mail into it once you receive it. At least then, you make a distinction between the mail that you have received and the mail that you’ve already seen, even if you don’t have the time to read it right now. This will make it easier to spot any new information without looking at the mails themselves.

An archive

Next, you need to realise that there is no good reason to ever throw mail away (excluding spam, of course). Storage is cheap, and you never know when you will need ‘that mail you got after dinner at X in 2004’.

Most email providers also provide an ‘archive’ folder where all your received and sent mail is kept. Gmail, for instance, has the ‘All Mail’ folder. However, if you get a lot of mails, this archive might be too small for your purposes.

If you don’t believe that you need an archive, delete all your mails right now and speak to me in a week.

The four new folders

Here’s what I suggest. You create the following 4 email folders and you clear out your inbox into them whenever you receive mail.

Read and Review: Any mail that you still have to read (again) before deciding what to do with it.

Reply: Any mail that you still have to reply to.

Waiting for: Any mail for which you’re still waiting on some other person’s action to continue.

Reference: Any mail that contains information that you might still need in the future, but you don’t have to do anything about.

The system then becomes something like this.

The above flowchart should be self-explanatory.

The entire point of these folders is to make sure there is no mail in your inbox, so that any mail in your inbox is a TODO-item. The mails in your ‘Read and Review’ and ‘Reply’ folders are TODO-items too, but you have already decided that you won’t be doing them right now and it’s not new info.

A final word

I realise that this system is not for everyone. I’m just trying to show you an option.

You might not use email as a communicational tool. You might not use email for work. You might not even use email at all. However, even if you use email on a regular basis and it’s an essential tool for your work, you might not be stressed out by an overflowing mailbox. Even in that case, I argue that you’re better off finding some way to clean out your inbox. Not only can you be more productive, your colleagues might be thankful that you handle email more professionally.

It has been made clear that digital data is not safe. I once had a backup system, but the one time I needed a backup, my backup harddrive failed and I lost all my data.

At university, I learned about RAID systems, but they are too expensive and too cumbersome for my purposes. That’s why I made my own little cheap backup system.

I understood that you need to save data in at least two different locations for them to be at least somewhat safe. I bought two external hard drives with which I built a makeshift RAID1 system. Here’s what I did:

A filesystem

First things first. I plugged in my harddrives via USB, but they’re not being mounted automatically, so need to locate them.

At this point, it’s very easy to use these as a backup system. I just write to the first disk, and copy everything over to the second with rsync.

rsync --recursive /backup/hdd0 /backup/hdd1

I could have the drives mounted all the time, and put this command into a cronjob, but I don’t use my backup system that much, so I just mount the drives whenever I’m making a backup, or restoring one.

Disclaimer: This post assumes a minimal understanding of the Haskell programming language. Some of the code presented will not compile, either because it is already implemented in Haskell itself, or because you might have to add the {-# LANGUAGE InstanceSigs #-} tag to the top of the source file..

Welcome to an alternative monad tutorial. Monads are notoriously difficult to explain. It is said that there is a curse on them.

Once you understand what monads are, and why they exist, you lose the ability to explain it to anybody. – Douglas Crockford

Monads were originally developed in category theory, one of the highest and most abstract branches of mathematics, but they are used in functional programming too. To understand monads yourself, you could jump into category theory and you might even want to do so (I know I did!), but for most programmers there has to be a better way.

Most of the programmers I know, have learned to program, not in a classroom or from a book, but from a lot of examples from different sources. Programmers have gotten really good at (silently) abstracting examples to implement exactly what they were looking for while ignoring most of the surrounding explanation.

I think that most monad tutorials explain monads the wrong way around. They start by defining a monad, and then explain why the concept of a monad could be useful. The ‘inventors’ of monads started out by seeing a repetitive pattern and abstracting that.

That is why I have opted to show you a few examples of monads, and finish by showing you the abstract definition. I will not try to explain monads at all, there are enough bad tutorials to be found online already. You will have to look for the pattern yourself.

Just to make sure you don’t want to learn category theory.

If you understood that, you can go read something else, you’re done. The theory behind this is really mind blowingly beautiful once you understand it. I just want to make sure that you’re not interested, because a well founded understanding of monads from category theory will be much more usefull to a programmer than simply knowing how to use them.

IO is also a monad, but we cannot look at the definition, because that part can’t be written in native Haskell. It is, however, another good example of a monad because it adds side effects to computation. I write ‘add’, because there are no other ways to introduce side effects into a program other than the IO monad.

The abstract monad

To conclude this tutorial, here is the abstract definition of a monad. You should be comfortable with both the return and the bind function by now, and the abstract definition should come as no surprise. The other two functions (>>) and fail are not mentioned in this post.

Your turn!

You’ve seen a few examples of monads, now it’s up to you to write one! I encourage you to write a monad that does nothing but abide by the monad laws. Something like the Useless monad maybe? Next, I would like for you to try using one monad you haven’t used before (so not the IO monad).

Xmonad: an awesome tiling window manager that uses Haskell for its configuration.

Some good monad tutorials

Of course, if you didn’t understand monads before this post, you won’t understand them now. Here are some more monad tutorials. Some of them are not necessarily the first to be found, but all of these are good monad tutorials.

Ever since I wrote about how I love getting up early, I have had people asking how I ever did it. How could I ever get up at 3am when some people only go to sleep at 2am.

I would like to give some concrete tips for anyone that actually wants to get up early. You might not want to get up at 3am, but you may want to get up an hour earlier in the morning, even if it’s just to take a longer shower, or have a more relaxed breakfast.

The obvious tips

Go to bed earlier.

Yes, it’s obvious. No, you don’t really want to. Yes, it’s essential to get up earlier. You might want to ask yourself this question: “At what point in time, do you not do anything ‘useful’ anymore?” It’s very important to note that rest is useful too! For example: after 8PM, I don’t do any work anymore, so have another hour or two to relax and then I go to bed.

Sleep a little less.

Some people actually sleep badly because they can’t fall asleep at night. It is possible to sleep a little less so that you’re actually tired and ready to sleep when you go to bed, rather than either staying awake too long or lying in your bed awake for hours.

Be consistent.

A lack of consistency is the reason that most people don’t get up early. To get up earlier with as much or more energy than before, you have to do it consistently. You can’t just get up earlier once, tired and grumpy, sleep in the next day and conclude that “you’re just not a morning person”. To be honest, you will probably be a little grumpy the first few mornings, but after a few days you will wake up with more energy and more time in your day.

The practical tips

Set more than one alarm clock.

Ideally, you set at least two alarm clocks. This has as a primary purpose to increase the transaction cost of snoozing an alarm. If you set two alarm clocks, and you know that the other one will go off in 5 minutes, you will be less inclined to snooze any of them.

Position your alarm clock to the other side of the room.

This is another way to increase the transaction cost of sleeping in. If you have to get out of your bed and walk over to a table, you will already be on your feet and more likely to get up.

The less obvious tips

Sleeping in one continuous sleep phase is the electric meat of sleep behaviors. Consider going to bed at 10PM, getting up at 3am and getting two more hours of sleep during the day. I personally need less sleep and get more energy if I sleep twice a day, or more.

Sleep multiples of about 90 minutes.

It turns out that humans sleep in cycles of about 90 minutes, of which the first three are the most important. Waking up at the very end of a sleep cycle seems to result in more energy to start the day. When setting your alarm, keep in mind that sleeping for seven and a half hours may leave you more rested than sleeping for eight hours.

Learn to empty your mind.

This is probably the hardest tip to apply, because it requires working on your personal stress. Emptying your mind, however, allows you to fall a sleep quicker and easier. I have gone from lying awake for half an hour to falling asleep in a matter of seconds.

Before you get started

Now, before you start getting up early, you have to have made it very clear to yourself why you are doing it. You might want to take your time to wake up more easily, have a more extensive breakfast or have a relaxing morning walk. On the other hand, you might want to get an extra hour of work done in the morning. In any case, it will be useful even to write down why you are getting up early. In the morning, when your alarm goes off, your brain starts to think of hundreds of good excuses to stay in bed, any of which will sound more attractive than getting up. At that point, you will need to convince your mind that it’s a good idea to get up. I promise, though, that getting up earlier is at least worth trying.

]]>Sun, 16 Nov 2014 00:00:00 UThttp://cs-syd.eu/posts/2014-11-16-how-to-get-up-early.htmlTom Sydney KerckhoveI like offending people, because I think people who get offended should be offended. - Linus Torvaldshttp://cs-syd.eu/quotes/2014-11-09-i-like-offending-people-because-i-think-people-who-get-offended-should-be-offended---linus-torvalds.html
[ERT: 58s]

Ah Linus, perceived arrogant as always. Is this arrogant though? Let’s have a look.

Offended: resentful or annoyed, typically as a result of a perceived insult.

Note very carefully the word ‘perceived’ here. I used to think that there were two prerequisites for a statement to be offensive.

The statement has to be meant as an insult.

The statement has to be accepted as an insult.

Then again, some people even succeed in being offended by things that aren’t meant as an insult at all.

Let’s take complimenting a person on their clothes as an example. Suppose I say to someone “Those are really nice jeans, you’re wearing!”. (I hope you can agree that this is really supposed to be a compliment.)

Now, I think we can equally agree that any person can perceive this as an insult in at least three different ways, for example: depending on where they hear the emphasis in the sentence.

That’s a really nice pair of jeans, you’re wearing!

That’s a really nice pair of jeans, you’re wearing!

That’s a really nice pair of jeans, you’re wearing!

As even a compliment can be perceived as an insult, I have revised my opinion. I now think that there is only one prerequisite for a statement to be insulting:

The statement has to be accepted as an insult.

Notice how this means that you alone are responsible for being insulted.

Back to Linus. With “people who get offended”, I personally think Linus means “people who have a habit of accepting insults”. Is that arrogant?

Yet again have I had an aggravating discussion about the specification of an abstract idea. The discussion involved a simple math problem. The specification of this problem is a little long to be practical for this post, so I will simplify the description without loss of generality.

John owns five apples.

Anticlimactic, right? How could anyone have a discussion about this simple sentence?

Let’s get started

One of the principles of solving a math problem is to assume that what is given, is true. It might not be true that John owns five apples, but that is not relevant to the case. We will assume that it is true, and look at what we can learn from that.

The next assumption is called the law of excluded middle, which simply means that a statement is either true or false. There is nothing in between. This means that an apple is either owned by John, or not owned by John. Note that when we don’t know whether something is true or false, there is still no third option.

We will assume that apples are indivisible, and that there are no negative apples. Let \(x\) be the exact amount of apples that John owns. This means that \(x\) is a whole number greater than zero.

From here on, we will find a range of values for \(x\) so that the original statement still holds. Are you still with me up to this point…? Yes? Good.

Some questions

Question: Does John own an apple?

Answer: Yes. John even owns more than one apple.

Question: Does John own three apples?

Answer: Yes. John even owns more than three apples. If you disagree here, imagine that John has to pay three apples. Would he be able to do so? Yes, exactly.

Question: Does John own six apples?

Think of your own answer. If your answer is “No, John owns five apples, not six”, then imagine, for a minute, that John does own six apples. Would you say that John owns five apples, now? Yes, exactly. If John owned six apples, you could also say that he owned five apples. This means that we really don’t know whether John owns six apples or not.

Answer: Maybe.

Are you still with me? Hang in there!

The interval

Back to \(x\). If \(x\) is strictly smaller than five, then the statement “John owns five apples” is false. If \(x\) is equal to five, the statement is true. And now for the interesting part: If \(x\) is greater than five, the statement is …. true, exactly! We can now write down an interval for \(x\):

\[ x \in [5,\infty[ \]

There is a hidden ‘at least’ in the original specification. If it were more explicitly clear, then it would say something like this:

John owns at least five apples.

The amount of information in this new statement is exactly the same as the amount of information in the original statement. That is to say, in every case where this statement is true, the original statement is also true, and vice versa.

\(x\) does not simply equal \(5\). If we wanted to specify that John owned exactly five apples, no more and no less, then we would have to rewrite the problem specification:

John owns exactly five apples.

The amount of information is this statement is greater than the amount of information in the original statement, so we can’t just replace the original one by this statement.

Are you still following along? Great!

Frustrations

You might agree with me here, and I would congratulate you, but you might as well have flipped a table somewhere along this post. The entire point of this post is to show that you have to be really careful with the information that you have, and be sure not to add any extra information.

I have to agree that in reality, there might be extra information in the context of the situation. Saying “John owns five apples” might mean something different. The context may imply that this statement means that there are zombies coming, but then extra information is required to ‘encode’ that statement.

I have flipped many a table myself trying to discuss this subject. Of course that’s one of the reasons that I wrote this post. I sincerely hope that this post aids me in decreasing the frequency of table flipping on my part.

]]>Sun, 02 Nov 2014 00:00:00 UThttp://cs-syd.eu/posts/2014-11-02-the-hidden-at-least.htmlTom Sydney KerckhoveThe less you do, the more of it you can do. - Scott Hanselmanhttp://cs-syd.eu/quotes/2014-10-26-the-less-you-do-the-more-of-it-you-can-do---scott-hanselman.html
[ERT: 42s]

He argues, as so many do in recent years, that we try to do too much simultaneously. We shouldn’t multi task. Even worse, there is no such thing as multitasking. There is only single tasking and context switching.

Suppose your life’s work is composed of projects. Let’s look at these projects as an abstract (not-necessarily strictly defined) amount of work. The maximum average amount of work you can put into every project is inversely related to the amount of projects you have running. As a simple illustration, here is a plot of the maximum average number of hours you can put into your projects in function of the amount of projects.

If you assume that the amount of hours you put into any project is at least somewhat related to the quality of the result, then it’s easy to see how having less projects in your life is beneficial your life’s work.

Personally, I just love how this explains why some people can do nothing, infinitely.

I used to enjoy reading books. Nowadays, I don’t enjoy reading books enough to take time out of my day to do so, but I would really enjoy reading books if I had more time. On the other hand, I am taking time out of my day for some other things that I don’t enjoy.

I have found a way to still read books, while making otherwise unenjoyable time enjoyable and educational. Allow me to show you the magic of audiobooks.

Time spent on virtually useless necessities

The main unenjoyable part of my day is commuting. I don’t like ‘transporting’ myself. I can’t bring any value to anything while riding a train, a car, or a bike. Moreover, commuting is something that I call a ‘brain-dead task’.

It is frustrating to realise that I have to spend time on brain-dead task while I don’t have enough time to do some of the things I would actually enjoy. I started looking for a way to combine a brain-dead task with something enjoyable.

The first thing to note is that during most of commuting, your hands might not be free, but your mind is. You could, of course, listen to music and that would certainly be enjoyable, but that still isn’t productive yet.

The concept of an audiobook

An audiobook is a recording of someone who reads a book aloud. Listening to an audiobook doesn’t require your hands to be free, but you should be able to focus on the book. You could even make sure that you don’t disturb anyone else by using headphones.

People usually read quicker than an audiobook is read, as an audiobook can only be read at speaking rate. Then again, listening to a good speaker is sometimes more enjoyable than listening to the little voice in your head.

Perfect complements

As it turns out, listening to audiobooks is perfectly complementary to commuting. You can do both, with minimal loss of accuracy on either.

Where to get audiobooks

If you’re the person who likes to read non-fiction, (auto)biographies, and other informative books, Librivox.org is the place to go to. Librivox.org contains books in the public domain that are read by volunteers. They are free to download.

Audible.com is the place to go to for any other kind of audiobook. Audible is to audiobooks as amazon is to books.

And now for something completely different. I’d like to dedicate a post to my lovely girlfriend: Thalia.

I won’t go into how incredibly attractive she is, on any level. Although that subject could fill entire books on its own, I feel it would be inappropriate to discuss it here. Neither will I go into all the little quirks that I love about her, like the way she smiles when she gets nervous. In this post, I will try to explain what makes her such an amazing person, as a way of showing her my appreciation, as well as encouraging everyone to dare to step outside of the norm.

Peer pressure

The first aspect of Thalia that I find admirable is that she doesn’t simply conform to what people expect of her. She will not apologise for being herself, nor will she pretend to be someone else, just because it’s easier to do so. I hope - and I imagine she does too - that she can serve as an example for people to be the best they can be.

Adventure

The reason I’m writing this here, rather than just telling her how amazing she is in person, is that she is currently at the other end of the world. Thalia has always had a knack for adventure. She studied in Valencia, Spain for five months in her third year at university. Somehow, she managed to learn to read, write and speak Spanish fluently by the time she got back. Now, she is in Cuenca, Ecuador at an internship for the university, working on the improvement of citizen participation and neighberhood development.

Morals

Morals and values had always baffled me. I could never understand why anyone would want any. They haven’t confused her though. She is the only one I know with such high moral standards without ever failing to meet them herself. Furthermore, she won’t impose any of her moral standards on anyone who minds his own business.

Only to give an example of one of those moral standards: Thalia has an absolute zero tolerance for prejudice. She hasn’t accepted, nor will she ever accept, any racism, sexism, or any form of discrimination for that matter.

Good

As you might imagine, I am absolutely crazy about this girl. She is the most worthwhile, thoroughly good person I have ever met. She has inspired me to be a better man, a better person, a better leader. I wish her, and anyone who wishes to follow her example, the best of luck and a life of great fulfilment.

I’ve been looking for a nice way to word this, but there’s really isn’t any way to say it nicely. Altruism doesn’t exist. Some people will already agree with me here, others will automatically be offended. Allow me to explain why altruism doesn’t exist, why that’s a good thing, and how this knowledge can benefit you.

Another confusing definition

First of all, let’s define altruism, as that will clear up half of the confusion in discussions on this topic.

This is what Google says when you ask it to ‘define altruism’.

Altruism: disinterested and selfless concern for the well-being of others.

Wikipedia:

Pure altruism consists of sacrificing something for someone other than the self (e.g. sacrificing time, energy or possessions) with no expectation of any compensation or benefits, either direct, or indirect (e.g., receiving recognition for the act of giving).

For the sake of argument, it’s important to include in the definition that in true altruism, there is no expectation of any compensation. In what follows, I will use Wikipedia’s definition because it is more specific. Note that these two definitions are not mutually exclusive, wikipedia just goes into further detail.

It’s small, but it’s there.

The reason I argue that there is no such thing as true altruism, is that you will always expect a compensation. You won’t necessarily expect a compensation consciously, but our bodies have evolved to expect a compensation down to the biological level. The nice feeling you get after an act of ‘altruism’ is a compensation. Even if there’s nothing more, at some level, you definitely expected that feeling.

It is of course possible to perform an act of selflessness without expecting or wanting external compensation. One could argue that such an act is rare, but that is not the topic of this post. I could agree that altruism exists if we exclude the expectation of internal compensation from the definition, but that is also not relevant to this discussion at this point.

Even if you still believe that pure altruism exists, I hope that we can agree that it is rare and that, for all practical purposes, we can assume that people are generally egoistic. By egoistic, I here mean that they will value their own benefits above others’ (except perhaps in the case of their children). This too, is evolutionary advantageous.

Wait, that is a good thing?

Years ago, at school, one of my more cynical teachers said the following:

If everyone would think of themselves, everyone would be thought of.

Of course, this sounded so cynical at the time that most of simply chuckled and went on with their respective thoughts. I’m quite sure this was indeed intended as a joke. Surely humanity would not benefit from people who only valued their own goals, … or would it?

I am convinced that valueing your own goals, above anyone else’s, can be of immense benefit to everyone else, especially if that were socially accepted. Before you stop reading, I ask you to allow me to explain what I call ‘intelligent egoism’ as opposed to ‘blind egoism’.

Predictability

The first reason this way of thinking would be beneficial, is that people would become more predictable. Predictability is a great part of trust, as well as clear communication.

If people valued their own goals, they would not solely rely on others to reach their own goals. If you could rely on the fact that people don’t simply expect that you fulfil their goals for them, that would make them more predictable.

Predictability also allows for more efficient communication. As long as goals are clear, you could rely on logical actions from any other party to plan your own actions.

No mutual exclusion

The offence that some people take from my teacher’s quote stems from the assumption that personal goals, as well as the path to them, are mutually exclusive or even opposite. While it is indeed possible that two people’s respective goals are complete opposites - even though I argue that such a situation is rare - it as almost always possible to align the paths to the respective personal goals. This argument definitely requires an example. I will give a rather trivial and concrete example, but once it is clear, it will be very easy to abstract that idea to a more general situation.

Suppose Fred’s life’s goal is to become rich. Fred will have to find a way to make money. Fred finds out that he has a knack for communicating with people. Fred has studied communication at his local university and is currently a communication trainer for a big company. Now, his original goal was to make money, but Fred figured that in order to make money, he must generate value using his personal skills. He therefore has to be good at his job and sets himself a new sub-goal to be a great communication trainer. In return, Fred is paid for his services.

Now, let’s look at John. John has always wanted to be a great leader. He started to work at a big company last month, and is now a low ranked manager. John struggles to work his way up the corporate ladder to become a chief executive. One day, he realises that his lack of communication skill are preventing him from doing so. John then goes on to find the company’s communication trainer. He pays for the communication training and becomes a better leader over time.

As you might have imagined, Fred is training John and is making money in doing so. Both Fred and John will eventually go on to reach their personal goals, while still valueing their own goals primarily.

It is important to realise that both Fred and John had to value each others’ goal to reach their own. However, they would never have done so, if they hadn’t been focused on their own goals. This is why I claim that intelligent egoism is of more value to mankind, than blind ‘altruism’.

A new sense of responsibility

Realising that altruism doesn’t exist allows you to be responsible in a whole new way. You alone are responsible for achieving your own goals. The universe doesn’t owe you anything, nor does anyone else. As harsh as this may sound, there is definitely a good side to it.

In your life, there will be times when you get to decide the rules of a certain social system. It could be the way your peers talk to you or it could be a transaction with a client that you’re meeting. You can set up the system so that when the other parties strive to achieve their goals, your progress is advanced simultaneously. Such a system would easily reinforce itself by positive feedback.

Suppose a social system exists where everyone relies on each other to achieve their own goals. Such a system would collapse as soon as one person fails to help an other. The person who doesn’t get any help, would become selfish and keep any of its resources to itself.

On the other hand, imagine a system where people only rely on theirselves. People would have to help each other to achieve their goals, as working alone could never get you as far as cooperating. In this kind of system, if one person fails to help himself by helping others, the system would still stand, as the other people would just go look for help elsewhere.

Intelligent egoism is simply a case of moving the equilibrium to a beneficial strategy.

It is your responsibility to make sure that achieving one’s goal at the expense of, rather than by alligning their goals with the goals of other parties is detrimental to their success. You achieve this by organising the social systems you control such that blind egoism goes unrewarded. There is no use in forcing people to cooperate. We can, however, give them an incentive to cooperate.

You are, by extension of your own purposes, not only responsible for achieving your own goals. You are also responsible for any cooperations you take part in.

]]>Sun, 05 Oct 2014 00:00:00 UThttp://cs-syd.eu/posts/2014-10-05-altruism.htmlTom Sydney KerckhoveChange the way you use your terminal use with this functionhttp://cs-syd.eu/posts/2014-09-28-change-your-terminal-use-with-this-command.html
[ERT: 1m35s]

I am a great fan of using transaction costs to improve your life. Using a terminal instead of a graphical interface has a high transaction cost for most (beginner) linux users. In this post, I will show you a way to reduce the transaction costs of using your terminal with one function. A basic understanding of aliases is assumed.

ls -whatever

If you look through the .bash_history file of most (beginner) linux users, you either see nothing at all, or something like this.

cd path
ls -l
cd to
ls -l
cd files
ls -l
<some_command>

The user executes ‘ls’, with some option(s), after every ‘cd’. The first thing you can do, is abbreviate this ‘ls -l’ to something shorter. Here’s an example of a set of ls aliases

This ‘l’ alias lists the current working directory in long color format with human-readable file sizes, a better time-style and with the directories before the files. It also sorts entries by extension instead of by file name. There’s no harm in using the long options. In fact, using the long options instead of the short ones makes the aliases easier to read and to modify. Since the entire purpose is to not type the entire command, but to put it in an alias file, this is the handier option.

cdls

If you look at the bash history again, you will see that most (beginner) users execute ‘ls’ after every successful ‘cd’. I will now show you how you can do that automatically.

This was my personal first attempt, but it won’t do.

alias cd='cd && ls'

Using this alias will cause you to go back to your home directory and list it every time.

Instead, you will need to use a function. Again, there’s no need to make this code short. It just has to be readable.

You can just put this in your .bash_aliases (, or even your .bashrc file).

The most used command used to be at least six characters long. Now it’s no more than three charactes long and you can add any number of options to your regular ‘ls’. Not only will this trick save you a lot of time, but it will encourage you to use your terminal more often. Of course, if you still don’t want to use your terminal, that’s fine, but this way, it will at least be easier.

After countless hours of discussions, arguments and even fights, I have realised that many of those would never have been necessary if we had defined the words we were using beforehand. The amount of confusion that has arisen from simply having a different understanding of what specific words mean is enormous.

I started thinking about how this issue could be resolved elegantly, or even at all. The next discussion I engaged in, I specifically asked my conversation partner what (almost) every word they used, meant. No longer than 5 minutes later, they got annoyed. Then, they said this: “I can’t tell you the definition of every word. You can’t possibly expect me to know the dictionary by heart!”

I was at least a little surprised by their reaction. Of course no one should be able to recite the dictionary by heart. This was entirely not what I meant!

Back to the basics

Since we even had a different understanding of the word “definition”, the next obvious thing for me to do was to look up the definition of the word “definition”.

A statement of the exact meaning of a word, especially in a dictionary.

Now, we can’t just assume that these definitions are ‘correct’ - by which I mean “commonly accepted” - but they do seem quite correct. These answers are, however, a little vague with respect to the implications of a definition, or how exactly a definition works. Any person, in my not-so-humble opinion, should thorougly understand the concept of a definition. What follows is my attempt at defining a definition.

The definition of a definition

When you say “I define X as Y”, that is exactly the same as saying “I’m going to talk about X and when I do, what I mean by ‘X’ is ‘Y’”.

That is it. There’s nothing more to it! You can take this quite literally too, I might add.

For example, when you define “\(2\)” as “\(0+1+1\)” as Peano did, every time you use “\(2\)”, you could replace it (quite directly) by “\(0+1+1\)”. As you might imagine, defining “\(50\)” in an analogous manner could reduce the amount of space and time you’re using significantly. If we look at definitions in this way, they exist purely for the sake of efficient communication. (Oh, the irony!)

This also works for non-mathematical purposes. Depending on your interests, this is where definitions become interesting on their own.

The most common miscommunication I have personally experienced, stems from a different definition of the world ‘always’, so I will use it as an example. Some may define ‘always’ as ‘in every single instance, without any exceptions’. Others could define ‘always’ as ‘in most, useful instances’.

As you might imagine, this leads to all kinds of confusion and frustrations. It is exactly why we should understand definitions.

Considerations and misconceptions

Somehow, some people seem to get offended by this concept. It seems as though they enjoy the ambiguity, even if it causes these miscommunications. These are some of the misconceptions about definitions.

“Your definition is wrong! ‘X’ is not ‘Y’!”

You might have noticed that, up until now, nothing has been mentioned about the truth. That’s right. Definitions don’t have anything to do with truth. There is no such thing as a wrong definition. When you define “\(1\)” as “\(2\)” - which you certainly can - you’re not saying “\(1\)” is “\(2\)”, or that it’s true that “\(1\)” equals “\(2\)”, but rather that you mean “\(2\)” when you say “\(1\)”. Whether a definition is useful is an entirely different question.

“Of course you know what the words mean, how could you not?!”

People usually get agitated when you ask them to define a word they’re using. They find it annoying to have to specify something ‘that is just so obvious’. It’s important that they realise that asking them to specify what they mean is not meant to be annoying, but rather as a show of interest. In fact, simply accepting a difference in definitions can then be viewed as annoying, or even malevolent.

As a practical tip, you could say something like this to make sure you’re not misunderstood.

I don’t mean to be annoying, but I just want to make sure that I understand what you mean. Could you please specify what you mean by “X”?

“If you just keep on defining terms, you can never even start talking!”

In a way, this is indeed correct. The trick is to find some common ground on which you can agree on some definitions, and build your way up from there. When you have practiced defining the terms you’re using, it becomes easier to talk to other people who have done so too. Note that you are not required to use the same definitions every time you’re talking, as long as it is clear what you mean.

I really hope it is clear why it is so important to understand definitions, as well as why it is important to use them correctly. It should be equally clear that you aren’t stupid when you ask for a definition, but rather a worthwile conversation partner.

I stumbled upon this wonderful quote while reading the autobiography of Benjamin Franklin. Allow me, for a moment, to write a little fuzzily.

I think this really is one of the more optimistic quotes I have ever read. Getting wet from rain can be a little uncomfortable at times, but really, as long as you can huddle together, it can make for an amazing moment.

“As wet as water could make us” is a beautiful way of saying that they were really wet, but that that wasn’t so bad. Even more fuzzily: Really, water can only get you so wet. There are way worse things in life and I find this an eloquent way of phrasing that.

This is not a short introduction to git. I will not explain what git is, what it does or how to use it. This is a post for anyone who wants to learn git, and doesn’t know where to start. Note that a basic understanding of version control is assumed.

To learn something quickly, you will want to learn from different sources. Keep in mind that you will still need about 20 hours to learn git to a level that allows you to collaborate with other developers. If you’re going to be a professional developer, these are going to be the best spent hours of your entire education. I personally recommend starting a small personal project with git.

Resources

If you look for resources for learning about git, you will probably find the following ones in order. The order in which you find them, however, is not the order in which you should look at them. Here’s why:

Scott Chacon wrote a beautiful book about the workings of git: Pro Git This book explains every part of git in depth. I like it as a manual, but for first use, I’d recommend against reading this entirely.

Ah, tutorials, the bread and butter for any programmer… These tutorials try to visually explain what git can do for you. They are made for developers who are coming to git from subversion, but they’re made very accessible to anyone. The drawback to the approach of these tutorials is that you should already know why you want to use git before reading them.

If you ever need to find the exact syntax and semantics of a git command, this is the place to go. The same information can also be found using the ‘man’ command. The reference documentation is great once you know how git works, but, for now, focus on understanding how git works, rather than on how you should use it.

Torvalds made the first version of git. In this talk, he explains why you, as a developer, should be using git. In his usual sarcastic way of talking, he also explains what was wrong with the version control systems before git, and how git improved on them. This is, in my not-so-humble personal opinion, the best place to start.

Knowing why something works, rather than only knowing how it works, is essential to truly understanding it. In the case of git, someone wrote an article on the inner workings of git at the conceptual level. You can use git without ever reading this, but you will want to, when you get familiar with the tool.

Beginner pitfalls

There are some things that you shouldn’t ever do with git. Some of these things are very common mistakes for beginners

Working without a development branch (or working without branches at all)

Working with branches is what makes git so powerful as a tool. Branches allow you to develop a feature separately from what the other developers are doing. They also allow you to have a stable branch (usually master) where everything is (semi-)guaranteed to work, and a development version that might be unstable. Lastly, branches allow you to really play around with an idea. The power to use branches gives you an incentive to be creative.

Committing binaries

Git is made to manage changes in source code at the granularity of lines. This works because these changes are often really small compared to the size of the entire file. Binaries don’t use lines, and they often change entirely when you change a small part of the code. Committing binaries will give you a lot of potential merge conflict, and headaches as a result.

Committing IDE configs

IDE setting are specific to your setup. If more than one person commits their settings, the team will be merging these manually constantly. Examples of these include eclipse’s ‘.metadata’ directory, as well as IntelliJ’s ‘.idea’ directory and netbeans’ ‘nbproject’ directory.

Not using git ignores

Thinking about which files not to commit becomes cumbersome. There are ways to have git automatically ignore certain files. At the level of the user, you can configure git to only ignore the files you never want to commit, like IDE configs. At the project level, you can ignore files on a per repository basis. This is useful to exclude binaries and such.

Not committing often enough

Some beginners are concerned with ‘wasting’ something by committing too often. They end up committing only at the end of their work session, which makes for a horrible git history. Encapsulating commits nicely is essential for easy merging.

You will want to look at the gitignores repository for more specific gitignores. You will want to add more of these ignores, specific for your workflow. For example: If you’re using eclipse to build a java application, add the specific eclipse and java ignores from the gitignores repository.

Aliases

When you start using git from the command line, you will notice that the commands you type are too long, compared to their frequency of use. I have written some aliases for git commands that I use most often. You can just put them in your shell’s aliases file.

I have always thought this was a beautiful call for tolerance among ‘smart people’. By ‘smart people’, in this case, I don’t mean actual smart people. I mean people who fancy themselves so accomplished that they need not learn any more, especially from other people whom they deem intellectually inferior.

This is a reminder for all the ‘smart’ people. The communicational barrier that you experience when talking to people you think are ‘less intelligent’ is felt in almost the same way at the other end. You can, however, take the responsibility to improve this communication by opening your mind for what you can learn from any single person. Once you get into this habit, you might enjoy these conversations orders of magnitude more than before while exercising your patience.

The difference between statements and expressions is very important, but it is considered trivial and therefor never explained in class. As with most of these ‘trivial’ concepts, I found this too important and too beautiful to be left unexplained.

Statements and expressions are both strings of characters, but they have an entirely different meaning. This post is dedicated to the semantics of these kinds of strings and the beauty that you can find in this knowledge as a programmer.

Expressions and Mathematics

Expressions are a way of talking about a value. They represent a value, or, in other words: Expressions are something. They don’t, inherently, do anything.

In mathematics, there only exist expressions. Some computation might be required to determine the value, but the expression represents the value rather than the computation. Examples of expressions are the Boolean values: True and False, numbers: \(5\), \(\pi\), collections: \(\\{\)’A’, ‘x’, ‘f’\(\\}\), functions, etc …

Statements and Programming

Statements are a way of saying what to do, or, in other words: Statements do something._ Statements don’t, inherently, have a value. They might, however, provide a value through computation.

Examples of statements are: the increment statement …

i++ # Java
inc <register> # Assembler

or a more complex statement that you’ve defined yourself:

robot.shoot()

As programming is a way of telling your computer what to do, at the lowest level in programming, only statements exist. It’s true that, in higher programming languages, expressions do certainly exist, but at the machine level they don’t. One might argue that the operand to an assembler statement can be seen as an expression, but that too is just a way of telling the computer which bits to set.

The bridge

As a programmer, you might try to implement a highly abstract idea like an application to connect with people, or a program to solve some complicated puzzle. The idea is often so abstract that it can only be described in some branch of mathematics, or a natural language. What you’re describing it the abstract value that this program would have to you, in expressions.

Now, as there are only statements in programming, your program will have to produce that value through the use of statements. Of course, few people still only code with statements in assembly. Higher languages have been developed that allow you to talk about expressions (to the computer) in a less minimal manner. Compilers have been written so that a programmer may tell the computer what to do at a higher level. Sometimes, these tools become so immensely complex, that the programmer can just tell the computer what he wants it to do without also telling it how to do it.

As you can see, the difference between an abstract idea and a concrete implementation couldn’t be greater. Two arrows are drawn. The topmost arrow is an illustration of the inherent difficulty of implementing an abstract concept. The more abstract (higher), an idea is, the more difficult it is to implement it. The bottom arrow represent the efforts that programmers make to make a developer’s life easier. Programmers have tried to make it as easy as possible to talk about ideas with computers.

As a programmer, your work forms the bridge between some value that you want to obtain and the implementation that’s going to get you there. You form the bridge between expressions in mathematics and natural language, and the statements in the machine you control. Realising this, I found a new powerful, beauty in programming and new courage in the late hours when I’m trying to fix that last annoying bug.

This is a lesser known quote from the first inbetweeners movie. It is a good example of the fact that not everything that sounds clever is clever. Of course what Neil says, is true. If you reverse the word “dog”, you do indeed get the word “god”. “G - O - D … D - O - G …”, as he goes on to explain, was a revelation that allowed him to stop worrying.

In fact, the entire scene is worth watching, but I couldn’t find it anywhere online. An entire speech follows after this quote where Neil explained how he became very happy when he stopped worrying about things. The first question that came to my mind after I was done laughing (and I laughed way too hard at this), was the following:

What exactly, about this person's statement, train of thought and view of the world, is different from the statements and trains of thought that we applaud?

I have pondered this question for a while now, and I’ve come to a worrying conclusion. There are a few things to consider.

To use the words of a fellow inbetweeners fan: “He just really sounds like an idiot.”

What is a revelation to Neil, is obvious to most people. “god” is indeed “dog” backwards, but nobody bothered to think about that.

This consideration, in itself, is fine, but it doesn’t mean that there is nothing more to learn from the statement. In the case of this quote, the entire train of thought that you’re now reading started after some reflection on my own prejudice.

It seems that general prejudice about the way someone sounds when stating his opinion is far worse than it could be. This means that if you have something important to say, you already have to know how to convey your message, otherwise you might as well have nothing to say. Lots of valuable information could be aggressively contained in the minds of people who haven’t found a way to effectively communicate that information through the walls of our prejudice.

I recently bought a “Truly-Ergonomic Keyboard”. It’s an ergonomic mechanical keyboard designed to be comfortable and efficient. At the same time I started to switch to a Dvorak keyboard layout. Notice how I wrote “started to”. I have already spent 10 hours trying to relearn how to type and I foresee many more of those hours.

The qwerty keyboard layout was designed to make sure that the typewriters of the time jammed as little as possible. This meant that the most commonly used keys were placed as far apart as possible. Obviously, this is exactly the opposite of what you would want in order to type quickly. The Dvorak layout, on the other hand, is specifically designed to make it easy to type quickly and comfortably. Together with an ergonomic keyboard, this should form a perfect keyboard setup.

I used an online tutorial to learn to type on a dvorak keyboard layout. This tutorial does a good job teaching you letters two by two, instead of a whole row at a time, as most other practice tools do. When I can type all letters adequately, I will switch to GNU’s gtypist as that tool focuses best on accuracy in typing, before focusing on speed. I will use an online test to test my typing speed as I progress.

The first few hours I spent teaching myself a completely new layout were spent on learning the home row keys. All vowels (except the ‘y’) are on the home row of the left hand (A-O-E-U-I). The most commonly used consonants are on the home row of the right hand (D-H-T-N-S). This way, as opposed to on the qwerty layout, you can already type a lot of words with only the letters on the home row. I personally found the ‘I’ and ‘D’ keys the hardest to learn because they are on almost the opposite position from on the qwerty layout. It helps to remember that all vowels are under the left hand.

After ten hours of deliberate practice, I can now type with all letters, at 20 words per minute. Keep in mind that, on a regular keyboard layout, my typing speed was around 70 words per minute. I have set my wallpaper to a picture of my current layout for temporary reference, but I still switch back to a regular layout when I’m not practicing.

I actually wrote this post on a dvorak layout. As a result, it took me three times as long as any other post.

I will post an update as soon as I’ve reached my typing speed goal of 125 words per minute. In the mean time, I urge everyone who types a lot to both buy an ergonomic keyboard an try the dvorak layout for a while. The ergonomic keyboard reduces wrist and shoulder pains while typing on a dvorak layout is more comfortable in general.

If you’re in trouble anyway, you might as well have fun! Life has its ways of getting you into a bigger mess than you could imagine. If you don’t, somehow, find a way to enjoy that, your life will be miserable anyway. You can, of course, enjoy this part of life, but it will require some effort.

If you’re currently down, I challenge you to take another risk. If it works out, you’re already on your way back up. If it doesn’t, you’ll probably have a smile on your face, and a crazy story to tell. Hopefully you will enjoy yourself in any case.

During my time at the university, I discovered the concept of “thinking paper”. I’ve shared this idea with everyone I’ve worked with ever since, and now I want to show you.

In the first year at the university of Leuven, everyone was given a goodie bag. In this goodie bag, there were the usual things, a map of the city, lot’s of informational flyers, etc… The goodie bag also contained a clipboard. It is with that clipboard that this whole idea started.

The basic idea

Thinking paper is just paper on a clipboard that you always keep around you when working. Anytime you’re thinking about anything creative or technical, use the paper. You could write things down, or you could draw things, but the real magic comes from being able to extend your thoughts to the paper

The magic

Thoughts on paper are useless to anyone who isn’t the author of them, simply because they wouldn’t know what the writing meant. They are no more useful to anyone else, just like thoughts in someone else’s mind.

To the author, however, thoughts on paper that they understand can be of great value. Thinking paper tends to work like a programmer’s rubber duck. You get to explain your thoughts to some other entity (that happens to be you too) through the paper and get feedback on them.

Secondly, thoughts on paper last. You look back at the paper whenever you need to. Be warned. The longer you want to keep the thought on paper effectively, the better the though has to be written down. By “better”, I don’t necessarily mean more detailed. I simply mean “easier to re-understand from scratch again”. The mind forgets. It doesn’t only forget the thought, but it also forgets the semantics of how you wrote it down.

More magic

Using thinking paper when working alone is fine, but it works even better when you don’t work alone. You can’t just share your thinking paper, the other person probably won’t understand any of it unless you explain what you draw. If you work together, keep your thinking paper at hand. You will notice that, just by holding a pen next to your paper, you will start to write things down or to draw. The paper then provides a visual clarification of the thought you’re trying to convey.

In this case, it’s a poor man’s whiteboard. However, I argue that it’s even better than a whiteboard if you’re working in a team of less than five people. The transaction cost of writing on paper on a clipboard is much lower than that of writing on a clipboard with dry-eraser markers that are rarely even there. People rarely write on whiteboards, which means that they are usually not comfortable writing on a vertical platform.

Making your own thinking paper.

Thinking paper is not much different from regular paper, but it has some unique properties.

Thinking paper is mobile.

You should be able to carry your thinking paper with you anywhere. This is why I discovered the concept thanks to the clipboard. I could bring my entire stack of papers with me in an instant and share my thoughts easily.

Note that you can ‘implement’ thinkink paper in other ways. You don’t have to stick to a pen, paper and a clipboard.

The paper is plentifully available.

Just having one piece of paper on your clipboard doesn’t do it. You need to be able to throw away a dozen sheets of paper without running out. If you can’t just write down anything you think of, you will unconsciously try to save the space you have left. This will inhibit your creativity, as you only want to write down ‘the good stuff’. You don’t just get good ideas, you have to get a lot of ideas, and filter the good ones out.

It is readily available.

You won’t write anything down if you don’t have the paper in front of you and the pen in your hand. You need to be able to start writing or drawing as soon as you start thinking. The writing should be done while thinking, not afterwards. Everything should also be ready before you start. Don’t go asking for a pen because you happen to have forgotten yours and interrupt your thinking in doing so. Carry some spares.

It is easily usable.

The pen you’re writing with should be comfortable. Different pens make you have different ideas. This may sound weird, but try taking notes with a fancy pen instead of a pencil stub, and you’ll notice. The paper you’re writing on should be fixed, so that it doesn’t slide away. Don’t just write on loose sheets of paper as that causes all kinds of problems. The paper should be supported, so that the writing can be steady. This is where a stack of paper comes in handy again. writing on a sheet ontop of wood usually causes less readable text than writing on a sheet ontop of a stack of papers.

Again, a clipboard provides the perfect environment for this, but you can make it work in other ways too. Some people use a text editor for this, but I’d recommend against this, because in a text editor you can’t mix drawings with text easily (although emacs probably has a mode for this somewhere).

Einstein was both religious and a scientist. He was convinced that the universe is based on deterministic laws. Quantum mechanics, however, tells us that the universe is governed by probabilistic laws. With whatever amount of knowledge about the present, or the past, we still can’t predict the future

As a religious person, Einstein believed that God is all-knowing. When he found out about this probabilistic nature, he said: “God does not play dice.”. He got angry. He never accepted any of the philosophical interpretations of this concept, but he still contributed to the field. This can be looked at in a number of ways, but these are the two that I suggest:

As Einstein lived in the twentieth century, in a time where being a scientist was frowned upon already, he can be viewed as an example of how religion and science can coexist.

Imagine what kind of scientists we have missed out on due to people’s lives being controlled be religion. Imagine what could have been discovered or invented if people weren’t punished for saying anything that isn’t consistent with the bible.

I use Linux on multiple systems. I want to share some config files across my systems, and use some config files only for specific systems. I made the Super User Stone for precisely this purpose. You can find the source on github available for use.

In this post, I will show you how to synchronise and back up your dotfiles with the Super User Stone.

Your dotfiles

If you’re a linux user, you probably at least have a ‘.bashrc’ and a ‘.bash_aliases’ file in your home directory.

/home/user
|- .bashrc
|- .bash_profile
|- ...

I will now show you how you can backup and synchronise these files on multiple systems.

The sus depot

The first thing you will need is a SUS depot. This is a directory with all your dotfiles. It is structured like this:

- depot
|- shared
|- hostname1
|- hostname2
|- configurations.sus

In the shared folder, you put all config files that you want across all file systems. For every system, you make a directory named after the hostname of the system. SUS uses the config file in the host name directory if it exists. It uses the shared config file otherwise.

In this example, both the bashrc and the bash_aliases file are deployed. On the ‘laptop’ system, the bash_aliases is deployed from the laptop folder instead of the shared folder while the ‘bashrc’ file is deployed from the shared folder. On any other system, both files would be deployed from the shared folder.

The .sus file

The Super User Stone need to know where to deploy the config files to. This is where the ‘configurations.sus’ file comes in. It is just a text file and it is structured as follows:

[<destination directory>]
source_file_name: destination_file_name

In the example above, the ‘configurations.sus’ would look like this:

[~]
bashrc: .bashrc
bash_aliases: .bash_aliases

In this case, the complete deployment happens like this (on the ‘laptop’ system).

How to synchronise and backup your depot

Now that you’ve set up your SUS depot, you can synchronise it. There are a few options for synchronisation.

Git(hub): Put your depot in a (private) repository. This has the advantage that you keep all history. The disadvantage is that you have to commit, push and pull the repository whenever you change a config file.

Dropbox:
Put your depot in a folder in your dropbox. A dropbox comes with the advantage of instantaneous synchronization but you might have to deal with synchronisation conflicts.

Bittorrent Sync: This is a newer synchronisation program. Bittorrent sync works in a distributed manner. If all your systems are on your own network, you’re not even using your provider’s network, which saves bandwidth.

Unsynchronized backup:
You can, of course, also just keep your depot on an external hard drive or a USB stick. This way, changes don’t get synchronised, but you can still share your config files.

Deploying SUS

You’ve set up your depot, and configured it. It’s now time to deploy for the first time.

By default, the deployed files are symlinked to the appropriate files, but you can also copy them. To deploy SUS, run the deploy script.

/path/to/super-user-stone/deploy.sh -d /path/to/sus/depot

If you did everything correctly, you should now see something like this:

What’s in the name?

The name ‘Super User Stone’ is an allusion to the philosopher’s stone from the famous Harry Potter series. The philosopher’s stone is said to transform any metal it touches into solid gold. By analogy, the Super User Stone is supposed to transform any system into your system.

This might sound like one of the more pretentious of quotes, but there are a few things worth considering before making that judgement.

Passionate people are often called “obsessed” or “crazy”. They do what they do because they love what they do. For them, happiness comes from doing the work, not from being able to relax afterwards.

Lazy people, or any mediocre people for that matter, fall into the habit of calling these passionate people “obsessed” or “crazy” as an excuse. This post is just a shout-out to the people who are passionate about their work. Keep on doing what you do, and don’t let anyone discourage you to do what you love to do.

In my education as a computer scientist, I once got an assignment where I had to calculate all pairwise intersections of N circles. I spent three hours finding out how to calculate the intersections between two circles, because that was not sufficiently explained anywhere. I intend to solve and explain the solution to this problem because I find it important to not only know how something works, but also why it works.

Subject

The question I intend to answer is the following:

Given the coordinates of the centres of two circles and their ranges, how do we compute the intersections?

I will also show why my solution is correct after I present it.

Required knowledge

Basic vector calculus

Basic geometry

Naming

To be able to effectively talk about this problem, we need to name some components.

Suppose we have two circles \(C_1\) and \(C_2\).

Centres of the circles: \(M_1\) and \(M_2\).

Intersection points: \(P_1\) and \(P_2\).

The coordinates of M_1 and M_2: \((x_1,y_1)\) and \((x_2,y_2)\) respectively.

The distance between \(M_1\) and \(M_2\): \(d\).

The radii of the circles: \(r_1\) and \(r_2\) respectively.

The line between \(M_1\) and \(M_2\): \(l_1\).

The line between \(P_1\) and \(P_2\): \(l_2\).

The intersection of \(l_1\) and \(l_2\): \(P_0\).

The distance from \(M_1\) to \(P_0\): \(a\).

The distance from \(M_2\) to \(P_0\): \(b\).

The distance from \(P_0\) to \(P_1\): \(h\).

The distance from \(P_0\) to \(P_2\): \(h'\).

an illustration will clarify this:

How to calculate whether two circles intersect

\(d \leftarrow \Vert M_2-M_1 \Vert\)

return \((d \le r_1 + r_2 ) \wedge (d \ge \|r_1 − r_2\|)\)

This is a very short way of saying: “If the circles are close enough to each other, they intersect”

How to calculate the circles’ intersections

This an algorithm to calculate the intersections of two circles.

If \(C_1\) = \(C_2\) then return \(C_1\)

If \(C_1\) and \(C_2\) don’t intersect then return \(\emptyset\)

\(d \leftarrow \Vert M_2-M_1 \Vert\)

\(a \leftarrow \frac{r_1^2-r_2^2+d^2}{2d}\)

\(x_0 \leftarrow x_1 + \frac{a}{d}(x_2-x_1)\)

\(y_0 \leftarrow y_1 + \frac{a}{d}(y_2-y_1)\)

\(h \leftarrow \sqrt{r_{1}^{2} - a^{2}}\)

\(x_1' \leftarrow x_0 + \frac{h}{d}(y_2-y_1)\)

\(y_1' \leftarrow y_0 - \frac{h}{d}(x_2-x_1)\)

If \(a = r_1\) then return \(\\{(x_1',y_1')\\}\)

\(x_2' \leftarrow x_0 - \frac{h}{d}(y_2-y_1)\)

\(y_2' \leftarrow y_0 + \frac{h}{d}(x_2-x_1)\)

return \(\\{(x_1',y_1'),(x_2',y_2')\\}\)

For the explanation of why this is true, read on.

\(l_1\) and \(l_2\) are perpendicular and \(h\) and \(h'\) are equal.

The triangles \(M_1P_1P_0\) and \(M_2P_2P_0\) are equilateral triangles, precisely because \(P_1\) and \(P_2\) are on the circles. An equilateral triangle can be split into two congruent right triangles. In this case, \(M_1P_1P_0\) can be split into \(M_1P_1P_0\) and \(M_1P_2P_0\) while \(M_2P_2P_0\) can be split into \(M_2P_1P_0\) and \(M_2P_2P_0\).

Because any of those triangles is a right triangle, \(l_1\) and \(l_2\) are perpendicular.

Because \(M_1P_1P_0\) and \(M_1P_2P_0\) are congruent triangles, \(h\) and \(h'\) are equal.

The algorithm is correct.

There are three cases to prove in the algorithm.

If the circles are not close enough, they don’t intersect

If the circles touch, they have two equal intersection points

Otherwise, there are two different intersection points

I will only prove the third case. The second case is a special case of the third. The first is trivial.

We now know that the triangle \(M_1P_1P_0\) is a right triangle. We can therefore calculate \(h\) with Pythagoras.

People usually hate waking up early. Most people get up just in time for their work and certainly don’t enjoy the morning. I wake up around 03:00 as much as I can and I want to show you why. I find that there is a magic in the early morning that I can’t describe, only encourage you to experience.

Some people are cranky when they first get up in the morning. This post is not for them. This post is for people who feel that they are the most focused right after they wake up. Although you may think you will never feel focused in the morning, don’t be too quick to judge yourself on this. Most people are just not used to getting up early, and only have bad memories of it. I am confident that most people would enjoy waking up earlier, if only they tried it.

The beauty

When you get up before 05:00, you get to see the magnificent sunrise. This time of day presents the perfect opportunity to take a relaxing walk and a breath of fresh air.

Granted, sunrise looks almost the same as sunset, but there are some differences in the atmosphere. In the morning, you can sometimes see a mist, just above the ground. Other than the occasional person just getting home from a party, there is no one to be found outside in the morning. It’s as if you get to be the first person to explore the world today.

The silence

Between 03:00 and 06:00, almost no one is awake. The complete silence is calming. You can hear yourself think and feel your heart beat.

This is the perfect time to meditate. It is the perfect time to think about your future and your goals. It is also the perfect time to plan and to focus. If ever you need to steal a few hours of time for anything, this is the time to do it.

The efficiency

Everybody has only 24 hours in a day, from the richest CEO to the poorest slum dog. What matters is how you spend those 24 hours. Most people get up at around 7 or 8 in the morning (or even later). This means that if you get up at 03:00, your morning is four to five hours longer. These four to five hours, that you would otherwise spend unproductively in the evening, you will now get to spend productively before sunrise. Imagine what you could do, what kind of progress you could make, if you had more time.

Getting started

If you want to try out getting up earlier than you’re used to, here are some things to note. (I don’t necessarily mean getting up at 03:00, just earlier than just in time to get to work.)

Make sure you know why you’re getting up early.

Often when people try to get up early without a purpose, they end up just going back to bed after five minutes. It’s not easy to convince yourself to get out of bed, even when you do have a purpose. Your mind will specifically think of legitimate reasons just to stay in bed. If you’re still half asleep, you’re even more likely to give in to yourself.

Make sure you know what to do.

Even if it’s just “get ready for work without rushing”, “clean the floor” or any other simple task.
You need to know what you want to get done in the morning. Ideally, you schedule a few things that are best done in the morning, rather than something that can be done at any time. I, for example, find it engaging to imagine the day in while taking a walk.

Document your experience.

Even if it’s been a horrible first experience, write it down on a piece of paper. This information will become valuable if you ever want to try it again. You will know why you didn’t like the experience and whether you want to try it again differently.

If the experience was as wonderful, as I hope it will be, also be sure to write that down. This way, if the next time you are contemplating trying it again, you will be motivated by that little piece of paper.

If you look at my system setup, you will notice that I use as few Graphical User Interfaces as possible. I actively avoid using them, and this is why.

What GUIs are for

I will not go over what GUIs are in a lot of words. I will, however, define GUIs, so that I may talk about it.

Wikipedia defines GUIs as:

A type of interface that allows users to interact with electronic devices through graphical icons and visual indicators such as secondary notation, as opposed to text-based interfaces, typed command labels or text navigation

It also mentions the following:

GUIs were introduced in reaction to the perceived steep learning curve of command-line interfaces (CLIs), which require commands to be typed on the keyboard.

What isn’t a concern for me

I am a computer scientist. It is my job and my passion to work with computers. I am, therefore, willing to invest time and energy to make my work efficient and pleasant.

I use (arch) Linux as my operating system, which means that I have access to a terminal. Even more so, I do almost anything in my terminal. It teaches me more about my system.

The steep learning curve of a command line is something that I do not mind. I have put many hours into using a terminal and CLIs. Currently I find GUIs even harder to learn to use.

For the record: This post is about why I don’t like to use GUIs. I’m not trying to convince you that GUIs are bad, nor that you shouldn’t use them or that anyone should share this opinion.

Speed

Speed is my biggest concern with GUIs.

Most GUIs actively use the mouse for operation. This often means that developers don’t take the time to also implement keyboard shortcuts. As a result, the user is often obligated to use the mouse to interact with the UI. Moving your hand away from the keyboard to the mouse, moving around with it, and moving your hand back to your keyboard is a nuisance. It is very slow and can waste a lot of time of someone who uses his system every day for hours on end.

It is estimated that using a mouse is approximately 4 times slower than using the keyboard. This means, that if you use your system for eight hours a day, and you spend 25% of that time using UIs, you will save approximately an hour and a half a day, just by not using GUIs. That’s an extra three quarters of a month per year you could spent productively (or otherwise).

Weight

GUIs can cause performance issues on low-end machines. This may seem like a minor concern for most people, but a GUI is meant to serve as an interface between functionality and the user. When simply interfacing with a program, I want to make sure that the program can run quickly without the hindrance of GUI overhead.

Sometimes you only have access to a terminal, In SSH sessions for example. It comes in handy to know a lot about using the terminal then.

Scripts

GUIs, without an official API, can hardly every be scripted with. On the other hand, CLIs can be scripted with almost indefinitely. If you do the same sequence of operations often, you might write a shell script. In this situation, knowing a lot about using the terminal also comes in handy, because shell scripts usually have exactly the same syntax. You could never make this kind of shortcut yourself when you’re using a GUI.

GUIs often don’t produce any good error messages. Sometimes they display a pop-up message that briefly explains what went wrong, but often times the program just crashed and you have to look in the log files to see what happened. When using CLIs on the other hand, error messages are instantly in front of you when something went wrong. It might happen that a CLI doesn’t print any error messages, but then that’s just developer ignorance.

CLI alternatives for GUIs

Here are some CLI alternatives for things that most people use GUIs for.

These are the ones that I regularly use.

Email: mutt

Text editing: vim, emacs

File explorer: terminal

Chat: weechat, irssi

RSS reader: newsbeuter

Music: MPD with ncmpcpp

Note that emacs is really a GUI, but it didn’t use to be so most people don’t use it as a GUI.

You can use w3m, Lynx or Elinks to browse the internet in your terminal, but I don’t usually recommend that. You can use a browser plugin like vimperator or pentadactyl to get more keyboard shortcuts in your browser.

Conclusion

In summary, the real reason I don’t use GUIs is that they’re not user-friendly to me. I understand that most people won’t share this opinion, or want to use a setup like mine, but I encourage everyone who uses a computer heavily to consider it.