readability of code

(page spawned from incr)

Martin Lemburg: I love readable code and using decr var 1 is more readable than incr var -1, or am I wrong?

RS In matters of taste, one's self is mostly right, and everything else appears to be wrong;-) I think the philosophy for not introducing a decr command analog to incr was that incr <varname> -<increment> does the same job, and makes the language smaller.

KPV Along the lines of your "matters of taste" quip, I've always like the following quote:

 "I have heard frequent use," said the late Lord Sandwich, in a debate
 on the Test Laws, "of the words 'orthodoxy' and 'heterodoxy;' but I
 confess myself at a loss to know precisely what they mean."
 "Orthodoxy, my Lord," said Bishop Walburton, in a whisper,--"orthodoxy
 is my doxy; heterodoxy is another man's doxy." --Priestley: Memoirs,
 vol. i. p. 572.

LCS: Which is why it should've been called "bump" or "next" rather than "incr". C'est le garre.

A smaller language may be better readable than a bloated one, because the reader can more easily have full grasp of the language. On the other hand, you extend the language everytime you write a proc... The tradeoff between personal requirements (which might lead one to write a decr proc) and simplicity (which tries to avoid too many extensions to the language, and also has to do with efficiency) has to be part of every design decision. I prefer (of course) shorter code without many extensions. When I started Tcl, I was very proud that I could create language elements like lassign, to spread a list to scalar variables, but over time I've come to think that

 foreach {a b c} $list break

is readable (if one knows how to read it) and standard Tcl, while

 lspread $list to a b c

(that's how my version looked) requires either reading or "intuiting" the definition of lspread, one costing time, the other possibly misunderstandings, so I don't do such things no more.

Variable names: While there is an understanding that variable names should convey some intention, it is still a matter of style whether one prefers

 set fp [open $fn] ;# to
 set file_pointer [open $file_name]
 set filePointer [open $fileName] ;# or any other variant

For frequent concepts like file pointers, RS prefers short names like fp; rarer concepts are better fully spelled out.

LCS: Some years back I ran into a C compiler that chose registers based on the length of the name of the variable - i, and j would usually go into registers, TimeIncrement would usually not. This code was vastly simpler than counting the number of uses of the variable to decide which should go in a register. And it worked just as well, when applied to most programmers code. Just because the above is a common prejudice.

Oh, fer crissakes. I coded decr the way I did because I have learned to use a structurally maintainable form; where error handling and output packaging can be bloated at will as necessary. I agree 100% with RS that his form is more better for, say, tcllib. And I think that 'decr foo' is easy for a brain-damaged c++ or java coder to understand, so that's why it's there. I also call the argument 'int' for the same reason that RS calls fp fp. I feel like a shmuck for feeling like I needed to explain myself.

RS: Oh come on.. we're just discussing... In C, checking and reporting errors is of course necessary. But in Tcl I only add error tests and message when I feel I can do it better than Tcl. My "unguarded" variant just runs into incr's errors:

 can't read "j": no such variable
 expected integer but got "foo"

which I think tell it well enough ;-)

Until it's 15 levels deep in roguish dungeon of code and it comes bubbling up all unadorned from... where? And errorInfo is just too verbose. I create my own call stack by returning my own errors, i.e.:

 foo: bar: baz: jimmy: decr: expected richard but got "attitude"

RS;-) A 15-level deep roguish dungeon of code probably isn't that readable either... One of my mottos is: Tcl was made to make things easy... go and do the same. I'm amazed when I read that folks write a 125k LOC app in Tcl - but I'm even more amazed when I see a half page of code that does an awful lot (and is, just by virtue of its shortness, better readable than a multi-pager). I'm tending towards a spirit of economy: use as little variables (procs, LOC) as possible to do the job. (That's why I'm also interested in functional programming, where assignments to variables is something like a cardinal sin ;-)

Even if that 125k LOC app is a fault tolerant data management and analysis system that was written in 4 years vs. 2 million lines of C++ that would take 20 years? I'm not talking man years here, I'm talking project time. Tcl scales. Tcl scales well. I like writing 20 line servers in Tcl too, but sometimes you have got to do the dirty business ;^)

KBK - One of the least readable pieces of code that I ever had to deal with (that wasn't intentionally obfuscated) was the original Bourne shell, which had C code that began with

  #define begin {
  #define end }

and similar stuff, to make it look like Algol. What's the moral of this tale? Probably to write in the idiom of the language you're given, rather than to modify it radically. That's why I'm of two minds about Richard's attempts at Radical language modification. They are wonderful tours de force at showing how far Tcl can be taken, but they simply aren't Tcl style.

LCS: No, they aren't - but programming languages need to grow and improve, and such mods are a powerful way to test out new ideas. And as for "Tcl Style" - I don't think there should be one. Tcl is hugely expandable, syntactically as well as every other way. It's only real style is to be an implementation chassis for building a language designed to talk about your application - not to force you to talk about your application in Tcl. This same concept was an original part of LISP - you weren't supposed the see the parens and s-expressions, it was supposed to have a friendlier syntax in front of it, but they didn't get around to it before LISP became popular and grew a large user base of code.

Arjen Markus Kernighan and Pike's book "The practice of programming" contains some useful comments on this very same subject.