Kari and Richard's attention to symbols, definition, and meaning is
highly appropriate, but there's another angle at play here which I
think is more central to the language-ness of programming languages.
I'd like to share an analogy that's stuck with me for several when
thinking about the distinction between "programming" and "natural" as
modifiers for the concept of language (particularly one that tries to
side-step discussion of symbols).

Consider the representation of some physical value such as the
temperature of a room. We can make a "programming" representation of
this value with some configuration of a fixed number of bits (an int
in a machine word). Likewise, we can make a "natural" representation
of the value with, um, another physical value such as a voltage or
height of a mercury column in a thermometer. The programming
representation has a very chunky, discrete range of expression with
delivers a set number of bits of information. Meanwhile, the natural
representation smoothly ranges over some continuous domain, conveying
a fuzzy/undefined amount of information bounded by a complex
interaction of external noise sources and sampling error.

In programming languages, we've got these very discrete sequences of,
say, ascii characters, some subset of which are blessed by a
particular context-free grammar to be valid. Program code isn't
bounded in the same way as a 32-bit unsigned int, but it has a similar
discrete feeling. Meanwhile, natural language encompass a seemingly
infinite domain of expression, but the deeper we dig in extracting
information from an utterance, the more we need to make assumptions
about where the message came from and how well we heard it.

Programming representations invite us to interpret
(parse/compile/execute/etc.) them once and be confident that we got
everything important on the first try. Natural representations invite
us to repeatedly ask refining questions, allowing subsequent samples
to change our mind about inferences from the first question. And ADC
can convert a noisy (at some level) electrical signal into a discrete
digital symbol by repreatedly checking whether the signal is currently
above or below certain reference voltages. Indeed any amount of
digital information can be packed into some real value
(http://en.wikipedia.org/wiki/Arithmetic_coding), but for practical
purposes you will stop after some number of iterations. Natural
language can be subject to a similar process where seemingly limitless
information can be sucked out of a fixed natural language input via
close reading and the asking of a lot of tiny questions
(http://en.wikipedia.org/wiki/Deconstruction seems to experimentally
probe for the practical limits here).

This analogy between languages and simple physical values gives us a
way to talk about particular non-natural-nesses of programming
languages without references to symbols and semantics. (And if code is
data and you can store any data in a big fat bitstring, then it
shouldn't be saying anything too controversial.) But I'm somewhat of
an advocate for programming languages as languages, so now I want to
show how practical programming representations regularly find
themselves creeping in the natural direction.

Consider the generation of html documentation from java code using
javadoc. The official java compiler immediately throws away a lot of
information when it reads your source (comments, indentation, the
order of certain declarations, etc.). The javadoc code analyser, on
the other hand, makes a few assumptions about where the code came from
(that the programmer followed certain common practices). This allows
it to slurp up and save many comments and tie them to the constructs
they describe (conventionally, the declaration on the next line). The
tool remembers enough of your (not-so-superfluous) code formatting to
provide click-through links to particular locations in the source.
Certainly human java programmers "read into the text" a lot more than
the official compiler does, but this extended, extra-grammatical
interpretation process is not exclusive to humans.

Because I'm a fan of Richard's, this next example uses Prolog.
Metaprogramming regularly involves reading deeper and deeper meanings
from a snippet of object language (with the meta-language being
something we are comfortable calling a programming language). The
prolog snippet "connect_via(kitchen,dining_room,west)." is a 100%
complete and valid program, but it doesn't do much to execute it
(other than populate a conceptual table). By piling on more and more
assumptions in the surrounding code, we can infer from this snippet
(1) an instruction in the larger process of building a house, (2) a
specification for how some existing house was built, (3) a description
of (query for) houses out of some external database, or many other
things. It's not that we can get these meanings the snippet ended with
a full stop making it a complete statement, just knowing that a loose
term of that shape existed in some list of lists somewhere might lead
us to the same inferences in metaprogramming.

In a final example, consider livecoding. While usually carried out via
the medium of a canonically "programming" language, what we see in the
livecoder's projected screen during a performance is almost always
incomplete, ungrammatical, and filled with symbols that have yet to be
given meaning by reference in other bits of code. Similar to the way
we verbally communicate using only-locally-coherent,
sometimes-overlapping islands of grammatical speech, the livecoder's
text editor (more like a workbench), is covered with fragments of
programs yet-to-be or no-longer valid. Functions will be defined only
to not be used for several more minutes, and large declarations will
be fractured so that their body can be modified and re-evaluated via
manual selection. Impromptu (a relatively popular livecoding
environment) may speak Scheme, but you would be very hard pressed to
find a point in a livecoding session where saving the text currently
in the buffer actually results in an executable program -- sounds very
much like "natural" languages, right? (And this is to say nothing of
the use of metaprogramming in livecoding, or the temporal and even
two-way negotiation of meaning the happens.)

This has been longer than I expected my first post to this list to be,
but I hope I can inspire some new thoughts on language-ness.

The Open University is incorporated by Royal Charter (RC 000391), an exempt 
charity in England & Wales and a charity registered in Scotland (SC 038302).

Reply via email to