Uglliness scale: Python <<< awk << p*** < SNOBOL4

Tim Peters tim_one at
Tue Aug 17 06:32:50 CEST 1999

[Robin Becker]
> I once described perl as being like awk on steroids and lsd

[John Machin]
> Actually perl is more like SNOBOL4 on sedatives.

While I'm tickled by the image, nothing is like SNOBOL4 -- not even its
modern successor, Icon.  SNOBOL4 was unique, and is still the Best Language
on Earth for writing string pattern-matching algorithms.

> [a nostalgic look at S4's pioneering features]
> ...
> It even had the ability to assign the result of a partial pattern
> match to a variable ... about 30 years later, Python got this in
> the re module's ?P<name> feature, and AFAIK perl doesn't have this
> even yet.

Neither does Python <wink>:  S4's "immediate assignments" allowed capturing
partial results even if the overall match failed.  Perl may yet get the
effect of that by allowing embedded Perl code in regexps, but Python likely

> However SNOBOL4 also had the ugliest syntax that I've ever seen in a
> language that was genuinely intended for serious work -- Intercal is
> far uglier but is a parody.

Its syntax was fine!  I expect that what you really object to is the absence
of control structures other than goto, and the LT/GE/etc spelling of
comparison operators.  That was common enough in its day, and even by the
time Pascal came around the keypunch I used still didn't have a semicolon
key.  It looks ugly in retrospect only because it is <wink>.

> For example [1]
> 	FLIP = LEN(*I) . HEAD LEN(1) $ X LEN(1) $ Y *LGT(X,Y)

All obvious to the most casual observer <snort>.  It's interesting that you
*still* can't spell this algorithm fragment with comparable ease in Python
or Perl!  Roughly, FLIP is a pattern fragment that skips the first I
characters of a string (or fails if the string is shorter than I chars),
assigns the next two characters to variables X and Y (or fails if there
aren't two more), and then succeeds if X is lexically greater than Y else
fails.  And the first I characters are assigned to HEAD iff the pattern as a
whole succeeds.  In context, the next line is


which matches FLIP against string STR, and interchanges X with Y if they're
lexically out of order (replacing the HEAD characters with themselves
unchanged).  In Python you'd be provoked to

    def flip(str, i):
            if str[i] > str[i+1]:
                str = str[:i] + str[i+1] + str[i] + str[i+2:]
        except IndexError:
        return str

To modern eyes I'm sure that looks clearer, but six delicate indexing
expressions are a half dozen chances to blow it that the S4 fragment can't
suffer.  I will admit that the call-by-reference Perl

sub flip {
    my ($s, $i) = @_;
    substr($$s, $i, 2) = $2 . $1 if $$s =~ /^.{$i}(.)(.)/ && $1 gt $2;

is much closer to the S4 <wink>.

> ...
> Did-anyone-we-know-write-a-SNOBOL4-mode-for-the-IBM-026-keypunch?-ly
> yours,

yes-but-it-was-in-fortran2-and-kept-blowing-the-tubes-ly y'rs  - tim

More information about the Python-list mailing list