Natural Language Principles in Perl
Learn it once, use it many times
You learn a natural language once and use it many times. The lesson
for a language designer is that a language should be optimized for
expressive power rather than for ease of learning. It's easy to
learn to drive a golf cart, but it's hard to express yourself in
one.
Learn as you go
You don't learn a natural language even once, in the sense that you
never stop learning it. Nobody has ever learned any natural
language completely. Unfortunately, in the interests of
orthogonality, many computer languages are designed so that every
degree of freedom (dimension) is available everywhere. This has
its good points if you understand the whole language, but can lead
to confusion if you don't. You'd like to ignore some of the
dimensions to begin with. You'd like to be able to talk baby talk
and be understood. It's okay if a language is difficult to learn,
as long as you don't have to learn it all at once.
Many acceptable levels of competence
This is more of a sociological feature, compared to ``learn as you
go'', which is a psychological feature. People don't mind if you
speak a subset of a natural language, especially if you are a child
or a foreigner. (Except in Paris, of course.) If a language is
designed so that you can ``learn as you go'', then the expectation is
that everyone is learning, and that's okay.
Multiple ways to say the same thing
This one is more of an anthropological feature. People not
only learn as they go, but come from different backgrounds,
and will learn a different subset of the language first. It's
Officially Okay in the Perl realm to program in the subset of
Perl corresponding to sed, or awk, or C, or shell, or BASIC, or
Lisp, or Python. Or FORTRAN, even. Just because Perl is the
melting pot of computer languages doesn't mean you have to stir.
No shame in borrowing
In English (and other languages not suffering an identity crisis),
people don't mind swiping ideas from other languages and making
them part of the language. Efforts to maintain the ``purity'' of a
language (whether natural or artificial) only succeed in
establishing an elite class of people who know the shibboleths.
Ordinary folks know better, even if they don't know what
``shibboleth'' means.
Indeterminate dimensionality
Scientists like to be able to locate things by giving a ``vector'',
that is, a list of coordinates in a space of known dimensionality.
This is one of the reasons they like orthogonality--it means the
various components of the vector are independent of each other.
Unfortunately, the real world is not usually set up to work that
way. Most problems, including linguistics problems, are a matter
of ``getting from here to there'', and the geography in-between has a
heavy influence on which solutions are practical. Problems tend to
be solved at several levels. A typical journey might involve your
legs, your car, an escalator, a moving sidewalk, a jet, maybe some
more moving sidewalks or a tram, another jet, a taxi, and an
elevator. At each of these levels, there aren't many ``right
angles'', and the whole thing is a bit fractal in nature. In terms
of language, you say something that gets close to what you want to
say, and then you start refining it around the edges, just as you
would first plan your itinerary between major airports, and only
later worry about how to get to and from the airport.
Local ambiguity is okay
People thrive on ambiguity, as long as it is quickly resolved.
Generally, within a natural language, ambiguity is resolved rapidly
using recently spoken words and topics. Pronouns like ``it'' refer
to things that are close by, syntactically speaking. Perl is full
of little ambiguities that people never even notice because they're
resolved so rapidly. For instance, many terms and operators in
Perl begin with identical characters. Perl resolves them based on
whether it's expecting to see a term or an operator, just as a
person would. If you say 1 & 2
, it knows that the &
is a bitwise
AND, but if you say &foo
, it knows that you're calling subroutine
``foo''.
In contrast, many strongly typed languages have ``distant''
ambiguity. C++ is one of the worst in this respect, because you
can look at a + b and have no idea at all what the + is doing, let
alone where it's defined. We send people to graduate school to
learn to resolve distant ambiguities.
Punctuation by prosody and inflection
Natural language is naturally punctuated by the pitches, stresses
and pauses we use to indicate how words are related. So-called
``body language'' also comes into play here. Some of this
punctuation is written in English, but much of it is not--or is
only approximated. The trend in recent electronic communications
has been to invent various forms of punctuation. :-)
Some computer language designers seem to think that punctuation is
evil; I doubt their English teachers would agree.
Disambiguation by number, case and word order
Part of the reason a language can get away with certain local
ambiguities is that other ambiguities are suppressed by various
mechanisms. English uses number and word order, with vestiges of a
case system in the pronouns: ``The man looked at the men, and they
looked back at him.'' It's perfectly clear in that sentence who is
doing what to whom. Similarly, Perl has number markers on its
nouns; that is, $dog
is one pooch, and @dog
is (potentially) many.
So $
and @
are a little like ``this'' and ``these'' in English. Perl
also uses word order: ``sub use
'' means something quite different
from ``use sub
''. Perl doesn't do much with case distinctions,
unlike the shells, which make use-vs-mention distinctions using a $
prefix. Though I guess if you allow that, you could count Perl
quotes as a form of case marker. On a slightly more abstruse
level, Perl 5's \
operator is a sort of case marker or preposition
indicating mention rather than use. But as with most computer
languages, prepositional notions are usually expressed by position
within an argument list. (Though it's certainly possible to
write calls using named parameters in Perl, and keys of hashes
sometimes function as prepositions.)
move $rook from => $qr_pos, to => "kb3";
Topicalization
With regard to topicalization, I should point out that this
sentence starts with one. A topicalizer simply introduces the
subject you're intending to talk about. There are several
syntactic forms in English, the simplest one of which is simply a
noun: ``Carrots, I hate 'em.'' Pascal has a ``with'' clause that
functions as a topicalizer. Topicalizers can sometimes give a list
of topics, at which point you see words like ``for BLAH and BLAH, do
BLAH''. In Perl, there are various things that work as topicalizers.
You can say
foreach (@dog) { print $_ }
This can even be used singularly:
for ($some_long_name) { s/foo/bar/g; tr/a-z/A-Z/; print; }
Pattern matches (and indeed any conditionals) tend to function as
topicalizers in Perl:
/^Subject: (.*)/ and print $1;
Discourse structure
Discourse structure is how an utterance longer than a sentence is
put together. Different languages and cultures have different
rules for how to tell a joke or a story, for instance, or how to
write a book about Perl. Some computer languages have rather fixed
rules for larger structures. COBOL and Pascal come to mind. Perl
tends to be pretty free about what order you put your statements,
except that it's rather Aristotelian in requiring you to provide
an explicit beginning and end for larger structures, using curlies.
But you could almost claim that #!/usr/bin/perl
corresponds to
``Once upon a time'', while __END__
means ``And they lived happily
ever after.''
Pronominalization
We all know about pronouns and their uses. There are a number of
pronouns in Perl: $_
means ``it'', and @_
tends to mean ``them''. (But
$1
, $2
etc. are also pronominal references back to antecedent
substrings in the last pattern match, which we mentioned can function
as topicalizers.) Within a foreach loop or a grep, $_
is not just
a copy of the item in question, but an alias for it. Similarly, @_
is a list of references to the function's arguments, and the
arguments can be modified by changing elements of @_
.
No theoretical axes to grind
Natural languages are used by people who for the most part don't
give a rip how elegant the design of their language is. Except for
a few writers striving to make a point in the most efficient way
possible, ordinary folks scatter all sorts of redundancy throughout
their communication to make sure of being understood. They use
whatever words come to hand to get their point across, and work at
it till they beat the thing to death. Normally this ain't a
problem. They're quite willing to learn a new word occasionally if
they see that it will be useful, but unlike lawyers or computer
scientists, they feel little need to define lots of new words
before they say what they want to say.
In terms of computer languages, this argues for predefining the
commonly used concepts so that people don't feel the need to make
so many definitions. Quite a few Perl scripts contain no
definitions at all. I dare you to find a C++ program without a
definition.
Style not enforced except by peer pressure
We do not all have to write like Faulkner, or program like
Dijkstra. I will gladly tell people what my programming style is,
and I will even tell them where I think their own style is unclear
or makes me jump through mental hoops. But I do this as a fellow
programmer, not as the Perl god. Some language designers hope to
enforce style through various typographical means such as forcing
(more or less) one statement per line. This is all very well for
poetry, but I don't think I want to force everyone to write poetry
in Perl. Such stylistic limits should be self-imposed, or at most
policed by consensus among your buddies.
Cooperative design
Nobody designs a natural language by themselves, unless their name
happens to be Tolkien. We all contribute to the design of our
language by our borrowing and our coinages, by copying what we
think is cool and eschewing what we think is obfuscational. The
best artificial languages are collaborations--even with a language
like Perl where one person seems to be in charge of it. Most of
Perl's good ideas were not original with me. Some of them came
from other languages, and some of them were suggestions made by
various folks as we went along. If you consider the language to
include the various cultural trappings (libraries, bin directories)
that go along with the language, then even languages like C, or
Ada, or C++, or even the Unix shells are collaborations by many,
many people. Perl is no exception to this.
``Inevitable'' Divergence
Because a language is designed by many people, any language
inevitably diverges into dialects. It may be possible to delay
this, but for any living language the forces of divergence are
nearly always stronger then the forces of convergence. POSIX tried
to unify System V and BSD, and as soon as they squeezed things
together in that dimension, the number of Unix variants exploded in
several other dimensions. The lesson for a language designer is to
build in explicit mechanisms so that it's easy to identify which
variant of the language is being dealt with. Perl 5 has an
explicit extension mechanism for which you specify, using ``use''
clauses, which kinds of special semantics or ``dialects'' you're
going to be relying on. Perl 4 didn't have this, and there was
considerably more pressure to put various things into the language
that didn't belong in the core language. Hopefully now we can
stabilize ``basic'' Perl so that there is less need to invent
oraperl, sybperl, isqlperl, etc.