Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Some more notes

Reply
Thread Tools

Some more notes

 
 
bearophile
Guest
Posts: n/a
 
      10-21-2004
Ville Vainio:
>It's highly typical for the newbies to suggest improvements to the
>language. They will usually learn that they are wrong, but the
>discussion that ensues can be fruitfull anyway .


Few more notes on the language. I don't know if I can really suggest
improvements to the language... but I hope to learn something

I think some things are better in Delphi/Pascal (like the := for
assignments instead of = and = for equality, that I suggested in the
my precedent notes):

1) The "print" and "printf" pair without automatically added spaces
between arguments, and with or without automatic newline, instead of
the current "print" command. Because adding lots of "+str()+" isn't
good for me (there's sys.stdout.write, but it's not built-in).
2) Adding "case var of:" can be useful.
3) "do while" (or "repeat until") can also be added, it's useful.
4) Maybe really raw strings RR"" can be added to avoid problems with
file paths on Win :-]

5) Inside function definitions, assignments of mutable types like this
can be forbidden and seen as errors by the interpreter:
def func(a=[1,2]):
...

6) Given:
a = [1]
a += [2]
a = a + [3]
The first assignment extends the list, and second creates a new list
and rebinds it. Why such difference for operations that look the same?
Isn't a kind of "error" to do different things with quite similar
looking commands?

7) There's something that I don't understand. I'm not a OOP purist,
but finding functions like this beside normal methods seems odd to me:
len(s) length of s
min(s) smallest item of s
max(s) largest item of s
For uniformity they can be:
s.len()
s.min()
s.max()
etc.

Thank you,
bear hugs,
Bearophile
 
Reply With Quote
 
 
 
 
Istvan Albert
Guest
Posts: n/a
 
      10-22-2004
bearophile wrote:

> I don't know if I can really suggest improvements to the language...


No you can't. Your suggestions are driven by nothing else
but your desire to make Python resemble Pascal since
that is the language that you are accustomed to.

Istvan.



 
Reply With Quote
 
 
 
 
Cliff Wells
Guest
Posts: n/a
 
      10-22-2004
On Thu, 2004-10-21 at 15:16 -0700, bearophile wrote:

> I think some things are better in Delphi/Pascal (like the := for
> assignments instead of = and = for equality, that I suggested in the
> my precedent notes):


Actually, since the assignment operator is used far more often than the
equality operator, making it require three keystroke rather than just
one is a bad idea.

> 1) The "print" and "printf" pair without automatically added spaces
> between arguments, and with or without automatic newline, instead of
> the current "print" command. Because adding lots of "+str()+" isn't
> good for me (there's sys.stdout.write, but it's not built-in).


Use string interpolation. However, I agree having print as a statement
rather than a function is a (very small) wart. Luckily it's easily
circumvented (and I've heard rumor that this is, in fact, slated to be
changed in Python 3000).

> 2) Adding "case var of:" can be useful.


Not familiar with this construct. If you mean "switch/case" as in C (or
some variation of same), then I absolutely agree.

> 3) "do while" (or "repeat until") can also be added, it's useful.


Occasionally useful. Not enough to put it high on my list of things I'd
like to see in Python, but I can see its utility for making *slightly*
more logical code (versus the "while True: if x: break" idiom).

> 4) Maybe really raw strings RR"" can be added to avoid problems with
> file paths on Win :-]


Not sure what problems you are referring to since I rarely use that
platform and the times I have used it I haven't had any issues. Do you
mean issues with "\"? Why not just use "/"?

> 5) Inside function definitions, assignments of mutable types like this
> can be forbidden and seen as errors by the interpreter:
> def func(a=[1,2]):


I don't see why valid Python syntax should be an error. Admittedly this
quite often bites new users of Python, but there are plenty of things to
confuse newbies, so I don't know why this particular construct should be
singled out, especially when there is a perfectly valid explanation of
the resulting behavior.

> 6) Given:
> a = [1]
> a += [2]
> a = a + [3]
> The first assignment extends the list, and second creates a new list
> and rebinds it. Why such difference for operations that look the same?
> Isn't a kind of "error" to do different things with quite similar
> looking commands?


I'd agree this can be confusing. However, like the mutable arguments
you mention previously, there is a logical explanation that suffices in
place of breaking tons of Python code.

> 7) There's something that I don't understand. I'm not a OOP purist,
> but finding functions like this beside normal methods seems odd to me:
> len(s) length of s
> min(s) smallest item of s
> max(s) largest item of s
> For uniformity they can be:
> s.len()
> s.min()
> s.max()
> etc.


I don't have a good answer for this. At least some of this is probably
pure history (len() worked on both strings and lists, and strings didn't
used to support methods, so I'm guessing it was a consistency issue back
then and it's a compatibility issue now, why it wasn't added as a method
is a good question). As far as min() and max() <shrug>. Perhaps to
avoid a plethora of methods on such commonly used constructs? At what
point do you stop adding new methods to classes? Perhaps the decision
was as simple as that.

> Thank you,
> bear hugs,
> Bearophile


That disturbs me every time I see it.


Regards,
Cliff

--
Cliff Wells <(E-Mail Removed)>

 
Reply With Quote
 
Jeff Shannon
Guest
Posts: n/a
 
      10-22-2004
bearophile wrote:

>I think some things are better in Delphi/Pascal
>


They may well be better _in_ Delphi/Pascal. That doesn't mean that
adding them into Python will make Python a better language. (I love
garlic. I love chocolate. I do not want to eat chocolate-covered
garlic cloves, nor garlic-flavored chocolate bars.)

>1) The "print" and "printf" pair without automatically added spaces
>between arguments, and with or without automatic newline, instead of
>the current "print" command. Because adding lots of "+str()+" isn't
>good for me (there's sys.stdout.write, but it's not built-in).
>
>


But Python *does* already have string interpolation: print "%s%s%s" %
('one', 'two', 'three')

This is more flexible than printf() would be, because it can be used to
generate strings even without printing. C had to resort to creating a
sprintf() function that did printf()-like formatting without actually
printing; Python made that a built-in operation on strings. I find that
I use this all the time, and never worry about print statements adding a
space after a comma because I don't need to use commas.

>2) Adding "case var of:" can be useful.
>
>


Not sure exactly what this is, but if you're referring to a case/switch
construct: using a dict of functions is (IMO) a better and cleaner way
of implementing the same idea.

>3) "do while" (or "repeat until") can also be added, it's useful.
>
>


Somewhat useful, sure, but it's not hard to achieve the same thing with
'while 1: if cond: break' . Python's designer made a deliberate
decision to minimize number of different types of loop structures to
use, since they tend to be very easy to convert between and fewer types
means less to learn. So we have two -- one that loops based on the
status of a condition, and one that iterates over each object in a
sequence. Minor variations on these themes are (according to Python
philosophy) better done by explicitly stating the rules, rather than by
creating new syntax for each variation.

>4) Maybe really raw strings RR"" can be added to avoid problems with
>file paths on Win :-]
>
>


Not really, because Python doesn't know what's supposed to be a file
path and what isn't. Unless, of course, you are explicit about it,
which means using os.path. In which case, you have already avoided
those problems using standard strings and don't need to worry about
whether a string is raw or not, let alone inventing a new "extra-raw"
string.

>5) Inside function definitions, assignments of mutable types like this
>can be forbidden and seen as errors by the interpreter:
>def func(a=[1,2]):
>
>


Except that having mutable types be shared this way can be a useful
feature. It's approximately the same thing as (in C/Java) declaring a
local variable to be static.

>6) Given:
>a = [1]
>a += [2]
>a = a + [3]
>The first assignment extends the list, and second creates a new list
>and rebinds it. Why such difference for operations that look the same?
>Isn't a kind of "error" to do different things with quite similar
>looking commands?
>
>


The idea of using += is that it modifies in-place. In-place
modification isn't meaningful for immutable types, but it can be very
useful for mutable types. Having a += x mean in-place modification
while a = a + x creates a new object allows both options to be easily
accessible without function-call syntax. Having both of them create a
new object means that one must call a.extend(x) in order to get in-place
modification. And I'd guess that the vast majority of cases where += is
used, in-place modification is the preferable behavior anyhow.

>7) There's something that I don't understand. I'm not a OOP purist,
>but finding functions like this beside normal methods seems odd to me:
>len(s) length of s
>min(s) smallest item of s
>max(s) largest item of s
>For uniformity they can be:
>s.len()
>s.min()
>s.max()
>etc.
>
>


You're apparently more of an OOP purist than Python is... Having these
as functions instead of methods is much simpler for Python's dynamic
type system. For example, new sequence types don't need to define min()
and max() methods -- the existing builtins just work. It also means
that implementation details of the function can be improved without
requiring a rewrite of every class that has ever defined a len() method,
and that Python can split the work of the function between the function
itself and one or more helper methods that might (or might not) be
implemented on any given class.

Remember, there's a lot more to good language design than just "Ooh,
this piece might be useful!" You also have to consider how all the
pieces fit together, and how certain constellations of pieces interact
with other constellations of pieces. Bulldozer blades, furrowers, and
manure-spreaders are all very useful devices when attached to the right
vehicle, but you wouldn't want them on your commuter car, right? Much
better to stick with a small subset of "useful devices" which fit
together in a consistent and (most importantly) practical way.

Jeff Shannon
Technician/Programmer
Credit International

 
Reply With Quote
 
David M. Cooke
Guest
Posts: n/a
 
      10-22-2004
http://www.velocityreviews.com/forums/(E-Mail Removed) (bearophile) writes:

> Ville Vainio:
>>It's highly typical for the newbies to suggest improvements to the
>>language. They will usually learn that they are wrong, but the
>>discussion that ensues can be fruitfull anyway .

>
> Few more notes on the language. I don't know if I can really suggest
> improvements to the language... but I hope to learn something
>
> I think some things are better in Delphi/Pascal (like the := for
> assignments instead of = and = for equality, that I suggested in the
> my precedent notes):
>
> 1) The "print" and "printf" pair without automatically added spaces
> between arguments, and with or without automatic newline, instead of
> the current "print" command. Because adding lots of "+str()+" isn't
> good for me (there's sys.stdout.write, but it's not built-in).


Use string formatting:
>>> a = "Hello"
>>> b = 5
>>> c = 4.52
>>> print "%s, %d is greater than %g" % (a, b, c)

Hello, 5 is greater than 4.52

Also, adding a , to the end of the print statement will suppress the
newline (although, not the space between the two calls).

> 2) Adding "case var of:" can be useful.


"can be" is the operative phrase here. It's not necessary. Chained
if/elif/elif works fine for small cases; for larger, you should
probably use a dict, or rewrite to use a class.

> 3) "do while" (or "repeat until") can also be added, it's useful.


Really, while loops and repeat until loops are special cases of the
much more useful loop-and-a-half:

while True:
... some stuff ...
if condition_true:
break
... more stuff ...

The above is a common enough Python idiom (also seen with while 1:,
which runs slightly faster due to absence of the lookup for True).

> 4) Maybe really raw strings RR"" can be added to avoid problems with
> file paths on Win :-]


I'm confused; how does r"..." not help? The only thing that gets
interpreted in a raw string is a backslash at the end of a string:
r"\" is not allowed. (I don't do Windows

> 5) Inside function definitions, assignments of mutable types like this
> can be forbidden and seen as errors by the interpreter:
> def func(a=[1,2]):
> ...


But then you have to determine what objects are mutable, and sometimes
this _is_ what you want (using the argument as a cache, or you're sure
that you don't mutate the argument).

> 6) Given:
> a = [1]
> a += [2]
> a = a + [3]
> The first assignment extends the list, and second creates a new list
> and rebinds it. Why such difference for operations that look the same?
> Isn't a kind of "error" to do different things with quite similar
> looking commands?


To me, a += [2] and a = a + [3] look different. You're applying idioms
you've learned in other languages (C?) to Python. += _can_ mutate the
argument, but it doesn't have to: it's very useful when used with
large mutable objects, such as Numeric arrays.

> 7) There's something that I don't understand. I'm not a OOP purist,
> but finding functions like this beside normal methods seems odd to me:
> len(s) length of s
> min(s) smallest item of s
> max(s) largest item of s
> For uniformity they can be:
> s.len()
> s.min()
> s.max()


Alex Martelli has answered this throughly in another thread, where the
context is why have __len__, etc. methods.

Another argument is that most objects, these methods would be useless:
what should s.min() be when s is, for instance, a database object?
Should numbers also have them? These methods only make sense when s is
some type of sequence (len() also works for a collection like a dict
or set, also).

Also, one Python tenet is "practicality beats purity". Making a new
sequence type is _easy_. Add __getitem__ and __len__ methods, and
*poof*. I don't have to inherit from a 'sequence' object, or implement
the methods above: the algorithms in min() and max() work right away.

--
|>|\/|<
/--------------------------------------------------------------------------\
|David M. Cooke
|cookedm(at)physics(dot)mcmaster(dot)ca
 
Reply With Quote
 
Cliff Wells
Guest
Posts: n/a
 
      10-22-2004
On Thu, 2004-10-21 at 18:07 -0700, Jeff Shannon wrote:
> bearophile wrote:
>
> >I think some things are better in Delphi/Pascal
> >

>
> They may well be better _in_ Delphi/Pascal. That doesn't mean that
> adding them into Python will make Python a better language. (I love
> garlic. I love chocolate. I do not want to eat chocolate-covered
> garlic cloves, nor garlic-flavored chocolate bars.)


Well, that's a matter of personal taste. Garlic is good on
*everything*.

> >2) Adding "case var of:" can be useful.


> Not sure exactly what this is, but if you're referring to a case/switch
> construct: using a dict of functions is (IMO) a better and cleaner way
> of implementing the same idea.


For many things this is true (and I use function lookup tables
frequently). However it doesn't as conveniently cover all use cases
that switch/case does (as it requires a function definition for each
item). While it's also true that if/elif/else can be used instead for
these other cases, I personally find switch/case far cleaner looking
(when there are more than five or six conditions to test).

Also, I'd be reluctant to claim that the dictionary lookup is cleaner
(it looks more cluttered to my eye), but rather, more flexible (items
can be dynamically added to the list).

Regards,
Cliff

--
Cliff Wells <(E-Mail Removed)>

 
Reply With Quote
 
Robby Russell
Guest
Posts: n/a
 
      10-22-2004
On Thu, 2004-10-21 at 18:43 -0700, Cliff Wells wrote:
> Well, that's a matter of personal taste. Garlic is good on
> *everything*.


Mmm... roasted garlic smoothies.



--
/***************************************
* Robby Russell | Owner.Developer.Geek
* PLANET ARGON | www.planetargon.com
* Portland, OR | (E-Mail Removed)
* 503.351.4730 | blog.planetargon.com
* PHP/PostgreSQL Hosting & Development
****************************************/


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)

iD8DBQBBeGiS0QaQZBaqXgwRAqTGAKCux0K7b/tkMuLXcfriT7vtFbAwQQCglRJi
Ni1b5lmCwGnQzhCwfZjuMkk=
=Gg43
-----END PGP SIGNATURE-----

 
Reply With Quote
 
Jeremy Bowers
Guest
Posts: n/a
 
      10-22-2004
On Thu, 21 Oct 2004 17:59:41 -0700, Cliff Wells wrote:
>> 7) There's something that I don't understand. I'm not a OOP purist
>> but finding functions like this beside normal methods seems odd to me:
>> len(s) length of s
>> min(s) smallest item of s
>> max(s) largest item of s
>> For uniformity they can be:
>> s.len()
>> s.min()
>> s.max()
>> etc.

>
> I don't have a good answer for this.


See the current thread "Python and generic programming". Those are
probably best though of as generic algorithms that can work even when
"max" isn't implemented.

Python 2.3.4 (#1, Sep 28 2004, 20:15:25)
[GCC 3.3.3 20040412 (Gentoo Linux 3.3.3-r6, ssp-3.3.2-2, pie-8.7.6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def somenumbers():

.... yield 1
.... yield 5
.... yield 2
....
>>> max(somenumbers())

5
>>>



"max" isn't a method in any sense of the term that I am aware of, so it
would be wrong to put it there. In some sense, then, this is *more* pure
OO than, say, Java's "Everything is a method of some object and to hell
with the consequences!" approach.

(It seems like the more mature I get as a programmer, the more Java
disgusts me. I'm beginning to have to stretch for reasons to like it at
all; one after another they keep falling down for me. But I digress...)
 
Reply With Quote
 
bearophile
Guest
Posts: n/a
 
      10-23-2004
Istvan Albert:

>No you can't. Your suggestions are driven by nothing else
>but your desire to make Python resemble Pascal since
>that is the language that you are accustomed to.


You are right, I'm just a newbie in Python, and there are other
languages than I know a bit better, like Delphi.
Like natural languages, computer languages have a personal "soul"
(grammar core, etc), but they also keep copying other languages, to
improve, etc.
-----------

Cliff Wells:

>Actually, since the assignment operator is used far more often than

the
>equality operator, making it require three keystroke rather than just
>one is a bad idea.


Right, still, from a mathematical/formal point of view, Pascal syntax
is better here :-]


>Use string interpolation.


Okay, I'll learn to use it more often.


>>2) Adding "case var of:" can be useful.

>Not familiar with this construct. If you mean "switch/case" as in C

(or
>some variation of same), then I absolutely agree.


Yes, it's the Delphi/Pascal version of it.


>Occasionally useful. Not enough to put it high on my list of things

I'd
>like to see in Python, but I can see its utility for making

*slightly*
>more logical code (versus the "while True: if x: break" idiom).


I agree, it's not essential, but it can be useful


>Why not just use "/"?


Okay, I'll use os.path.normcase to convert them.


>but there are plenty of things to confuse newbies,


Reducing non-obvious, magic or not-standard behaviours is quite
necessary inside a language, it helps non-newbies too, making the
language more conceptually transparent. Sometimes such non-standard
behaviours can be useful to improve language speed or other things,
but they have to reduced to the minimum possible. Python often prefers
transparency, even when there are many (worse and more opaque, but
maybe faster) ways to do things. This is positive for a hi-level
language. So making a hi-level language like Python more transparent
can be a way to improve it
Mathematica is more transparent than Python (its hashes can process
everything, it has just a mutable list type and not tuples, assignment
copies the object, and it's more functional so there are much less
problems with globals and side effects, etc. but it can still be used
with imperaive programming) and often it's also faster, but it's far
from free (and its can be worse to do "real" programming, etc) :-]
Note: Mathematica can be used with a quite powerful "pattern matching
programming", I don't know if such thing (or a subset of it) can be
useful to add to Python.


>there is a logical explanation that suffices in
>place of breaking tons of Python code.


There are logical explanations for everything (because everything must
be executed by the processor), but for humans some things are more
logical than others
Python 3.0 already breaks lots of things, even division operators, so
that's the best occasion to improve/change/fix things.
-----------

Jeff Shannon:

>using a dict of functions is (IMO) a better and cleaner
>way of implementing the same idea.


I don't know... The Case syntax can be something like:

Case <name>:
1: DoSomething1
range(2,23): DoSomething2
else: DoSomething3

(Etc. There are many other possibilities, like the Switch, etc).


>it's not hard to achieve the same thing with
>'while 1: if cond: break' . Python's designer made a deliberate
>decision to minimize number of different types of loop structures to
>use, since they tend to be very easy to convert between and fewer

types
>means less to learn. So we have two -- one that loops based on the
>status of a condition, and one that iterates over each object in a
>sequence. Minor variations on these themes are (according to Python
>philosophy) better done by explicitly stating the rules, rather than

by
>creating new syntax for each variation.


Okay... I'll use the 'while 1: if cond: break'


>Except that having mutable types be shared this way can be a useful

feature.<

It looks more dangerous than useful. And assignments of non-mutable
types can still be accepted.


>Having a += x mean in-place modification
>while a = a + x creates a new object allows both options to be
>easily accessible without function-call syntax.


Okay, the manual I've read wasn't clear enough about this


>Having these
>as functions instead of methods is much simpler for Python's dynamic
>type system. For example,
>new sequence types don't need to define min()
>and max() methods -- the existing builtins just work. It also means
>that implementation details of the function can be improved without
>requiring a rewrite of every class that has ever defined a len()

method,

Okay. Thank you for the info. I still prefer Python to Ruby (a more
pure OO language, I think).


>Remember, there's a lot more to good language design than just "Ooh,
>this piece might be useful!" You also have to consider how all the
>pieces fit together,


I agree, sometimes adding things is positive, and sometimes it's not
good.
Things have to be discussed by people expert on the language (and I'm
a newbie), but I am here to learn too
("pattern matching programming" can be one of such things.)
-----------

Cliff Wells:

>While it's also true that if/elif/else can be used instead for
>these other cases, I personally find switch/case far cleaner looking
>(when there are more than five or six conditions to test).
>[...]
>Also, I'd be reluctant to claim that the dictionary lookup is cleaner
>(it looks more cluttered to my eye), but rather, more flexible (items
>can be dynamically added to the list).


I agree.
-----------

David M. Cooke:

>Also, adding a , to the end of the print statement will suppress the
>newline (although, not the space between the two calls).


Right, I've forgot it


>"can be" is the operative phrase here. It's not necessary.<


Well, OOP and lots of other things (inside Python too) aren't
necessary. I was discussing mostly about things that can be useful.


>Chained if/elif/elif works fine for small cases; for larger,
>you should probably use a dict, or rewrite to use a class.


Uhm... I'll try with the dictionary.


>Really, while loops and repeat until loops are special cases of the
>much more useful loop-and-a-half:
>while True:
> ... some stuff ...
> if condition_true:
> break
> ... more stuff ...


I'll use it, but I think it's really ugly. It looks like the old
spaghetti code with GOTOs :-]

Thank you for the answers and explanations,
a handshake to Cliff and bear hugs to everybody else,
bearophile
(remove HUGS if you want to mail me directly)
 
Reply With Quote
 
Peter Hansen
Guest
Posts: n/a
 
      10-23-2004
bearophile wrote:
> Cliff Wells:
>>Why not just use "/"?

>
> Okay, I'll use os.path.normcase to convert them.


That's not necessary in almost all cases. Windows happily(*)
accepts forward slashes in all system calls. The only place
it does not is in the *shell* (aka command.com and cmd.exe).
That means paths passed as arguments to os.system or the
Popen gang need to be normcased, but for things like open()
you don't need to bother.

-Peter

(*) There are theories that although Windows does accept
forward slashes, it does so only grudgingly.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
dos bootable usb bootdisk.com HP tools - some notes jameshanley39@yahoo.co.uk Computer Information 0 12-11-2007 07:09 PM
C# 2.0 (Lotus Notes 6 & 7) Create mail document in draft folder for Lotus Notes SteveM ASP .Net 5 08-28-2007 04:16 PM
Need some notes allenfox MCSD 3 07-21-2006 03:45 AM
Accessing email from Notes-mail-server without Lotus Notes installed Bjorn Jensen Perl 0 03-22-2005 01:44 PM
Some notes bearophile Python 19 10-17-2004 08:34 PM



Advertisments