One of my uncles is an American Sign Language interpreter and has sometimes shared with us ASL puns which, as they are in a different language most of us don’t know, rarely make sense to us until he explains them. One of the idea he shared when explaining a pun some years ago was that in ASL you can save topics for future reference but placing
them in some location in space, then refer to them later by grabbing
them from that saved location.
When I am telling a story I often refer to people and sometimes objects by pairing the definite article the
with a description that makes them unique within the story, such as the cashier
, the red car
, or the president.
Sometimes instead of the
I use a possessive description attached to someone else, such as my uncle
, your friend who sells insurance
, or the car’s passenger seat.
Many people in my life have names, which I can sometimes use to identify them. But only sometimes; it’s not uncommon for me to be in a meeting with Geoff, Geoff, and Jeff and years ago I worked with two unrelated people both named Benjamin Johnson. Sometimes I can add to a name a role or descriptor, such as the Geoff who teaches 233
, Spanish Ben
, or not him, the other Carl.
In my first job I almost immediately forgot the name of my direct supervisor and several other coworkers. Too embarased to ask, I adopted the habit of standing at attention next to people until they looked at me, then making eye contact and addressing them without ever verbalizing who I was addressing.
I spend more time than I ever expected I would helping run meetings and arbitrate who gets to speak next. Much of this direction is based on eye contact, facial expressions, and gestures. Quizzical looks, imperative motions, and pointing can help people understand that their desire to be heard has been registered and queued without the need to add my voice to the conversation.
All of these are examples of identifying people and things. Identifying is key to communication, an essential part of keeping all party’s thinking about the same thing. But there’s not a single solution that allows identification in all settings: how we go about it depends on context.
Programming is the act of communicating instructions to a computer. It requires precision because we tend to write long sequences of instructions to be executed more quickly than we can follow so misunderstandings cannot be caught and corrected in the moment and can have significant impact. It requires simplicity because the ways humans and computers think is different enough that we have to teach both an alien language to understand one another and don’t want to waste effort making that alien language complex and hard to learn. And it requires universality because we always want to do more with it later than we expected we would when we designed it.
Some programming languages use textual names called identifiers
to identify things. They might name a process sqrt
and define it using several internal names, such as x
and guess
, perhaps in something like11 consider sqrt
(2):guess
starts as 1guess
is replaced by (1 + 2/1)/2 = 1.5guess
is replaced by (1.5 + 2/1.5)/2 = 1.41666…
(1.41666… + 2/1.41666…)/2 = 1.41421568…
(1.41421568… + 2/1.41421568…)/2 = 1.4142135623746…
and so on
How to find the
sqrt
of a numberx
:
- start
guess
out as 1- repeat until
guess
stops changing in digits we care about:
- replace
guess
with (guess
+ (x
÷guess
)) ÷ 2- use
guess
as the answer
These names are confusing to most programmers when they are first getting started, in part because they mean what the program says they mean and not what their name looks like it should mean and in part because they keep changing meaning, like guess
does in the above example.
Some programming languages use numbers instead of identifiers for naming things. Effectively they replace sqrt
with function 1234
, x
with value in location 3
, guess
with value in location 4
, and so on. This is close to what the underlying hardware does, but is not usually what programmers want to see22 One of the only times I’ve used similar language outside of programming is when I lived in a close-knit and sociable neighborhood of multi-student apartments all on one street and it was common to refer to the people in 492
or let’s meet in 326
, where those were house numbers..
Twenty years ago I wrote33 DOI 10.1145/2157136.2157155 an experimental programming language that tried to use English to identify things. It used identifiers like the number
or the third value,
and it worked, but it was tedious to write.
how to find the square root of a number:
start the answer as 1
repeat until the square of the answer = the number:
replace the answer with (the answer + (the number / the answer)) / 2
Both identifiers and numbers have a problem with collisions: what if I write some code that uses x
for one purpose and you write some code that uses x
for a different purpose and we want our code to work together? One solution is name mangling
: when I write x
the computer changes it into something complicated like _D7luther__T5xTG3fZQlFkZAQk
which your x
turns into something like _D7reader__T5xTiZQjFkZAi
. But that only works for identifiers; for numbers the more common solution is a stack
: the first thing to be used gets name 0
, the next one 1
, then 2
and so on; but to avoid running out of numbers when I’m done with something I can remove it, causing the number to go back down.
Often stack-based identification is coupled with a set of surprising operations like push 3
meaning add the number 3 to the top of the stack
, pop
meaning remove the top thing from the stack
, dup 2
meaning add a copy of the thing 2 items from the top of the stack to the top of the stack
, dup 0
means add a copy of the top item on the stack to the top of the stack
, and swap 4
meaning move the top item of the stack to the position 4 down and vice versa.
They also tend to assume operations like divide
means remove the top to items from the stack and put the lower divided by the upper on the top of the stack.
How to find the square root of the top value of the stack:
- push 1 44 stack: 2 1
- repeat until the top value on the stack stops changing in digits we care about:
- dup 1 55 stack: 2 1 2
- dup 1 66 stack: 2 1 2 1
- divide 77 stack: 2 1 2/1=2
- add 88 stack: 2 1+2=3
- push 2 99 stack: 2 3 2
- divide 1010 stack: 2 3/2=1.5
- swap 1 1111 from 2 √2 to √2 2
- pop 1212 stack: √2
- the answer is on the top of the stack
Stack-based languages are quite common as a portable intermediate layer for sharing code between computers1313 All three of the common cross-platform partially-compiled languages (WebAssembly, Java ByteCode, and the Microsoft Intermediate Language) are stack-based. They tend to be straightforward to convert into efficient hardware-based numbered representations regardless of how many numbered values the hardware in question can handle.