Ian Bicking: the old part of his blog

Of Syntax and Environment

I was reading Robert Lefkowitz's post What makes a programming language great? (via his son).

In it he (kind of) argues against overly-simple core languages. Thinking back to the 2003 PyCon Keynote, wherein I thought Paul Graham was off his rocker, I can see Robert's point. But in doing so I think he argues two kinds of simplicity -- both of which are arguable, but are also very different.

There's syntactic simplicity, and the simplicity of homogeneity. I.e., pure syntax vs. a pure runtime.

With syntactic simplicity you get languages like Lisp, Smalltalk, Logo, and Tcl (in more-or-less increasing order of simpicity and regularity). Advantages:

Non-advantages:

Disadvantages:

Note that complex syntaxes can have all these disadvantages as well, these are all just generalizations.

On the other hand, you can have a pure runtime. Examples include Java (excluding JNI), Squeak, and many Schemes. To make a contrast, Lisp and Tcl aren't very pure, while Java is yet doesn't have a pure syntax.

Advantages:

Non-advantages:

Disadvantages:

Robert talks about Perl regular expressions, vs. Python's. In terms of syntax Perl's is less regular and more expressive -- Python has no native regular expression syntax, and instead uses normal strings. But in terms of runtime they are nearly identical -- Python happily uses a C backend just like Perl, and even a backend with the same heritage (note: I was corrected, and their isn't any shared heritage, though they are similarly implemented in C). Java would be a counterexample, since I'm guessing Java regular expressions are implemented in Java.

Python, since I can't help but bring it up specifically in every post, is a particularly impure runtime. It's made significant compromises in the process. The GIL is largely there to make it easier to mix Python and C code. There's been a lot of reluctance to add microthreading and continuations to Python, and I think there's also a connection, because Python is easier to interface with C if they share a stack, and the C stack isn't all that amenable to continuations (though it's not impossible; but it truly is impossible with the Java stack).

As a syntax, Python is middling. It resists (non-traditional) punctuation. It tries to leverage its syntax for multiple uses. It has uniformity of attribute access. But it's largely programmatically opaque, and there's never been any effort to keep it down to a core of primitive constructs.

Created 05 Feb '05
Modified 05 Feb '05

Comments:

source
"a backend with the same heritage"

Really?  Given that the Python RE backend was written by
someone who's never used Perl, on a machine without a Perl
installation, maybe you could explain that sentence?
# Fredrik

I thought Python regular expressions were Perl-compatible in syntax, and somewhere I guess I got the impression they used the PCRE backend, though I might have entirely imagined that. At least I thought the distinction between re and regex was that regex used Emacs-style regular expressions, and re used Perl-style.

But I'm not saying I'm right or anything.

# Ian Bicking

source
In 1.5.2, the RE module used PCRE.  In 1.6 and later, that was
replaced with a Unicode-aware engine, SRE, which was written from
scratch, using on the 1.5.2 documentation and test suite as the
specification.

(guess who wrote it? ;-)
# Fredrik

source
should have been "using only the"
# Fredrik

The GIL is not only for C-extensions. Even if you could wave a magic wand and make all C-extensions thread safe, you may decide to keep the GIL, so that Python bytecode operations remain atomic. Use of the GIL was an engineering choice, to promote performance and simplicity, at the expense of responsiveness.

Because the GIL guarantees atomic bytecode operations, you can make those operations nice and fast, with no worries about thread context changes in the middle (another thread messing up your ducks while you have them nicely in a row). Also makes things simpler, because of the checks you can avoid, you can just plow ahead, knowing nothing happens with threading until you release the GIL.

But you lose responsiveness. Sometimes a thread is started for naught, because an earlier thread hasn't released the GIL yet. Would you want something like a GIL at the heart of a real-time system? Probably not.

# nobody