What is guaranteed in languages in practice

July 30, 2008

In theory, what is guaranteed in a language is the things that are in its (official) specification; if the specification is silent or says that something is not guaranteed, it isn't, regardless of how implementations behave.

More and more I have come to believe that this is mistaken, and that in practice what is guaranteed in a language is what programmers code to, regardless of what the specification says. This is because of simple pragmatics: a new implementation that does not run most of the existing code is generally pretty useless to people. Thus, a new implementation that breaks from established practice does not get much traction and adoption, even if its differences are blessed by the specifications.

(Or in short, people don't care why it doesn't run their old code, they just care that it doesn't.)

You can change this state of affairs, but it takes a long time and the new implementations have to have something desirable that will get people to overcome their inertia and actually change their code instead of just sticking with the existing, working implementation. Of course you can try to give people no choice, for example by no longer selling the old implementation, but this can backfire on you in various ways.

(There are many examples of such slow changes; consider how long it took to get C programs to be 64-bit clean and large file aware, and note how it only really started happening once there was 64-bit hardware out there.)

The corollary to this pragmatic view is that if you want people to stick to what is documented, you need to get them coding to it from the start. I can think of two ways to encourage this:

  • make your first implementation enforce the specification, especially the things the specification says that programmers can't count on.
  • have multiple implementations from the start, ideally ones with useful differences, so that people are pushed towards coding to the documented subset.

    (For this to work you need people to be interested in moving their code between the implementations.)

Unfortunately both are easier said than done.


Comments on this page:

From 70.74.240.140 at 2008-07-30 14:36:22:

It does have some weight, which I glossed over too much in my previous post. However, how much weight is very situational, and has to be balanced against the benefits of the change.

Python has changed such things in the past. Sometimes it makes concessions, such as retaining old-style classes, or requiring a __future__ import. The ability to test on alternate implementations is essential, and spreading the change out over several releases accomplishes that.

I don't see an easy way to do that with dict atomicity, but you must realize one thing: threading is a dark corner of the Python language. There's a lot of poor designs, buggy implementations, and incomplete specifications. It's unlikely that a fix for all of this would reuse the old APIs, so the most you can hope for is a transition period.

-- Adam Olsen, aka Rhamphoryncus

Written on 30 July 2008.
« What you can (probably) count on for concurrency in Python
SSL's identity problem »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Wed Jul 30 01:05:37 2008
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.