Compare source code

S

Seebs

If it's that obvious, why do people keep causing those indentation-
related bugs in C?

I don't think they do. I can't remember the last time I've seen one.
I'm glad for you that you have a finely trained attention to detail that
is able to instantly spot misindented C code (or is that misplaced braces
and correctly indented?), but it is a notoriously common error which
suggests that it's not anywhere near as obvious as you think.

It's "notoriously common", but can you show me an actual example of
it happening in real code? Not a "hey guys look how misleading this
would be" example conjured up for illustration, but an *actual* example
in live code?

I can't remember one, except I think maybe I saw one somewhere in...
hmm. No, wait, that was perl.
I question that assertion. Good engineering practices is about setting
best practices, and following them, not avoiding them because there might
be the odd exception here and there.

I don't think I buy this. I've seen a whole lot of good writers and good
programmers, and in both groups, they consistently report that you have
to know how the rules work before you break them.
The language shouldn't make
everyone carry the burden of supporting two-page functions all the time,
just to save you an insignificant amount of trouble on the vanishingly
rare occasion you need a function that is two pages long.

I don't think there's a particularly big burden there.

Explicit is better than implicit. It is *better* to explicitly mark the
ends of things than to have it be implicit in dropping indentation. That's
not a burden, it's good engineering practice.

-s
 
S

Seebs

I question that.
You've claimed that you have to deal with broken indentation on a regular
basis.

I'd guess I see something which got screwed up somehow every couple of
weeks, usually while refactoring stuff.
Python does have some redundancy against indentation mangling. Not all
combinations of indentation are legal.

True, but it doesn't seem to catch the most common failure modes.
And so on. True, there are some failure modes which can't be easily
recovered from without reading and understanding the code. That's okay.
Such failure modes are vanishingly rare -- for every twenty thousand
braces you avoid typing, you might, if you're unlucky, need to fix an
instance of broken indentation.

This is ridiculous overstatement. Moving a single block of overly-nested
code out into a separate method could generate several indentation
mishaps if Something Goes Wrong, which it does sometimes. I haven't
written more than a couple hundred blocks in Python, so I'm a factor of a
hundred out from twenty thousand braces, and I've had six or seven
indentation problems.

And yes, I can just recreate it, but it takes more effort, since I can't
do things like just handing it to an automated tool that can correct
it completely automatically.

Furthermore, I don't WANT to skip closing braces. EXPLICIT IS BETTER
THAN IMPLICIT. I *WANT* to have the beginnings and ends marked.

I want end braces or "end" or something at the end of a block for
the same reason that I prefer:
x = "hello, world"
to
x = "hello, world
where we just assume the string ends at the end of the line.
So you say.

Well, it works for me.

-s
 
G

Grant Edwards

Explicit is better than implicit. It is *better* to explicitly mark the
ends of things than to have it be implicit in dropping indentation. That's
not a burden, it's good engineering practice.

Dededenting does explicitly mark the end of a block.
 
T

Tim Harig

Yes, and I also said that I sympathized with him if he couldn't.

Perhaps it would be more constructive, for everybody, to make suggestions
on how to reliably transfer code using channels that distort whitespace.
No. The community does deal with it. It deals with it by saying "It isn't
going to change." If you want a language that forces you to wrap ever
block in BEGIN END tags, you have a thousand choices. Python is not one
of them. What is so hard to understand about this?

Please to not mix my contentions with somebody else's. I have not,
anywhere in this thread, asked to change the language. I certainly
didn't say *anything* about adding "BEGIN END" tags to the code itself.
I did say that I found code folding markers in the comments to be a
useful form for expressing code structure; but, that has nothing to with
chainging Python itself. I also expressed my opinion that I felt spaces
for indenting was a poor choice for the standard; but, since it is also
not part of the language proper, it can safely be ignored.

What I did suggest was a more constructive way of dealing with these
criticisms. You said that you found it "*incredibly* annoying" to have
this to see the same old "snide remarks" from "the same old people." I
merely suggested that if the community changes its attitude towards those
making those remarks, that it might go a long way towards silencing some of
those descents. The fact that you are unwilling to make these changes
makes me question your conviction when you claim to be so annoyed.
Yes, well that too goes both ways. *I* have a psychological communication
block that prevents me from hearing any complaints about the lack of
braces from people who refuse to acknowledge that having to type braces
is stupid and annoying, and that the use of braces in a language hurts
readability.

I understand that you don't like braces; but, I have nowhere advocated
adding them to the Python langauge. That is a different argument that you
are having with Seebs.
Frankly, I DON'T CARE how often your editor breaks your source code. I

Only you have even mentioned editors in this thread.
don't care about Seeb's mail server that converts his Python code to
HTML. I don't give a rat's arse about how many times some buggy ftp
client has mangled the indentation on Python files. Not my problem. Your

Nobody else mentioned ftp servers in this either; but, I must admit that
you are doing a good job of providing evidence for the alternate viewpoint.
pain is not my pain, and any solution to these problems that involves
changing the way I read and write Python code is an anti-solution to a
non-problem to me.

Then why bother adding to the noise in this thread at all since it has
nothing to do with you? I see however, since you have brought all this
baggage to the table that was not otherwise in the thread, that you
obviously have a axe to grind.
Until the "Python is broken 'cos it has no braces" crowd acknowledge this
fact, I just harden my heart against their complaints. Why should *I*
have to acknowledge their issues when they don't acknowledge mine?

Then please state your Python language issues rather simply grinding your axe
against those who are stating theirs.
 
S

Steven D'Aprano

I don't think I buy this. I've seen a whole lot of good writers and
good programmers, and in both groups, they consistently report that you
have to know how the rules work before you break them.

Yes. How does that contradict what I said?

There is a huge difference between knowing when to break the rules, and
avoiding the rules because there might someday be an exception.

I don't think there's a particularly big burden there.

Good for you.

Explicit is better than implicit.

Ah, argument by misunderstanding the Zen!

It is *better* to explicitly mark the
ends of things than to have it be implicit in dropping indentation.
That's not a burden, it's good engineering practice.

Python does explicitly mark blocks. It does it by changes in indentation.
An indent is an explicit start-block. An outdent is an explicit end-
block. There is nothing implicit in a change in indent level.

To illustrate the difference, this is how a hypothetical language might
use implicit end of blocks:


if condition:
true_clause()
another_true_clause()
else:
false_clause()


The if block ends implicitly when you reach an else statement, and the
else clause implicitly ends... where?

It gets worse:

if condition:
if another_condition:
true_clause()
else:
false_clause()
another_clause()


Such a hypothetical language might decide on a rule that else will always
match the closest if, or the outermost if that is legal. That would be an
implicit end of block. This is not even within the same galaxy as what
Python does.

It simply isn't possible to have implicit start/end block markers, unless
you restrict your language in ways that exclude most blocks. E.g. if all
if blocks were restricted to a single statement, then you could have an
implicit block -- the block in one statement. Stating that Python uses
implicit block markers is simply wrong.
 
S

Seebs

Yes. How does that contradict what I said?

Once you understand that you do have to break the rules occasionally,
it is a good idea to design things that will be robust when the rules
are broken.
Ah, argument by misunderstanding the Zen!

I see. So explicit boundaries are a good thing, except when they are
one specific special case.

Let us imagine a hypothetical mirror-universe person, who is otherwise
like you, but:

1. Has a goatee.
2. Actually hates the indentation rules, wishes Python had braces,
but has become emotionally invested in defending the status quo because
if he had to suffer, dammit, everyone else should have to suffer too.

You have not yet made a single argument that he wouldn't have made
too.
Python does explicitly mark blocks. It does it by changes in indentation.
An indent is an explicit start-block. An outdent is an explicit end-
block. There is nothing implicit in a change in indent level.

What's the token that marks the end of a block, corresponding to the
colon used to introduce it?
It simply isn't possible to have implicit start/end block markers, unless
you restrict your language in ways that exclude most blocks. E.g. if all
if blocks were restricted to a single statement, then you could have an
implicit block -- the block in one statement. Stating that Python uses
implicit block markers is simply wrong.

No, it isn't. There's no token telling you where the block ended.

C *allows* implicit blocks, and this is widely regarded as a key flaw.
However, it also allows you to explicitly mark blocks in a way which
is robust against common errors, allowing software to automatically
fix up differences between, say, competing indentation styles.

-s
 
M

Michael Torrie

Furthermore, I don't WANT to skip closing braces. EXPLICIT IS BETTER
THAN IMPLICIT. I *WANT* to have the beginnings and ends marked.

I suggest, then that Pascal or Ruby would suit your needs better than
Python.
I want end braces or "end" or something at the end of a block for
the same reason that I prefer:
x = "hello, world"
to
x = "hello, world
where we just assume the string ends at the end of the line.

Not even close to the same thing, sorry.

As for refactoring code, vim makes it really easy to move blocks in and
out. The only time I could see this becoming an issue is if functions
or blocks of code are too long to see on a page at once. If this is the
case, break them up. Sounds to me like your problems with refactoring
and indention in python could be do to these kinds of design issues.
Having curly braces certainly doesn't help in these situations either.
More than once I've had C code I was refactoring that broke due to the
fact that while trying to move blocks around I misplaced a brace, an
issue I never have in Python.

In the meantime, whitespace structure is one of the things about Python
that I like the *most* about the language. Being able to crank out
executable pseudo-code is pretty addictive. And I never write
pseudo-code on paper with begin and end blocks cause it's too much
effort when scribbling by hand.
 
S

Steven D'Aprano

I'm not expecting it to change;

Then why talk about it? Just to hear the sound of your voice? (Or see the
font of your writing?) To waste our time? To feel more virtuous than
those who don't see your point of view?

If you don't expect a change, what's the point of this discussion?

I'm pointing out that insisting that it's not a problem is
*insulting* to the people for whom it is a problem.


And insisting that it is a problem is equally insulting to those for whom
it is not a problem.
 
S

Seebs

Then why talk about it?

Because I find technical questions interesting in and of themselves. I
will happily talk with people about the reasons for which the C preprocessor
is the way it is, even though it's never going to change and we all
hate it like poison.
And insisting that it is a problem is equally insulting to those for whom
it is not a problem.

No, it isn't.

A friend of mine is colorblind. For him, certain red/green pairings are
indistinguishable. For me to insist that it is not a problem that a
user interface uses those to distinguish two things is insulting to
him; I am dismissing a very real problem. For him to insist that it
is a problem for him is in no way insulting me. He's not saying that it's
a problem for me. He's merely saying that *there exist* people for whom
it is a problem.

No one has claimed that this is a problem *for everybody*. Just that
there exist real-world workflows for which it is a problem, or people
for whom it is a problem.

This is an asymmetrical situation. The opposite of "it's never a
problem for anybody" isn't "it is always a problem for everybody"
but "it is at least sometimes a problem for at least some people."

The reality is, the indentation-instead-of-markers thing *does* sometimes
lead to problems. We could blame it on tools, but the tools could just as
easily blame the language for being brittle. Given the degree to which
the rest of the world has standardized on not caring how *much*
whitespace is between things (though sometimes caring whether or not
there's *any* whitespace between them), it seems to me that the odd
man out is the one who is creating the burden.

Once many file formats exist which don't care how many spaces you
use, and many tools have been developed with those file formats in
mind, coming up with a new file format which cares how many spaces you
use seems a little short-sighted. Demanding that all tools be changed
to fit a new paradigm is a pretty big demand to place on people.

On the whole, I don't personally think the benefits have been worth it.
I think Python would be a better, richer, language if it used explicit
end tokens of some sort. Maybe it wouldn't. I do know, though, that
of the programmers I know outside the Python newsgroup, not a single
one likes that aspect of Python. It is consistently regarded as an
annoying quirk. Some use Python anyway; it has merits, certainly. If
I were offered a choice between Python and PHP for a project, I would
*absolutely* pick Python. (Subject, of course, to the assumption that
the project would in some way involve computers, or programming, or
that I would at some point have to either write code for the project
use it, or possibly come within twenty feet of someone who was working
on it; outside of those limitations, I might consider PHP.)

I feel the same way about pretty much every language I use. C would
be a much better language if the macro processor weren't such a giant
filesystem verification stage for a filesystem distributed across
multiple machines*. They all have flaws.

Python's the only language I use where an obvious flaw, which is repeatedly
observed by everyone I know who uses the language, is militantly and
stridently defended by dismissing, insulting, and attacking the character
and motives of anyone who suggests that it might be a bit of a nuisance.

I suspect part of that is simply because it *is* a tradeoff, and there
are good reasons for it. It offers some advantages. It's not something
that you'd be insane to like; the problems are easily mitigated once you
know about them, and the benefits are worth it. If I worked with a lot
more novice-level C programmers who hadn't yet had the importance of
careful style drilled into them, I might well find the indentation problems
people keep talking about to be a real thing, possibly even a very
serious one.

But the fact remains, being brittle in the face of whitespace changes *is*
a flaw. It breaks code under circumstances which are, for better or
worse, common. As I pointed out before: There is a *REASON* that diff
has an option for ignoring whitespace changes -- because they are common
enough that such an option is commonly useful for distinguishing between
real changes and inadvertant ones.

Note that "whitespace indentation" in and of itself isn't the thing I'm
describing as a flaw; it's the side-effect of being brittle when whitespace
changes. The indentation thing as a whole has some definite plusses, and
it's a tradeoff that I think may even be a good fit for a language
specifically focused on easier readability.

-s
[*] clusterfsck.
 
S

Seebs

I suggest, then that Pascal or Ruby would suit your needs better than
Python.

In the absence of network effects, I'd just be using Ruby. I have reason
to work with projects that have a lot of existing Python, though, so I
use it too.
As for refactoring code, vim makes it really easy to move blocks in and
out.

Yes, though I mostly use nvi, same thing -- basically. The issue I've
had is that the automatic-tab thing (which I actively want for everything
else I edit) tends to make it quirky.
The only time I could see this becoming an issue is if functions
or blocks of code are too long to see on a page at once. If this is the
case, break them up. Sounds to me like your problems with refactoring
and indention in python could be do to these kinds of design issues.
Having curly braces certainly doesn't help in these situations either.
More than once I've had C code I was refactoring that broke due to the
fact that while trying to move blocks around I misplaced a brace, an
issue I never have in Python.

For me, I'd rather have the compiler choke because I have mismatched
braces than have the code run apparently just fine except that something
has unintentionally moved in or out of an else clause because there was
no marker. I've had both happen, probably.
In the meantime, whitespace structure is one of the things about Python
that I like the *most* about the language. Being able to crank out
executable pseudo-code is pretty addictive. And I never write
pseudo-code on paper with begin and end blocks cause it's too much
effort when scribbling by hand.

I never write on paper anyway. :)

Anyway, I'm not disputing that there are things that it makes nicer. I'm
just observing that there exists a category of failures which is completely
unique to Python, which no other language (except BF, which I'm not sure
I ought to count) has, which tends to show up occasionally until you've
gotten all the changed tools and habits, and even then can show up when
dealing with other people who use tools which, well, work perfectly for
everything else. But not for this.

Only other tool I know with a comparable dependance on spacing is Makefiles,
and I have never in my life met someone who used them and didn't think
that was a loathesome error which should never have made it into
production code. Python's not nearly as bad, actually. :)

-s
 
L

Lawrence D'Oliveiro

The question is *why* diff has that option.

The answer is because whitespace changes (spaces to tabs, different
tab stops, etcetera) are an extremely common failure mode, such that
it's quite common for files to end up with unintentional whitespace
changes.

Except the diff option is to *ignore* such differences, not highlight them.
 
L

Lawrence D'Oliveiro

It is extremely useful to me to have spaces converted to tabs
for every other file I edit.

I’m thinking of going the other way. After many years of treating tabs as
four-column steps, I might give up on them and use spaces everywhere.
 
E

Emile van Sebille

On 11/3/2010 4:09 PM Seebs said...
What's the token that marks the end of a block, corresponding to the
colon used to introduce it?


My thoughts tend more towards 'can we get Guido to eliminate the colon
requirements' -- The indent level of the next line ought to suffice.

Seriously.

Emile
 
S

Seebs

Except the diff option is to *ignore* such differences, not highlight them.

Yes. That's because those changes are irrelevant, so people don't
care about them, so they want an option to handle the common case where
whitespace got changed but no one cares about that.

But unintentional whitespace changes are common enough that you *need*
the ability to filter them out and just look at "real" changes.

-s
 
S

Seebs

I???m thinking of going the other way. After many years of treating tabs as
four-column steps, I might give up on them and use spaces everywhere.

I *absolutely must* use tabs for Makefiles.

For code in most other languages, it's merely a factor of 8 improvement
in storage. :)

-s
 
G

Grant Edwards

On 11/3/2010 4:09 PM Seebs said...



My thoughts tend more towards 'can we get Guido to eliminate the colon
requirements' -- The indent level of the next line ought to suffice.

But without the colon, how are people who write programming editors
going to know when to increase the indentation level as I enter code?
Seriously.

Just as seriously.

Syntactic sugar isn't just for humans...
 
G

Grant Edwards

I quit using tabs (except for Makefiles) about 30 years ago.
I *absolutely must* use tabs for Makefiles.

And my editor (emacs) knows that. It uses tabs in Makefiles and
spaces everywhere else.
For code in most other languages, it's merely a factor of 8 improvement
in storage. :)

That's only true if your source code consists entirely of tabs.

;)
 
S

Steven D'Aprano

Once you understand that you do have to break the rules occasionally, it
is a good idea to design things that will be robust when the rules are
broken.

That does not follow.

As a general rule, one should not expect that electronic equipment should
be safe to operate under water. But there are exceptional cases. So what
should we do?

(1) Insist that all consumer electronic equipment is designed to operate
under water? (All blocks need redundant START/END tags just in case
you're operating in an environment where indentation can't be trusted.)

(2) Tell people not to drop their toaster into the bath tub, and leave it
up to the exceptional cases to deal with the need for water-proof
electronics in whatever way they see fit? (Trust the indentation, tell
people not to mangle their source files with dodgy mail servers, and if
you need redundant tags, build your own solution.)


I see. So explicit boundaries are a good thing, except when they are
one specific special case.

INDENT/OUTDENT is an explicit boundary.

Let us imagine a hypothetical mirror-universe person, who is otherwise
like you, but:

1. Has a goatee.
2. Actually hates the indentation rules, wishes Python had braces, but
has become emotionally invested in defending the status quo because if
he had to suffer, dammit, everyone else should have to suffer too.

I had to suffer?

Funny, I hardly noticed.


You have not yet made a single argument that he wouldn't have made too.

The arguments Evil-Steven would make would be your arguments:

* redundant BEGIN/END tags make blocks robust in environments where
indentation can't be trusted;

* there are tools out there that assume that indentation is meaningless,
and some people want to use those tools, so the language is poorly
designed;

I *understand* your arguments, I just don't value them. But in fact, non-
evil Steven made the opposite arguments:

Re extra redundancy: you aren't going to need it often enough to make up
for the extra effort of dealing with BEGIN/END tags that can contradict
the indentation.

Re tools: if the tools don't fit your use-case, your tools are broken,
and you should change your tools.


What's the token that marks the end of a block, corresponding to the
colon used to introduce it?

Your assumption is incorrect. Blocks are introduced by an increase in
indentation level, not by a colon. The colon is enforced, but it's there
for the benefit of readability rather than to mark a new block. You can
write:

if condition: true_clause()
else: false_clause()

No blocks are started, the clauses are limited to a single line, but the
colons are still required.

To end the block, you need a decrease in indentation limit. In fact, the
Python parser actually places overt INDENT/OUTDENT tokens into the token
stream.

# From token.py:
INDENT = 5
DEDENT = 6

No, it isn't. There's no token telling you where the block ended.

I disagree, but for the sake of the argument let's suppose you are
correct. So what?

x = 123+456

There's no tokens telling you where the ints 123 and 456 begin and end
either. So where's the problem?

Signals, or tokens if you like, can be explicitly made either by placing
a distinct marker (a delimiter or separator), or by a change of state. In
the case of ints, the explicit end-of-token is a change of state, not a
marker:

digit digit digit non-digit

There's no need for a distinct End Of Int marker, because the change of
state is explicit enough. But this is not the case for strings, which you
mentioned in an earlier post. Strings require a special BEGIN/END tag
because they may be terms in expressions and you can't assume they will
end at the end of the line (a change of state).

If you have an environment where strings do end at the end of the line,
such as INI files, you can avoid the delimiters:

[section]
x = Hello world.
y = Goodnight Gracie!


but in a general purpose programming language where strings can be terms
in expressions, you need delimiters.

Blocks are more like ints than strings. They don't need delimiters,
because they start and end according to an explicit change of state.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top