They're like guard rails on the highway, they make totally explicit what is going on.
The 'but you're writing for other humans to read' argument imho is not 100% the truth, you're writing for both the computer and other humans to read.
Humans like the indentation, the braces make it explicit.
The computer doesn't care about the indentation, it just looks at the brackets.
Drop a bracket and you get an error, drop a couple of spaces and your program will happily continue to work, only not in the way you intended.
it's funny how even in languages that don't use 'begin/end' markers (such as python) there are extraneous characters, such as the () pair when calling a function (surely there are ways to do without that ?), or when making a list or a dictionary.
Some things come in pairs, and the beginnings and endings of blocks are such things.
In Pascal it was BEGIN and END, which seemed overly verbose, in C it was { and }, which seems about as minimal as you can go before you become invisible, and when you get invisible you lose something.
Try cutting and pasting some python examples from online fora and see how well it works without.
And try figuring out from a python program that has been created on a box with alternate tab settings what it's intended function was (yes, I know there are tools for that situation).
Begin and end block have meaning, they are 'there', and even if you don't strictly speaking need them they cost next to nothing and make me feel a lot more like things are spelled out to mean exactly what I'm reading.
I should probably start collecting python examples in the wild on the web where the indentation is clearly messed up so the code no longer works the way it is intended, this is a lot more common than you'd want. It is also very frustrating when learning a language.
So, please keep those braces.
'They're like guard rails on the highway, they make totally explicit what is going on.'
Using this logic, perhaps you should add some ASCII art to your source to denote blocks a third time? This is also a common practice. Do you feel the same about duck typing?
'The 'but you're writing for other humans to read' argument imho is not 100% the truth, you're writing for both the computer and other humans to read.'
Yes, that's true the computer also parses the code. You still haven't provided an argument why using seperate blocking formats is required.
'they cost next to nothing and make me feel a lot more like things are spelled out to mean exactly what I'm reading.'
The cost is evident: there are many cases of indentation not matching braces and vice versa, and the inconsistency between these causing confusion between the language and the humans trying to debug issues.
Tell me you've never looked for an unmatched brace in code you can otherwise parse?
I disagree. I know that the word "redundant" sometimes carries a negative connotation, but the truth is that it is a mere property whose value depends upon the context and associated tradeoffs.
Spacecraft have redundant systems, but those systems are far from superfluous.
Human languages have built in redundancies. Generally they are there for ensuring communication still happens in a noisy environment.
My music CDs have redundancy in the encoding, and thankfully at that: after years of accumulating scratches I could still rip them without loss of quality. Redundancy was a positive here too.
Redundancy is a tradeoff, not an automatic downside.
What loss are you preventing by requiring blocks be delimited twice?
Have you considered that inconsistencies due to repetition are frequently themselves cites as a cause of data loss?
Ever had code that looks good to you but doesn't parse because a machine is expecting an extra bracket?
I think jacquesm already mentioned the value of the redundancy above: you will never have a situation where a change in indentation leaves you with a runnable, but semantically-different program when you pasted code from a forum or from a machine with different tab settings. Note how the missing-bracket case in your last question is superior to this: a missing bracket offers fail-fast detection of the problem. If you indent a line wrong your program may still run, but differently: indent the last line of a block at the wrong level and it may happen after a loop rather than inside a loop.
The indentation is for the person. The braces are for the compiler. I like this, personally. I understand how some may prefer the python way (it has a superficial elegance, after all). But I personally don't like the downsides that jacquesm mentioned.
In that situation, with any computer language, you'll have an unreadable program. In Python, you'll need to fix the readability before the program will execute - which is a win to me.
for foo in bar:
foo.fizzle()
baz.wibble()
...versus... for foo in bar:
foo.fizzle()
baz.wibble()
...how would it know that I wanted to wibble the baz every time I fizzle a foo, as opposed to wibbling the baz only after all foo have been fizzled?Python executes your data the same way you yourself parse it: by how it appears. Brace requiring languages execute your data using different rules than you use to parse it.
Redundancy of logic is universally known to be a poor engineering practice.
Achilles: Why do you want to wear a helmet?
Tortoise: So that I won't hurt my head if I bump it.
Achilles: You won't bump it.
Tortoise: Suppose I do.
Achilles: You won't bump your head.
Tortoise: But suppose, hypothetically, that I fall off my bike and bump my head. What would protect it from injury?
Achilles: Your head is not injured, because you didn't bump it.
Tortoise: But that's the very basis of my hypothesis!
Achilles: Yeah, I'm going to just ignore you said that, and tell you again that you won't bump your head.
Tortoise: How do you know?
Achilles: Because you made sure that it didn't come into contact with anything.
Tortoise: Good night, dear Achilles. May you encounter others like you.
Fortunately, Python gives you:
* A helmet. It won't parse unblocked code like any other language.
I'm not sure why you think blocking a second time with brackets would improve things or avoid this risk. But hey, if you want to wear a second helmet, that's cool. May you encounter others like you. :^)
* A mirror where things are as large as they appear (the blocking looks like it executes), unlike other languages where these can get out of sync and cause problems. If you enjoy this risk, that's awesome. High five.
* A handy warning light should you accidentally stray too far to the wall (Python will telling you that your readability is broken at the same time it tells you your blocking is - and you only need one fix). If you'd prefer not to be told about this, two places to fix things, and enjoy receiving badly written code, that's your prerogative and who am I to say anything other than that it's not mine.
Achilles: Nice bike and helmet.
Tortoise: No!
Achilles: Er, ok. Could you explain?
Tortoise: I need to get a helmet!
Achilles: You're already wearing one.
Tortoise: But what if I fall?
Achilles: You're wearing a helmet, which will protect you.
Tortoise: But I need to get a helmet.
Achilles: No you don't, you're wearing one. Oh and by the way, you need to be visible at night. The helmet's reflective, so you probably don't want to cover it with another ...
Tortoise: You're not listening to me!
Achilles: I am listening, but I'm also disagreeing. Are you listening to my disagreement?
I apologize for wasting your time with my attempt at putting in to words what I was thinking, at your request no less.
Let me give you a simple example, in two psuedo languages, one with and one without braces:
if a > b
a = a + 5
b = b / 2
if (a > 0) {
a = a + 5
b = b / 2
}
vs if a > b
a = a + 5
b = b / 2
or if (a > b) {
a = a + 5
b = b / 2
}
Even though the text is similarly corrupted (for whatever reason) the redundancy in the second example makes it clear that something is amiss, you could even lose the second brace and still at least know that all is not kosher in that segment.That's not 'ascii art', that's functional.
Redundancy definitely has it's uses.
I'm going to do some digging later on and find a bunch of examples of broken code due to cut & paste problems, some of it on the django site, no less.
That's something that would never happen in C or any other 'overspecified' language.
And regarding 'finding that matching bracket' that is exactly what they're for, if you can't match the bracket chances are that you really do have a problem in the code.
if a > b
a = a + 5
b = b / 2
is quite different from: if a > b
a = a + 5
b = b / 2
Without needing a second markup for the compiler to emphasize the point.The point is that you can't know which one was the one that was meant to be written there in the first place, and all that changed is some literally invisible characters are gone.
It's like with comments and code, if a comment says 'add two volumes' and I see that the code does not do that then I have a hint that something is not correct.
It could be the comment or it could be the code, but there is something smelly there.
Redundancy = good.
Er, no. That's not the extent of the changes at all: the very visible code has shifted to the left. I refuse to believe you cannot see that with your own eyes.
'The point is that you can't know which one was the one that was meant to be written there in the first place'
In any language at all, the lack of indentation makes it quite clear the intention is different.
You asked what benefit might come from the redundancy of a curly brace, and this was a scenario in response.
Python also has the handy benefit of telling you this immediately.
jacquesm's statement about the visible difference is obviously false.
However I don't think it's doing anyone any good to keep contributing on this topic. All I was doing was making a suggestion to improve something. The troll who posted 'no' with no arguments has a bunch of supporters, I'm being moderated down to nothing. You're not responding to my points, and you seem to think I'm not listening to you, though I'm trying to understand what you're saying. I give up, this isn't worth it.
This problem only exists if indentation is significant in the language as a way of demarcating blocks. This is exactly the reason for the suggested syntactic redundancy. A reasonable person can accept the tradeoff, but it's not reasonable to insist that the tradeoff isn't there at all.
Edit: the proposed scenario is readable code. It is, in fact, disingenuous to ignore that. It isn't candid to claim apathy, either.
If you find that disingenuous, fine, I don't care anymore.
Edit: you consider badly indented code readable? You must be great fun to work with. :^)
I bet you meant "semantically correct" instead. Yes, every program's semantics need to be correct in order for the program to be correct. That's a tautology, and it's a deflection from the subject of the tradeoff analysis that you requested upthread.
You're probably a bundle of joy to work with, too. :^)
if (a > b) {
a = a + 5
b = b / 2
}
...is not considered readable brace-requiring language because it's appearance doesn't reflect what's executed.Ie:
* Python and similar languages would execute the code consistently with how it looks. This is good.
* A brace-requiring language would execute the code in a way that is not consistent with how it looks. This is not good.
Scroll up: I didn't request any analysis, I made a suggestion. Someone posted a blank 'no', and I asked them for a more civil explanation of their views.
Yeah, that's the request I was referring to.
Python and similar languages would execute the code consistently with how it looks. This is good.
It's good and bad. You win something, you give up something. This is the nature of a tradeoff. It's not like Python lives in an alternate universe where tradeoffs don't exist. But I'm beginning to think its advocates live in one where tradeoffs are invisible in broad daylight.
Having an opinion thrust at you does not equate to soliciting said opinion.
It's your responsibility to clearly state the benefits of what you're advocating. You don't seem to be able to do that.
I suggest you examine your own courteousness.
The () when calling a function with no arguments is not extraneous -- because Ruby lets you omit that, it needs yet another function type to disambiguate when you want a reference to a method (total of 4: Methods, Procs, Lambdas, and Blocks).
What is completely superfluous in the syntax is the colon preceding an expression suite -- you're already using a keyword and indenting the next line(s).
if x == foo:
# do things
if y == bar:
# do something
# do other stuff <-- at what indent level should this line live?
# get on with life
You and I know what that means given its indentation, but an autoindenter can't know what to do with the fifth line. It gets worse when you're moving blocks of code into different indent levels.Now, it's true that in this simple case, you could rewrite the snippet starting with:
if x == foo and y == bar:
# ...
# get on with life
but when blocks get long, this becomes less practical. And your autoindenter still doesn't know when to stop indenting and get on with life.As a result, in my Python code, I use otherwise gratuitous pass statements all over the place–ugly, but it does the trick.
if x == foo:
# do things
if y == bar:
# do something
pass
# do other stuff <-- at what indent level should this line live?
pass
# get on with life
My hypothetical ideal language (the one that's not lispy in outward appearance, anyway) would use braces but would also not run if any inconsistencies of indentation are found.This would be allowed:
if x == foo {
# stuff
# more stuff
}
But this would not: if x == foo {
# stuff
# more stuff <-- BAM!
}1. It mixes format with logic. Don't we all know this is one of the greatest evils one can commit?
2. Indentation is a bitch to parse compared with braces. Violates occam's razor of software of engineering -- simpler is better. Unnecessary complexity is the second greatest evil in software engineering.
3. Indentation is neither symmetrical nor logically unique. Therefore you can't delete all the formatting from a python program and expect a formatter to get it right. With symmetric braces a formatter always knows exactly what logical level it should be on by counting the number of closed braces; not possible with python's goofy system.
4. All that tiresome debate and worry over tabs versus spaces.
5. One can't really say "braces are redundant not indents" or "indents are redundant not braces". Redudency is commutative. I would say braces are for computers, indents are from human; it is simple to go from braces to indents but not so in the other direction.
Just a note -- I will always pick Python over any other scripting language. I just think the indentation is a serious mistake; there are so few other bad choices it tends to irk me that much more.
Re: parsing, read each line, if the indent is greater than the current indentlevel, add line to a new block, else, add line to existing block.
Tabs were considered harmful before Python, they're still considered harmful now.
You could add braces to Python quite easily, I think this has already been done in jest a few times...