tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: style change: explicitly permit braces for single statements



> E.g. web browsers just reflow the text when you change the window
> width.  Why don=E2=80=99t we have this for code editors?

Short answer: try to build it and you'll see.

Longer answer: Because the exact layout of `words' affects readability
of code far more than it does running text.  Consider

	Longer answer: Because the exact layout of `words' affects
	readability of code far more than it does running text.

	Longer answer: Because the exact layout of `words'
	affects readability of code far more than it does
	running text.

	Longer answer: Because the exact layout of
	`words' affects readability of code far more
	than it does running text.

	Longer answer: Because the exact layout
	of `words' affects readability of code
	far more than it does running text.

To a first approximation, all are equally readable.

Now consider

 for (i=0;i<32;i++) ring[i] = 0;
 j = 0;
 for (i=0;i<32;i++) j = map[j];
 for (i=0;i<10;i++)
  { ring[j] = 1;
    j = map[j];
  }

	for (i=0;i<32;i++) ring[i] = 0; j = 0; for (i=0;i<32;i++) j =
	map[j]; for (i=0;i<10;i++) { ring[j] = 1; j = map[j]; }

	for (i=0;i<32;i++) ring[i] = 0; j = 0; for
	(i=0;i<32;i++) j = map[j]; for (i=0;i<10;i++) { ring[j]
	= 1; j = map[j]; }

	for (i=0;i<32;i++) ring[i] = 0; j = 0; for
	(i=0;i<32;i++) j = map[j]; for (i=0;i<10;i++) {
	ring[j] = 1; j = map[j]; }

	for (i=0;i<32;i++) ring[i] = 0; j = 0;
	for (i=0;i<32;i++) j = map[j]; for
	(i=0;i<10;i++) { ring[j] = 1; j =
	map[j]; }

IMO, none of those are even close to as readable as the first one.  I
suspect that even those who don't like the style of the first one will
find it more readable than any of the reflowed versions.

The problem is that introducing line breaks into code in a way that
doesn't slaughter readability is a hard problem.  There are tools, like
indent, that try to partially solve it.  Some of them don't do too
horrible a job, but even they fail catastrohpically in some cases (as I
remarked upthread, I've yet to see a rule that won't cripple
readability in at least a few cases.)  I suspect doing it *well* is an
AI-complete problem; in support of this stance, note that humans often
disagree as to which of various alternatives is more readable, and note
also that tools like indent invariably utterly trash readability in
various extreme cases, cases in which humans have the aesthetic
judgement to realize that rules must sometimes be broken to preserve
minimal readability.

The analogous problem for text does exist, mostly with poetry.
Consider, for example, something like

	Thus has it been told in the ancient recountings
	        Of those who before us were here
	And their kinds and their ways, the Valar, most terrible,
	        Holy, and bless'd, and revered.

Simply reflowing that

	Thus has it been told in the ancient recountings Of those who
	before us were here And their kinds and their ways, the Valar,
	most terrible, Holy, and bless'd, and revered.

rather mangles it.  Now try to fit it into a narrow column.  Just
reflowing for a narrow column gives

	Thus has it been told in the ancient
	recountings Of those who before us were
	here And their kinds and their ways,
	the Valar, most terrible, Holy, and
	bless'd, and revered.

and it's not obvious, even to a human, how to lay it out so as to both
preserve the poetic structure and fit it into a narrow column.  Here's
about the best I've been able to do:

	Thus has it been told
		in the ancient recountings
	  Of those who before us were here
	And their kinds and their ways,
		the Valar, most terrible,
	  Holy, and bless'd, and revered.

but even that doesn't look nearly as nice, to my eye, as the original.

I've occasionally thought about trying to build tools that treat C code
(because C is what I mostly work in these days) as a stream of C
tokens, ignoring layout, for purposes like diff.  It would be much
harder to do so for purposes of code editing, because the clearest
layout depends heavily on semantics.  For example, in general, I would
tend to format else-if chains more or less like this:

	if (...)
		...
	else if (...)
		...
	else if (...)
		...
	else
		...

But I've seen cases where (I think) it's clearer to do things that, in
other contexts, would look bizarre:

	     if (!strcmp(s,"one"     )) v = 1;
	else if (!strcmp(s,"two"     )) v = 2;
	else if (!strcmp(s,"three"   )) v = 3;
	else if (!strcmp(s,"ten"     )) v = 10;
	else if (!strcmp(s,"hundred" )) v = 100;
	else if (!strcmp(s,"thousand")) v = 1000;
	else badarg(s);

Making the parallel code structure into parallel visual structure is
compelling enough that it gets me to do things like introduce what
would otherwise be spurious whitespace before the first if and inside
parens.  As a more extreme example,

	switch (value)
	 { case 1: s = "one";     if (0) {
	   case 2: s = "two";   } if (0) {
	   case 3: s = "three"; } if (0) {
	   case 4: s = "four";  }
	      ...do common stuff with s...
	      break;
	   ...other cases...
	 }

That's one of the very few uses I've found for if (0), and when the
per-case code is as small as in this example I find that formatting to
be the overall best.  But it flies in the face of all sorts of rules.

That sort of judgement call is a hallmark of an AI-complete problem.

/~\ The ASCII				  Mouse
\ / Ribbon Campaign
 X  Against HTML		mouse%rodents-montreal.org@localhost
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B


Home | Main Index | Thread Index | Old Index