That’s an odd title, for sure. What is “action at a distance”? Well, how about an example? Let’s take Python 3.x, but it would work very much the same with JavaScript. Or Lua. Or most other languages.
1 2 3 4 |
|
A perfectly fine program, right? It adds some elements to a list, nothing
unusual (yes, I know extend
exists, but extend
is only a shortcut for
exactly this functionality), you might see that in every Python program ever.
Now, how about we wrap that in a function?
1 2 3 4 5 6 |
|
That’s something most semi-knowledgeable Pythoneers would object, since you can
call that function anywhere and the value of lat
magically changes. This is
what I was calling “action at a distance”. You can call that also “nonlocal
modification/assignment”, and Python 3 even has a nonlocal
keyword to allow
such nonlocal assignments.
So, looking at the function, it takes no arguments and returns None
.
Python-programmers will say: ok, then, make lat
an argument and return the
new list instead.
1 2 3 4 5 6 7 |
|
Great, now the function is not able to magically change lat
any time it
wants. When we look into this code, we have basically run into a circle: the
for
loop “takes” no input data and “returns” no output data, it just
magically changes lst
. This is a small toy function, so it is easy to see,
but conceptually we can think about it again as a function that does action on
a distance.
The usual way is to do so is to write functions that take arguments and return
some new values. Unfortunately, append
does not return a value, it, again,
does action at a distance in some way, “magically” adding an element to the
list. That’s easy to fix, let’s make our own append operator:
1 2 |
|
With this in order, we would need to call append(lst, 4)
and then
append(that_result, 5)
and append(previous_result, 6)
on it, thus
constructing append(append(append(lst, 4), 5, 6)
. Fortunately, Python ships
with a function that does exactly that, in 2.x it is called reduce
and in
3.x it is still called reduce but moved into the functools
module.
1 2 |
|
The whole code looks like this now:
1 2 3 4 5 6 7 8 |
|
This time we eliminated all action-at-a-distance operations. Every operation takes an input and returns a result, there is no more things changing in the background without an assignment. Interestingly enough, we have just invented functional programming, a paradigm that avoids action-at-a-distance as much as possible, which makes reasoning about code easier. This is, by the way called “referential transparency”, a fancy-pants name for “nothing happens at a distance”.
Would you think, that there are people who made programming languages which only do functional programming?