Panel 1: At a hotel reception desk, a receptionist and a visitor are standing. The visitor sais: "Oh my god this crazy country is just freaking me out…" -- Panel 2: The person facepalms and sais: "…I mean, seriously? a bed without meat?" -- Panel 3: A bed is shown which uses a turkey as a pillow, bacon as cover, and a T-bone-steak as mattress, and sausages as feet. The person sais: "To me, it is not a bed without meat."

Popular Culture:

Science, Software, Hardware:

Zeroth World:

Comics/Images/Audios/Videos:

The world wants to boycott Germany? Or at least say so? Well, apparently they want to boycott buying German products, not getting German money.

It is easy to blame someone, especially someone with a history as bad as us Germans'. What I saw in this report about the poor Greeks' situation (having to give their children away) shocked me. And while there might be nationalism in Germany, most Germans would not agree to measures that lead to something like that. They just don't know that it is really that bad.

Don't forget: Many Germans are poor too - mostly not that poor apparently, but still poor. And their only daily lecture is Bild - which tells them that the lazy Greek people take away their money. The reason that poor Greek people are angry about Germany is similar to the reason that poor German people are angry about Greece: They think that it causes their bad situation.

So just today I read that Apple could have bailed out Greece twice. And I wonder: Why not #boycottApple then? But again, it is not Apple alone. I am sure there are many companies that could do so. And I am sure that there are many companies that even caused Greece's situation. Why don't we all just boycott them? Why not #boycottCapitalism?

Could it be because we all secretly love the current kind of capitalism? Greece benefited from it in the past, as well as Germany did. As Volker Pispers points out: It is the modern religion, you don't have to understand it, you just have to believe it.

While I can pity single persons, I do not pity the Greece people on the whole. For decades they accepted this system. And when it was too late, they elected extremist parties. I am sure if it was the other way around, they would have a government that would behave like Germany does now, maybe a little better, maybe a little worse.

And I am sure the day will come for many of the German people who cry about our precious German money being given away to greedy Greeks to be in need of help themselves. Hopefully the system has changed till then.

Every nation gets the government it deserves. (Joseph de Maistre)

Panel 1: A person lifting his finger on the left side, a person holding a bill on the right side. The left person sais: "You will find out that money cannot be eaten." The right person sais: "Actually, we switched to biodegradable Freigeld a while ago." -- Panel 2: The left person now bends his finger and looks confused. He sais "W?" and is interrupted by the right person, who took a bite of his bill, saying "Mmmmmh… Strawberry taste…"

External Content not shown. Further Information.

I am not a professional software developer — well, I guess in some sense I am, but at least not an industrial professional software developer. But at least what I heard from some industrial software developers, what I will describe now is a usual experience:

You develop a complex piece of software. Especially the "practical" pieces of software are usually evolutionally grown and very complex. And usually, when writing code, you write something very specific and nontrivial – because if it was trivial, there would usually be no reason to write it, except exercising, which is also pointless if the solution is trivial to you.

So what happens to me often (and as far as I heard, I am not alone with this) is that I wrote a large piece of software, and then compile and test it – just to eliminate the worst bugs and lots of small mistakes. I really hate this phase of writing code.

So recently, I had to optimize a functional algorithm. I did so, and it was really hard, it took me a few hours. Then I leaned back and had this feeling that I always have before the first debugging phase.

But just a few moments later I remembered: The code I have written was functional for a reason: The entire algorithm was formally verified against a specification which I already had debugged and reviewed thoroughly. Admittedly it took me longer to write verified code than it would have taken to write unverified code, but the whole phase of testing and debugging is practically nonexistent.

External Content not shown. Further Information.

There might be some duplicates from past link lists due to a broken computer and Firefox profile fsckup. Sorry about that.

Popular Culture:

Nerd Culture:

Science, Software, Hardware:

Zeroth World:

Comics/Images/Audios/Videos:

Quotes:

Panel 1: Two persons are shown. Person A has a computer with an external webcam attached to it. Person B has a computer without external devices, with a Bomb Plant emblem on the back of the screen. Person B sais: "I see you use an external webcam." Person A sais: "Yes. It does its job." -- Panel 2: The perspective of the scene slightly changes. Person B sais: "But isn't it impractical to always carry it with you?" Person A sais: "No." -- Panel 3: The perspective of the scene changes, person A is only shown in the background, but the front of person B's screen is shown. In the place where the integrated webcam would be, two glue strips are holding a piece of paper, so the webcam cannot take images. Person A sais: "Hm. I prefer everything to be integrated. I like to have everything ready when I need it."

External Content not shown. Further Information.

Popular Culture:

Nerd Culture:

Science, Software, Hardware:

Zeroth World:

Comics/Images/Audios/Videos:

Quotes:

Induction is one of the nightmares of many computer science students, it seems. For mathematicians, it is a very natural concept, and often the first higher proof strategy. Induction itself is not hard, the problem is that most proofs involve a lot more work than just induction, and it can be hard to even find the right parameters for induction.

When doing type theory, one quickly notices that induction is somehow equivalent to recursion: Recursion operators have a type signature similar to the formulas which encode induction principles. This is not a coincidence - but recursion operators are not really intuitive either, for a beginner. However, I think that for many beginners who have at least a little knowledge about programming, the key for understanding induction could be recursion. Even though from a purely "practical" viewpoint, recursion might not be good programming practice (especially if you ask older programmers), it is a well-understood concept.

I assume that the reader knows what a function - in the sense of programming - is. I will use C notation here, but without pointer magic, to make it easily understandable.

A well known function is the factorial of a number. Mathematical notation for the factorial of n\in\mathbb{N}_0 is usually n!. For n\ge 1, we can "define" the factorial as n!=1\cdot 2\cdot\ldots\cdot n. Furthermore, it is defined that 0!=1. A simple implementation of this function in C would look like

int fact(int n) {
    int ret = 1;
    for (int i = 1; i <= n; i++) {
        ret = ret * i;
    }
    return ret;
}

And in fact, this would calculate the factorial (and is probably the way most software engineers would recommend). On the other hand, notice that n! = n\cdot(n-1)! for n>0. This equation and 0!=1 fully determine the values of the factorial function. So, an alternative way to write a factorial function in C is

int fact (int n) {
    if (n == 0) return 1;
    else return n * fact(n - 1);
}

This function calls itself. This is called recursion, the function is called recursive. Notice that the function argument decreases. Behind this lies a simple principle: We can already calculate the function for a smaller argument, and we can use this value to calculate the function's value for the larger argument. We can reduce the problem to a simpler problem.

Another classical example for recursion (and especially for the problems with recursion) is the Fibonacci sequence. We define f_1=f_2=1 and f_{n+2}=f_{n+1}+f_n for n>2. This is a recursive definition. In C, we can write

int fib (int n) {
    if (n < 3) {
         return 1;
    } else {
        return fib(n-1) + fib(n-2)
    }
}

This definition has a major disadvantage: Its runtime is exponential (if you don't know what that means: really really slow). But it also has a great advantage: It is easy to write and easy to understand. The non-recursive definition looks like

int fib (int n) {
    int j = 1, k = 1;
    for (int i = 3; i <= n; i++) {
        int l = j + k;
        j = k;
        k = l;
    }
    return k;
}

This function is (arguably) harder to understand. This is often the case, and this is a common problem that computer science tries to solve: Things which are easy for humans are hard for computers and vice versa. That is why modern programming languages have abstractions like functions, classes, modules, etc. The art of computer science is to find a common language that both computers and humans understand well. For the hardest parts, people rely on mathematical proofs.

And one principle that makes it easier for humans to reason is to reduce a problem on simpler problems. And this is what recursion can do.

Now back to induction. The classical introduction to induction usually contains Gaussian sums: Assume we want to add the numbers from 1 to n, that is, we want to calculate 1+2+\ldots+n. This is similar to the factorial, except that we use addition instead of multiplication. And of course, we can use the same function as above, and just replace multiplications with additions (and 1 with 0):

int gauss (int n) {
    if (n == 0) return 0;
    else return n + gauss(n - 1);
}

This function loops through all numbers below n, it takes linear time. This is not bad, but there is an easier way:

int gauss (int n) {
    return (n * (n + 1))/2;
}

In fact, 1+2+\ldots+n = \frac{n(n+1)}{2} for all n\in\mathbb{N}. How do we know that this holds for every natural number? We can calculate this for every single number, but not for all numbers, as there are infinitely many natural numbers: We need a mathematical proof.

Before we go into induction, let us define a function from natural numbers to proofs. It is possible to do this formally, but not without a deeper understanding of mathematical logic - so we just do this informally here. Let us call this function Q. That is, Q(1) is a proof for 1=\frac{1\cdot 2}{2}, Q(2) is a proof for 1+2=\frac{2\cdot 3}{2}, and in general, Q(n) is a proof for 1+2+\ldots+n = \frac{n(n+1)}{2}. We will define this function recursively.

For Q(1), we can just calculate this. So, we can say

Q(1):=\mbox{'Calculate }\frac{1\cdot2}{2}\mbox{ and notice that it
is equal to }1\mbox{'}.

For Q(n) with n>1, we can do recursion. Q(n-1) proves that 1+2+\ldots+(n-1)=\frac{(n-1)((n-1)+1)}{2}. Using this proof, we can set

Q(n) := \begin{array}{cc}
 1+2+\ldots+(n-1)=\frac{(n-1)((n-1)+1)}{2} & \mbox{by }Q(n-1) \\
 1+2+\ldots+(n-1)+n = \frac{(n-1)((n-1)+1)}{2}+n & | +n \\
 1+2+\ldots+n = \frac{(n-1)n+2n}{2} & \\
 1+2+\ldots+n = \frac{nn-n+2n}{2} & \\
 1+2+\ldots+n = \frac{nn+n}{2} & \\
 1+2+\ldots+n = \frac{n(n+1)}{2}\end{array}

We recursively defined a function that generates proofs. We did this in a very informal way, but with just a little more theory, we could do this in a fully formal way. (If you're interested, look at proof assistants like Coq or Agda.)

Denote by A(n) our proposition 1+2+\ldots+n =
\frac{n(n+1)}{2}. Notice that Q(n) is a proof of A(n).

Notice that our definition of Q(1) proves A(1). Our definition of Q(n) for the other cases uses Q(n-1) - a proof of A(n-1) - to prove A(n). So essentially, one could say that the recursive definition is itself a proof of A(n-1)\rightarrow A(n). And notice that these are the premises of induction: If A(1) and for all n>1 we have A(n-1)\rightarrow A(n), then we have A(n) for all n.

There are more general induction schemes. For example, on binary trees, you can do induction on every branch - but the same way you can do recursion. The important part about induction (and recursion) is that something decreases, which cannot decrease infinitely often.

External Content not shown. Further Information.

Popular Culture:

Nerd Culture:

Science, Software, Hardware:

Zeroth World:

Comics/Images/Audios/Videos:

Quotes: