Monday, 29 April 2019

The Thief Knot Analogy

Another ropework analogy comes forth! Today, we will examine the Reef Knot and its evil twin - the Thief Knot.

The Reef Knot is a somewhat adequate knot for joining two lines of equal thickness - if the anticipated strain isn't expected to be enormous. It's handy and can be done in a pinch, though, as I mentioned earlier, no seaman worth his salt will use it for supporting very heavy loads.

A Reef Knot

However, sometimes people make the mistake of tying it this way. In this form, it's called a Thief Knot.

A Thief Knot

See the difference? The ends are on opposite sides of the knot. Which in turn means that the strain is coming from diagonally opposite positions. In the event of strain upon the knot, it would very quickly collapse.

The above happens when there is a lack of understanding as to how the knot is constructed and the focus is on the form rather than the function. Thus when someone looks at the Thief Knot without looking at the big picture, it would appear identical to the Reef Knot. But when the knot is put under pressure, that's when the mistake becomes apparent.

The Programming Parallel

Similarly, when writing code, sometimes what appears correct visually turns out to be logically incorrect when other things are taken into account. Let's use scope as an example. This is in JavaScript, but may hold true in other programming languages.

This code takes the variable, i, and every second, it increments i and displays the output in the console. You would actually substitute the code in the callback for something less trivial, but this has been deliberately kept simple for clarity.
function inc()
{
    var i = 0;

    console.log(i, " is the value of i");

    setInterval
    (
        function()
        {
            i++;
            console.log(i);
        },
        1000
    );
}

inc();

Pretty straightforward.

Now, let's see what happens if all that code is part of an object.
var obj =
{
    i: 0,
    inc: function() {
        console.log(this.i, " is the value of i");

        setInterval
        (
            function()
            {
                this.i++;
                console.log(this.i);
            },
            1000
        );
    }
}

obj.inc();


Aha! The first console statement runs just fine. The value of this.i is 0, and that's correct. But why does it fail in the setInterval() function?



Because while the code looks analogous to the first non-objectified example, there's a new wrench thrown in the works. Namely, this. In the main body of the inc() method, this.i would refer to the i property of the parent object, obj. So console.log(this.i) works just fine.

But once you place this.i in a callback, this no longer returns to obj. It still refers to its parent object, but now its parent object has changed. Its parent function is now the callback! Needless to say, this new piece of code wouldn't hold up at all.

The Knotty Conclusion

Scope is merely one example of how it can all go sideways if you take the same piece of code and expect it to work in some other context. The same way it will all go to shit if you blindly copy the form of the Reef Knot without understanding its function. It looks similar, but it performs drastically differently.

this has been a pleasure. Au revoir!
T___T

No comments:

Post a Comment