allowing braces around suites

  • Thread starter Kjetil Torgrim Homme
  • Start date
R

Reinhold Birkenfeld

Isaac said:
Kjetil> that's a hack, and IMHO not worthy of a Python program.
Kjetil> not even Perl has anything like that, AFAIK.

Hm... hacks are not for Python?! We see every kind of hacks
everywhere in Python just like it is in Perl, like (2,) syntax, etc.

Why would you call (2,) syntax a hack?

If you like, you can call tuple([2]), but I would consider _this_ an
ugly solution or a "hack".

Reinhold
 
A

Alex Martelli

Kjetil Torgrim Homme said:
code I read can be using "#fi", "# end if", "# }", "pass" or nothing.
sure, I can write a tool to enforce a single coding standard for my
project, but external code will naturally not comply. that's why I ...
my hope is that my solution can be ignored by those who don't need it,
and used by those who like it.

Unfortunately, if you make it optional, "external code will naturally
not comply" still applies. Either for your solution or for any of those
you list above, you need in any case a simple tool that will take
noncomplying (but otherwise assumed to be correct) code and insert the
terminators. Given that you need this tool, why not also have the tool
able to CHECK that a module complies? This way you don't need to change
Python to give a syntax error for non compliance.

Best of all, the hypothetical tool almost exists, you have it:

....whereveryoukeeppython.../Tools/scripts/pindent.py

It uses the '# end if' style, but you could alter that in your copy.
The 'almost' is because I don't think it has the 'just check and tell me
if something wrong' functionality -- it's just able to insert or remove
the terminators into/from an otherwise correct source, and to fix up
indents in a source file which has proper terminators -- from the
latter, a switch to have it just check shouldn't be hard to add (exit
with error indicator if any fixup would be needed, say).


Once you have scripts that do whatever checking you wish and have a
uniform specified way to signal errors, you could think of a general and
truly useful addition to Python: a commandline switch (ideally settable
as a sys. attribute at runtime too) that makes it run checking scripts
automatically as part of the compilation process when it imports any
source (.py) file. This would put pay to the problem common to all
"offline" checkers -- "the checker would have diagnosed the problem but
I did not run it". You could run pindent, pychecker, unit tests,
_whatever_ -- possibly at the price of slowing down imports of newly
edited sources, but that depends on how thoroughly you want to check,
only. What we need, I think, are good conventions to determine what to
run on the source (before compilation), what on the bytecode (right
after compilation, or possibly even, every time, even when importing a
bytecode .pyc file), how a checker lets Python know about problems, how
Python in turn diagnoses them to the user.

Hmmm -- I'm thinking that the existing import hooks might be enough to
let one prototype this "automatic checking" functionality, not quite as
smoothly as a fully architected system maybe, but enough to get some
early adopters, shake out teething problems, build a constituency to
lobby for smoother integration in a future Python version...


Alex
 
R

Roel Schroeven

Kjetil said:
[Roel Schroeven]:
Just the time needed to read the code.


No offense, but I wonder why you have a problem with this
code. IMO the indentation makes perfectly clear what's happening.


I don't think it is appropriate that I dump thousands of lines of code
here to illustrate the problem :)

when I provide four lines of code and tell you there's a bug, of
course you can spot it immediately.

I immediately saw what the code does; at first I didn't know it was the
bug you were referring to since I don't know what the code is supposed
to do. Then I read 'only students have their data updated' as
description of the bug, and only then I knew that the commit was
incorrectly indented.
when it's part of a large system,
it's a bit harder. also consider that the db.commit() originally was
correctly placed by the programmer, and the wrong indentation was
introduced later by an editing glitch.

In that case, I agree it can be harder. But IMO it gets harder with
increasing code complexity, whether braces are used or not. I haven't
yet seen very complex python programs, but I have seen C and C++ code
with multiple nesting levels, and let me assure that it can sometimes be
very difficult to spot errors.
 
K

Kjetil Torgrim Homme

[Roel Schroeven]:
In that case, I agree it can be harder. But IMO it gets harder
with increasing code complexity, whether braces are used or not. I
haven't yet seen very complex python programs, but I have seen C
and C++ code with multiple nesting levels, and let me assure that
it can sometimes be very difficult to spot errors.

indeed, C or C++ is no better in this respect, quite the opposite IMO.
Paul McGuire illustrated the corresponding problem in C:

db->update_name(person);

if (is_student(person))
log("update student %s", person->name);
db->update_courses(person);
db->commit();

I think it's harder to spot the bug here than in my Python example.
this doesn't mean Python can't be improved further :)
 
I

Isaac To

Kjetil> I think it's harder to spot the bug here than in my Python
Kjetil> example. this doesn't mean Python can't be improved
Kjetil> further :) -- Kjetil T.

I don't think your proposal to throw { and } into the code will solve
the problem and make it easier, though.

Regards,
Isaac.
 
G

Grant Edwards

Why would you call (2,) syntax a hack?

Because so many people at first think that parens construct
tuples the way square-brackets and curly-brackets construct
lists. When in reality it's commas that construct tuples, but
only in certain contexts because commas are used for about
three other purposes as well.
If you like, you can call tuple([2]), but I would consider _this_ an
ugly solution or a "hack".

I would call it the former.

IMO, the only non-ugly, non-hack solution would be to have
another set of delimters that are used as tuple-constructors so
tha the syntax for a literal tuple, a literal list, and a
literal dictionary are consistent.
 
G

Grant Edwards

Because so many people at first think that parens construct
tuples the way square-brackets and curly-brackets construct
lists.

Um, that should have finished with "and curly-braces construct
dictionaries."
 
R

Roy Smith

Grant Edwards said:
Because so many people at first think that parens construct
tuples the way square-brackets and curly-brackets construct
lists. When in reality it's commas that construct tuples, but
only in certain contexts because commas are used for about
three other purposes as well.
[...]
IMO, the only non-ugly, non-hack solution would be to have
another set of delimters that are used as tuple-constructors so
that the syntax for a literal tuple, a literal list, and a
literal dictionary are consistent.

I agree. It's even uglier that "," doesn't form a zero-length tuple.
Thus you get:

tuple0 = ()
tuple1 = 1,

So, is it parens that form tuples, or commas? I guess There's More Than
One Way To Do It :)

My personal choice would have been angle brackets, i.e. <1, 2, 3>.
Then, <1> would have been a length-1 tuple with no ambiguity.

tuple0 = <>
tuple1 = <1>
tuple2 = <1, 2>

But it's way too late for that now. Maybe in P3K?
 
A

Alex Martelli

Grant Edwards said:
IMO, the only non-ugly, non-hack solution would be to have
another set of delimters that are used as tuple-constructors so
tha the syntax for a literal tuple, a literal list, and a
literal dictionary are consistent.

I think that a hypothetical greenfield-designed language similar to
Python might do without literal tuples, lists, and dictionaries, just
like Python today does without literal sets (in 2.4 where they're a
built-in type). It would make some constructs more verbose,
specifically using words instead of punctuation, but I think that,
overall, that is reasonably Pythonic.

list(a, b, c) instead of [a, b, c] would not be horribly heavy syntax, I
think. You can already use list() instead of [] -- just as dict()
instead of {} -- and I think sometimes that's more readable, even having
both choices. tuple would work like list. dict isn't quite so obvious,
except where the keys are constant strings that happen to be identifiers
in which case, even today, dict(a=1,b=2,c=3) is fine. But I'm sure fine
solutions could be identified, as, also, for the issue of how to
differentiate from list(x) meaning [x] and list(x) meaning the same as
[foo for foo in x] -- for example list(*x) would also mean the latter,
so maybe that's the solution for this.

I think 'commas makes tuples when the commas don't mean anything else'
should stay, though, because somedict[x, y] or a,b=b,a depend on that,
and I find them just too sweet to lose!-)

This of course is all pretty hypothetical, just like the idea of
introducing a new set of delimiters -- won't happen in Python, not even
in 3.0. Just musing about some details of language design.


Alex
 
I

Isaac To

Alex> list(a, b, c) instead of [a, b, c] would not be horribly
Alex> heavy syntax, I think.

On the other hand, [b*b for b in c] is too sweet to lose as well. :)

Regards,
Isaac.
 
G

Grant Edwards

IMO, the only non-ugly, non-hack solution would be to have
another set of delimters that are used as tuple-constructors so
tha the syntax for a literal tuple, a literal list, and a
literal dictionary are consistent.
[...]

I think 'commas makes tuples when the commas don't mean anything else'
should stay, though, because somedict[x, y] or a,b=b,a depend on that,
and I find them just too sweet to lose!-)

This of course is all pretty hypothetical, just like the idea
of introducing a new set of delimiters -- won't happen in
Python, not even in 3.0. Just musing about some details of
language design.

Mostly it won't happen because there just aren't enough
delimiters in any common characer set for everything --
especially if you want indexing and function-calling to have
postfix-operator-delimters that are unique from all of the
aroundfix-literal-contsructor-delimiters.

Or something like that.
 
R

Roel Schroeven

Kjetil said:
indeed, C or C++ is no better in this respect, quite the opposite IMO.
Paul McGuire illustrated the corresponding problem in C:

db->update_name(person);

if (is_student(person))
log("update student %s", person->name);
db->update_courses(person);
db->commit();

Sorry, I meant "C or C++, even with consistent use of braces", implying
that using braces IMO in general doesn't help spotting this kind of bugs.
 
A

Alex Martelli

Isaac To said:
Alex> list(a, b, c) instead of [a, b, c] would not be horribly
Alex> heavy syntax, I think.

On the other hand, [b*b for b in c] is too sweet to lose as well. :)

But list(b*b for b in c) is essentially the same thing, and already in
Python 2.4 it works just fine.


Alex
 
J

Jeremy Bowers

Hmmm -- I'm thinking that the existing import hooks might be enough to
let one prototype this "automatic checking" functionality, not quite as
smoothly as a fully architected system maybe, but enough to get some
early adopters, shake out teething problems, build a constituency to
lobby for smoother integration in a future Python version...

You know, I'm totally unexcited about the syntax stuff this thread is
putatively about, but running automated testing over newly imported stuff
sounds kind of useful, not just for development but deployment as well;
"forcing" the users to run the tests once and report problems could be
very useful in some contexts.

I already tend to name my unit tests for file "x.py" as "tests/xTest.py"...

Maybe something that looks for a __validate__ function taking no args in a
module and runs it if the code was imported and newly compiled, combined
with a few convenience functions for the common cases?

I'm not *quite* familiar with the import hook stuff to knock this off
right away. I tried prototyping it but got stuck on how to determine if a
Python file already has an up-to-date .pyc file. (Although I guess there
may be external dependencies... well in the interest of keeping it simple,
deal with that later.)
 
J

Jeremy Bowers

And be sure that the Python community
does not need to be educated about what "real world" code looks like.

For evidence, see the recent thread on "average Python programmer age".
While the newsgroup may not be represenatative, I am surprised to be as
much of a yung'un as I am at 25.
 
I

Igor V. Rafienko

[ Paul McGuire ]

[ ... ]
In fact, you can cite examples on this argument in either direction;


I am a bit curious, what are the arguments _against_ an explicit
end-of-block marker? Does such a marker create any problems? (I know
that it solves a couple, though).

As a side note -- my last employer had absolutely horrible coding
conventions. No one liked them (developers and management included).
However, everyone had to comply, and despite an occasional nastiness,
the bug that you illustrated could not have happened in that
environment, because _every_ if was required to have its body within
braces.

[ ... ]





ivr
 
C

Christophe Cavalaria

Igor said:
[ Paul McGuire ]

[ ... ]
In fact, you can cite examples on this argument in either direction;


I am a bit curious, what are the arguments _against_ an explicit
end-of-block marker? Does such a marker create any problems? (I know
that it solves a couple, though).

It's unpythonic ?
As a side note -- my last employer had absolutely horrible coding
conventions. No one liked them (developers and management included).
However, everyone had to comply, and despite an occasional nastiness,
the bug that you illustrated could not have happened in that
environment, because _every_ if was required to have its body within
braces.

Well, there are worse coding conventions than that. Remember that chaining
unbraced if and else if becomes ambiguous.
 
A

Andrew Durdin

Well, there are worse coding conventions than that. Remember that chaining
unbraced if and else if becomes ambiguous.

Oh yes. I was bitten again by that just a couple of days ago. I had:

if(sometest)
do(this);
else
do(that);

And needed another (separate) test for do(this), so naturally changed
the code to be:

if(sometest)
if(othertest)
do(this);
else
do(that);

It made me wish I was writing the program in Python -- no silly braces
to have to put in there :)
 
I

Isaac To

Igor> I am a bit curious, what are the arguments _against_ an
Igor> explicit end-of-block marker? Does such a marker create any
Igor> problems? (I know that it solves a couple, though).

(1) it solves nothing unless it is universally used, (2) universally
using explicit braces makes even simple functions long, and (3) long
functions are bad because they are hard to comprehend (once you can't
put a function into a single screen you lose a lot). I believe the
net effect of adding explicit braces is much worse than what we have
now.

Regards,
Isaac.
 
A

Alex Martelli

Jeremy Bowers said:
You know, I'm totally unexcited about the syntax stuff this thread is
putatively about,

Hmmm, yeah, it DID start out about braces, didn't it?-)
but running automated testing over newly imported stuff
sounds kind of useful, not just for development but deployment as well;
"forcing" the users to run the tests once and report problems could be
very useful in some contexts.

I agree with you entirely.

I already tend to name my unit tests for file "x.py" as "tests/xTest.py"...

I tend to use tests/test_x.py, myself, but here we're back to discussing
syntax sugar again;-).
Maybe something that looks for a __validate__ function taking no args in a
module and runs it if the code was imported and newly compiled, combined
with a few convenience functions for the common cases?

I'm not *quite* familiar with the import hook stuff to knock this off
right away. I tried prototyping it but got stuck on how to determine if a
Python file already has an up-to-date .pyc file. (Although I guess there
may be external dependencies... well in the interest of keeping it simple,
deal with that later.)

Hmmm, I could be wrong, but I think you have to check timestamps and
'magic' signatures yourself. Pity, because imp.load_module must also do
that, but I don't think it makes this logic available separately.
Still, I believe Demo/imputil/importers.py has all the code you need.


Alex
 

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

No members online now.

Forum statistics

Threads
473,992
Messages
2,570,220
Members
46,807
Latest member
ryef

Latest Threads

Top