Updated 2015-02-19 12:10:54 by pooryorick

In (20 April 2001) Peter Lewerin wrote
By good girls don't languages I mean languages that have been designed to make impossible certain programming idioms that the designer feels are unsafe, insane, or merely unseemly. Never mind the notion that responsible and competent programmers could put these same idioms to safe, sane, or elegant uses -- good girls simply ‘don't’.

and went on to name a few instances, which precipitated comments that came about as near flames as the famously good-natured Tcl community ever stoops to.

It was quite stupid of me to give examples since 1) the examples weren't the point and 2) this quality is subjective anyway. Obviously a language designer strives to make their design as useful as possible, and in those few cases where a design truly fits the description above, the resulting language probably has a user base in single digits.

Still, sometimes I use a language that isn't one of my favorites, and find that I can't do this thing that I want to do because the language is designed to disallow it. Being human, I reach for an invective. The Jargon Lexicon uses the term Bondage & Discipline languages, but to me, that's not necessarily a negative connotation. Rather than imagining myself and the language engaged in some kind of kinkiness, I feel that it's like every time I say "I'd like to do X", the language responds with a prudish "Well, I'm sure I don't know what that is!" (NB: this is of course something a person has every right to say, but I don't feel I have any obligation to respect the hurt feelings of a programming language.)

This line of thinking probably says more about me than about the languages I mentioned in the original text, but I can't help thinking that I can't be altogether alone in this. (9 January 2010)

I have left the comments unedited, but note that they are about an earlier, more specific, version of this text.

Kevin Kenny (21 April 2001):

Certainly a worker needs to be given sharp tools. Pascal is perhaps an extreme example of withholding sharp tools for fear that programmers will cut themselves.

Larry Smith: You know, I'm getting tired of seeing this canard. Pascal was a teaching language, and more than sharp enough if you bothered to understand its design philosophy rather than bellyaching about how it isn't C. Being not C was a good thing then, and it's a truly wonderful thing today, unless you really like having hackers loading new code into your application because you forgot to check an array bound.

More to the point: Wirth never intended Pascal as a production language. The languages he did design for production are Modula/2 and Oberon, and their most recent descendent is Component Pascal, which is a) type safe, b) garbage collected, and c) sharper than any scalpal you are likely to find. It plugs the two biggest holes in C that enable hijacking of code and which blow development schedules out of the water. It is also fast and efficient at producing code. A version for the .NET and jvm architectures is available at [1].

But there's something to be said, too, for strong typing -- in its place. I'd argue that we need a two-tier language architecture. Strongly typed languages are easier to optimize -- important in performance-critical code. They detect many errors early -- important when managing complex data structures. Their chief disadvantage is that they do not allow for easy combination of data structures and algorithms that were not designed to work together in the first place. This easy combination of disparate components is where scripting languages shine.

Microsoft realized this principle early. In the pre-.NET world, applications are built by developing components in Visual C++ and then wiring them together in Visual Basic. This two-tier approach pervades the Microsoft world.

Sun, alas, fell victim to its own hype about Java as the universal language. The Java world tries to make Java the universal language on both tiers. It doesn't work. Java is far, far too bureaucratic for effective use as the scripting layer. This is the chief reason that development of user interfaces using AWT/Swing/Java Beans is expensive and time-consuming; there isn't any easy way to take prebuilt user interface components and wire them together -- without resorting to a GUI builder, which then eliminates any hope of maintaining the GUI source code without the same GUI builder, locking the programmer into the relationship with the vendor.

Early on, it looked as if Tcl (Jacl / TclBlend) might be a candidate for the scripting layer atop Java. Alas, it never came to be.

It is equally unfortunate that Dilbert's boss thinks that one programming language should be enough for everyone.

Jean-Claude Wippler (21 April 2000):

Sooooo true, Kevin. In the previous century, I penned down some notes about this very issue, see [2].

In a nutshell: for me, the essence of scripting is not the language choice, nor even the level of dynamic typing (which Tcl, Perl, Python, and Lua all approach differently), but the fact that it allows building software in several levels. With different languages best suited for each level - and dynamic ones of course eminently suitable at the top / app / business logic level.

Peter Lewerin (22 Apr 2000):

I feel that design decisions concerning strong/weak or static/dynamic typing are fundamental and not really subject to this type of criticism. If a designer chooses strong typing, I as a programmer am not able to mix and match types -- but on the other hand I get better error checking and optimizations. Good girls don't designs, by my definition, take away X from my toolbox and give me nothing, or something less important, in exchange.

For further interesting notes on typing:

(I quote these sources because they make the point that type system designs might sometimes miss the mark completely.)

Maybe unrestricted pointers are a better example. Sure, pointer abuse is the root of many evils in software production. I have nothing against language designers that provide useful alternatives or make pointer use superfluous, but to just take away the possibility to use pointers because the designer doesn't trust me, the programmer, to be able to use pointers correctly is insulting.

Kevin Kenny (23 May 2000):

Peter, I think you and I are fundamentally in agreement. From your original post it appeared to me that you objected to strong typing as a "good girls don't" idea, without recognizing its advantages. Inferential strong typing, as in SETL, ML or Haskell, is definitely preferable to what the Algol-derived languages do, which in turn is better than nothing.

For Brian Kernighan's notes on Pascal and its "good girls don't" attitude to practically everything, look at:


Lars H (21 January 2003):

Having read the notes at the above link, I cannot see that they support your claim that Pascal has a "good girls don't" attitude to practically everything. What is clear from them is that there are many things missing from Pascal, and in particular, from the form of the language described in the proposed standard of the early 1980's. Big deal. The typical Pascal compiler one could encounter in the late 1980's and early 1990's would have contained non-standard modifications of the language that addressed most of them, so in practice the language wasn't as bad as it was in theory. (It is however true that most of the problems that were not addressed had to do with types.) A language that allows jumping into loops can hardly be said to have a "good girls don't" attitude to everything. Pascal's attitude is more a kind of "there is no reason the language should display the attributes of the underlying computer" (such as being binary, having a file system, etc.) attitude.

As for "good girls don't", what about multiple precision arithmetic? Every processor I've learned assembler for has had support for multiple precision arithmetic (carry flags, n bits times n bits -> 2n bits multiplication (if there was multiplication), etc.) built in. I have yet to see any high-level language that exposes this functionality. - RS has seen this feature advertised in Scheme and Ruby at least. It was discussed for Tcl too, there is the mpexpr extension, and Arbitrary Precision Math Procedures. - Lars H: I meant the provisions made in the processor for this, not to necessarily have arbitrary precision arithmetic implemented (although in Tcl it should be, in some form). Since C does not attempt to expose this functionality (readily available in most processors), I suppose it has to be deemed a "Good girls don't do multiple precision arithmetic" language.

Donal Fellows (21 October 2002):

Tcl's really another "good girls don't" language in relation to code layout; the way Tcl works fundamentally discourages people from starting "blocks" (yeah, I know Tcl doesn't really have them, but virtually everyone codes as if it does) on a different line than the command with which they are associated. It's possible (with some help from backslashes) to use the style that puts open braces on their own line, but it is so much more typing and so forced that Tclers don't...

That's more of a "good girls won't" issue -- the virtue possessed by these good girls being laziness.

But.. about optimization and strong typing: the truth here might not be immediately obvious to everyone. For example, consider how current versions of tcl don't have first-class arrays. It's true that if tcl were a strongly typed language, the tcl compiler (*whimper*) would be able to perform certain optimizations in the context of array usage that would somewhat speed up the performance of this code. Nevertheless, other benefits are plausible if the language simply introduces array as a first-class type. why????

DKF - See TIP#111[3] though it should be noted that first-class values in Tcl are always immutable; mutability is a property of variables, not values.

Peter Lewerin (2003-03-12): Donal, I don't think Tcl qualifies wrt code layout. In Python, indentation is significant because (to put it simply) GvR hates badly indented code and would like to see it abolished. In Tcl, you can't put open braces on their own lines because the line-equals-command rule contributes to Tcl's syntactic simplicity.

DKF - Well, I think he's right to hate badly indented code. I do as well, though I also happen to think that it's easy to fix that with an appropriate software tool. What I was really talking about was the following (C) fragment:
  for (i=0;i<n;i++)
    {
      if (i==x)
        {
          do(something);
        }
    }

That's properly (if unusually) indented, but not a style that's at all supported by Tcl. You can get close with the help of backslashes, but the language is fundamentally inimicable to it...

wdb 2006-05-15 It is a matter of taste. My Emacs does all the indentation the electrical way:
 for {set i 0} {$i < $n} {incr i} {
     if {$i == $x} then {
         do something
     }
 }

It is even possible to write this:
 for {
     set i 0
 } {
     $i < $n
 } {
     incr i
 } {
     if {$i == $x} then {
         do something
     }
 }

The fact that opening braces cannot have their "private line" does not bother me; moreover, I really prefer this style (well, my taste ...)

DKF (2006-May-16): But some people insist on the brace-on-its-own-line style, and they always have problems with Tcl. Those of us who prefer the brace-on-end-of-previous-line style have far fewer problems with Tcl's syntax. :-)

Of course, Tcl does have a real "good girls don't" issue, and that is pointer arithmetic which it really really doesn't support. Pointer arithmetic isn't the root of all evil, but it's the source of endless trouble when you've got it. Standard Pascal and Java are also by-and-large free of pointer trouble too, as are many other languages more common in the research world. Pointer math is only somewhat useful when you're doing something very nasty and low-level (like hardware drivers)...

wdb 2006-May-16 Well ... procedure names and object instance names are true pointers. Even if they are strings. But, I agree, no pointer-hell.

WL -- OTOH, I'm not sure what's worse for pass-by-reference: */& in C, or trying to keep uplevel/upvar straight. I hate having to give up a good variable name to upvar...

AMG: DKF, leave that sort of thing to the lower tier language (C), and expose the functionality (not the implementation!) to the higher tier language (Tcl). Build as much of the system as possible in Tcl to minimize the total quantity of nasty. :^)

RS: Not exactly pointer arithmetics, but parts of it are modelable in Tcl:
 char[] str = "hello, world!";
 char* cp = str;
 puts(cp+7);

corresponds somehow to Tcl's
 set str "hello, world"
 set cp $str
 puts [string range $cp 7 end]

:^)

DKF: No, since if you change the original string between taking the reference and printing the string, you get a changed message in C but not in Tcl.