Re: Confessions of a Python fanboy

2015-05-11 Thread Steven D'Aprano
On Monday 11 May 2015 11:46, zipher wrote:

 By having methods like len() in your built-in namespace when it's really
 only relevant to objects that are types of containers, you blur one
 primary component of OOP:  encapsulation.


Gosh, one would almost think that Python's concept of OOP wasn't pure enough 
for you.

You should talk to that other guy who says that Python is too pure, his name 
is Mark Rosenblitt-Janssen. I'm sure you two would have a lot to talk about.



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2015-05-11 Thread Mark Lawrence

On 11/05/2015 07:15, Steven D'Aprano wrote:

On Monday 11 May 2015 11:46, zipher wrote:


By having methods like len() in your built-in namespace when it's really
only relevant to objects that are types of containers, you blur one
primary component of OOP:  encapsulation.


Gosh, one would almost think that Python's concept of OOP wasn't pure enough
for you.

You should talk to that other guy who says that Python is too pure, his name
is Mark Rosenblitt-Janssen. I'm sure you two would have a lot to talk about.



Ah, the penny has finally dropped.  I recall years ago somebody pointing 
out his website.  It had clearly been put together after the narcotics 
from several bulk carriers had been consumed.


--
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence

--
https://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2015-05-10 Thread zipher
  3.) true OOP
  Now before you go and get all huffy over this statement, hear me
  out. Python is the best language in the world. But it damn sure has
  some warts! len(this) instead of obj.length max(that) instead of
  [1,2,3,4,5].max().
 
 As the Zen says: '[P]racticality beats purity'. Personally, I'm not
 sure how a handful of convenient built-in functions make a language in
 which _everything is an object_ somehow false OO.
 
 If you're really that concerned with writing true OO (for some
 wildly variable value of true), there's nothing stopping you from
 doing so now:
 
 obj.__len__()

The issue is that Python currently blurs a very powerful conceptual boundary in 
CS -- between the abstract space where objects and variables are held and the 
concrete underlying machine. 

By having methods like len() in your built-in namespace when it's really only 
relevant to objects that are types of containers, you blur one primary 
component of OOP:  encapsulation.

Mark
-- 
https://mail.python.org/mailman/listinfo/python-list


OFFTOPIC, WAS Re: Confessions of a Python fanboy

2015-05-10 Thread zipher
On Sunday, May 10, 2015 at 9:18:55 PM UTC-5, Chris Angelico wrote:
 On Mon, May 11, 2015 at 12:11 PM, zipher dreamingforw...@gmail.com wrote:
  Please take care of your quoting. You just quoted two other posts, and
  I have no idea who said things without going and digging in the
  archive.
 
  I'm sorry.  I've been sleeping on the beach, away from civilization, a 
  little too long, and didn't see that this was a post from 6 years ago.
 
  Feel free to disregard.
 
 That actually has nothing to do with it. You're still quoting without 
 citation.

Well, I replied right at the point of my correspondent (Alex23).  If 
googlegroups isn't tracking that fact, it shouldn't put a reply button at every 
single message, but only at the end of the thread.

 This is why Google Groups has such a bad reputation. I think it's time
 for me to *plonk* you.

I see.  Someone should inform google not to put a reply after every post, but 
only at the end of a thread so users don't assume that it's tracking thread 
hierarchies.  So you're point is apropos, if that's the case.

In which case, my reply was to Alex23 who was replying to the OP's first post 
who goes by the name r.

Mark
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: OFFTOPIC, WAS Re: Confessions of a Python fanboy

2015-05-10 Thread Ben Finney
zipher dreamingforw...@gmail.com writes:

 On Sunday, May 10, 2015 at 9:18:55 PM UTC-5, Chris Angelico wrote:
  That actually has nothing to do with it. You're still quoting
  without citation.

 Well, I replied right at the point of my correspondent (Alex23).

That's not the issue :-)

The omission Chris is referring to is: in earlier messages, you were
stripping the “attribution line” from directly above the quoted
material. That makes it anonymous, and it becomes difficult to track who
said what.

The attribution line looks like:

“On Sunday, May 10, 2015 at 9:18:55 PM UTC-5, Chris Angelico wrote:”

without the quote marks.

You need to preserve the attribution lines – as you did on the message
just now, that I'm replying to – in order to show who wrote what quoted
material.

Only remove attribution lines if you're *also* removing all of the
attributed material. Keep attribution lines for the material you're
quoting.

-- 
 \“We have to go forth and crush every world view that doesn't |
  `\believe in tolerance and free speech.” —David Brin |
_o__)  |
Ben Finney

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2015-05-10 Thread zipher
 Please take care of your quoting. You just quoted two other posts, and
 I have no idea who said things without going and digging in the
 archive.

I'm sorry.  I've been sleeping on the beach, away from civilization, a little 
too long, and didn't see that this was a post from 6 years ago.

Feel free to disregard.

Mark
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2015-05-10 Thread Chris Angelico
On Mon, May 11, 2015 at 11:46 AM, zipher dreamingforw...@gmail.com wrote:
  3.) true OOP
  Now before you go and get all huffy over this statement, hear me
  out. Python is the best language in the world. But it damn sure has
  some warts! len(this) instead of obj.length max(that) instead of
  [1,2,3,4,5].max().

 As the Zen says: '[P]racticality beats purity'. Personally, I'm not
 sure how a handful of convenient built-in functions make a language in
 which _everything is an object_ somehow false OO.

 If you're really that concerned with writing true OO (for some
 wildly variable value of true), there's nothing stopping you from
 doing so now:

 obj.__len__()

 The issue is that Python currently blurs a very powerful conceptual boundary 
 in CS -- between the abstract space where objects and variables are held and 
 the concrete underlying machine.

 By having methods like len() in your built-in namespace when it's really only 
 relevant to objects that are types of containers, you blur one primary 
 component of OOP:  encapsulation.


Please take care of your quoting. You just quoted two other posts, and
I have no idea who said things without going and digging in the
archive.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2015-05-10 Thread Chris Angelico
On Mon, May 11, 2015 at 12:11 PM, zipher dreamingforw...@gmail.com wrote:
 Please take care of your quoting. You just quoted two other posts, and
 I have no idea who said things without going and digging in the
 archive.

 I'm sorry.  I've been sleeping on the beach, away from civilization, a little 
 too long, and didn't see that this was a post from 6 years ago.

 Feel free to disregard.


That actually has nothing to do with it. You're still quoting without citation.

This is why Google Groups has such a bad reputation. I think it's time
for me to *plonk* you.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-08-26 Thread Luis Zarrabeitia
On Friday 31 July 2009 04:08:33 am Masklinn wrote:
 On 30 Jul 2009, at 23:57 , Luis Zarrabeitia wrote:
  I'd like to ask, what container.each is, exactly? It looks like a
  function
  call (as I've learned a few posts ago), but, what are its arguments?
  How the
  looping works? Does it receive a code object that it has to
  execute?
  Is .each some kind of magic keyword? (This has little to do with
  python or
  the current thread, so feel free to reply off-list if you want to...)

 #each is simply a method that takes a function (called blocks in
 ruby). One could call it a higher-order method I guess.

 It's an implementation of the concept of internal iteration: instead
 of collections yielding iterator objects, and programmers using those
 through specially-built iteration constructs (e.g. `for…in`),
 collections control iteration over themselves (the iteration is
 performed inside the collection, thus the internal part) and the
 programmer provides the operations to perform at each iterative step
 through (usually) a function.

Interesting. I know what internal iteration is, and I suspected it was along 
these lines when I saw the syntax and that .each was a function and not a 
keyword. But if it is internal iteration and the .each method is receiving an 
anonymous function, I wonder what is the scope of the variables in that 
function. In pseudo-python terms (using your example),

 x = 5
 some_list.each((def (item):
 do_something(item, x)
 x = do_something_else(item)
 ))

(or something like that). In python, the inner function would be invalid 
(the 'x' is local). For that construct to be equivalent to a for loop, the 
anonymous function shouldn't create a new scope. Is that what is happening? 
(If it is, this would be a big difference between anonymous and non-anonymous 
functions). 

Anyway, this is OT. Thank you for your reply.
(ah, sorry for taking so long... I was out of town)

-- 
Luis Zarrabeitia (aka Kyrie)
Fac. de Matemática y Computación, UH.
http://profesores.matcom.uh.cu/~kyrie
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-08-05 Thread Just Another Victim of the Ambient Morality

Steven D'Aprano ste...@remove.this.cybersource.com.au wrote in message 
news:pan.2009.08.04.09.28...@remove.this.cybersource.com.au...
 On Tue, 04 Aug 2009 10:03:53 +0200, Bruno Desthuilliers wrote:

 Disadvantages: your code is filled with line noise. It's an arbitrary
 choice between @@ meaning instance attribute and @@ meaning class
 attribute -- there's no logical reason for choosing one over the other,
 so you have to memorise which is which. It's easy to get it wrong.

 So far that's something I have no difficulty living with.

 I don't like arbitrary symbols. Most people don't -- that's why line
 noise is unpopular. It's hard to read, hard to write, hard to maintain,
 and hard to talk about. The more line-noise, the worse the language.

It's not line noise if it conveys information...


 Of course, *ultimately* every symbol is arbitrary. There's no reason why
 2 should mean the integer two, or list should mean a sequence type,
 but some symbols have such a long history, or have some other connection
 (say, with human languages), that the arbitrariness is lost. For
 instance, + is the obvious, non-arbitrary choice for the addition
 operator in any programming language using Latin symbols, and probably
 any programming language on Earth. (Not the *only* choice, but the
 obvious one.)

 I have a similar dislike for decorator syntax, because @ (at in
 English) has nothing to do with decorations. It's an arbitrary symbol.
 One might argue that $ would have been a more logical choice, because
 we turn numerals into currency by decorating it with a $ sign. (At least
 in the US, Canada, Australia, and a few other countries.) I use
 decorators all the time, and they are a fantastic invention, but the
 arbitrariness of the @ syntax is a negative. Oh well, one negative out of
 a whole lot of positives isn't too bad.

You can think of @ as describing something being at the instance or 
the class.  $ is totally arbitrary to me 'cause I don't thnk of my code as 
currency...


 At least I only have to deal with *one* such arbitrary symbol that needs
 memorizing. There's no need to distinguish between @@function_decorator
 and @class_decorator (or should it be the other way around?). Similarly,
 Python's choice of syntax for attributes is consistent: object.attribute
 works for everything, whether object is a class, an instance, a module,
 and whether attribute is callable or not. You can even use it on ints,
 provided you are clever about it:

You can think of @ as being at an instance or @@ to be more 
emphatically (as the Japanese do in their language) integrated with a class, 
being available to all instances... or you can simply understand that 
instance vairables are more common than class variables so the shorter 
notation is used for the more common case...
You want to talk about arbitrariness?  Why is len() a function you pass 
objects into while objects can have methods that describe themselves to you? 
At least Ruby defines operators using the actual name of the operator 
instead of you having to remember an arbitrary magic incantation that 
corresponds to the operator...

class Test
attr_reader :data

def initialize(data)
@data = data
end

# This is the operator part...
def + right
Test.new @data + right.data
end
end


 Somebody who knows more Ruby than me should try writing the Zen of
 Ruby. Something like:
 (snip childish parody of Python Zen)

 Steven, is that any useful ?

 It made me feel good.

 Why ???

 You don't like Ruby ? Fine, don't use it. Period. I can't see the point
 of all these pissing contests.

 Criticism of a language is a pissing contest?

 Yeah, okay, I was a tad dismissive. I un-apologetically jump to strong
 impressions about languages based on minimal use -- but I'm also willing
 to change my mind. Ruby certainly looks to me like it has some nice
 features. Syntax that looks like Perl isn't one of them though.

Yeah, that would be the pissing contest part.
You could simply have gone to the Ruby newsgroup and posted some 
criticisms to see what was behind those decisions.  However, that would have 
avoided the pissing contest and perhaps you wanted one...


 Just because Smalltalk had a particular (mis?)feature

 You can drop the 'mis' part IMHO. The point of code blocks in Smalltalk
 is that once you have something as powerful as the message+code blocks
 combo, you just don't need any other 'special form' for control flow.

 Well, maybe, but remember, programming languages are only partly for
 communication to the compiler. They also have the requirement to
 communicate with human programmers as well, and that's even more
 important, because

 (1) humans spent a lot more time working with code than compilers do;

 (2) human programmers charge much more money than compilers do;

 (3) and you can modify the compiler to suit human needs much more easily
 than you can modify programmers to suit the compiler's needs.


Re: Confessions of a Python fanboy

2009-08-04 Thread Bruno Desthuilliers

Steven D'Aprano a écrit :

On Fri, 31 Jul 2009 13:38:56 +0200, Bruno Desthuilliers wrote:


On the other hand, we don't have to prefix names with @ and @@,

Nope, we have to prefix them with 'self' or 'cls' (or even
'self.__class__').


Incorrect.


Correct for all relevant cases, except this one:


class K:

... class_attribute = 'No @@ required.'
...



K().class_attribute

'No @@ required.'


Once again: Ruby's attributes are *private*, so you can't access an 
attribute (class or instance) from outside a method. IOW, the above 
example is irrelevant.


(snip)

Disadvantages: your code is filled with line noise. It's an arbitrary 
choice between @@ meaning instance attribute and @@ meaning class 
attribute -- there's no logical reason for choosing one over the other, 
so you have to memorise which is which. It's easy to get it wrong.


So far that's something I have no difficulty living with.


and we
don't have the compiler trying to *guess* whether we're calling a
function or referring to a variable.
Please re-read a bit more carefully - it's *all* method call. 


What did I misread from here?


Nowhere - it's me that got it wrong here, sorry.

(snip)



Somebody who knows more Ruby than me should try writing the Zen of
Ruby. Something like:

(snip childish parody of Python Zen)

Steven, is that any useful ?


It made me feel good.


Why ???

You don't like Ruby ? Fine, don't use it. Period. I can't see the point 
of all these pissing contests.


But seriously, while I admit that I have very little Ruby experience, and 
so aren't in a great position to judge, it seems to me that Ruby doesn't 
have anything like Python's over-riding design principles (the Zen). If 
there is a design principle to Ruby, I can't see what it is.


Fullfill the tastes of Matz ?-)

(snip)


Although I'm sure Ruby has its good points. I'm not convinced anonymous
code blocks are one of them though.

Ruby's code blocks come from Smalltalk, where they are an absolute
necessity since message passing (which code blocks are part of) is the
*only* builtin control flow in Smalltalk - so you just *need* this
construction to provide branching and iterations.


Just because Smalltalk had a particular (mis?)feature


You can drop the 'mis' part IMHO. The point of code blocks in Smalltalk 
is that once you have something as powerful as the message+code blocks 
combo, you just don't need any other 'special form' for control flow.


doesn't mean that 
other languages should copy it.


Nope. But OTHO, Python is famous for all the features it copied from 
other languages !-)

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-08-04 Thread Steven D'Aprano
On Tue, 04 Aug 2009 10:03:53 +0200, Bruno Desthuilliers wrote:

 Disadvantages: your code is filled with line noise. It's an arbitrary
 choice between @@ meaning instance attribute and @@ meaning class
 attribute -- there's no logical reason for choosing one over the other,
 so you have to memorise which is which. It's easy to get it wrong.
 
 So far that's something I have no difficulty living with.

I don't like arbitrary symbols. Most people don't -- that's why line 
noise is unpopular. It's hard to read, hard to write, hard to maintain, 
and hard to talk about. The more line-noise, the worse the language.

Of course, *ultimately* every symbol is arbitrary. There's no reason why 
2 should mean the integer two, or list should mean a sequence type, 
but some symbols have such a long history, or have some other connection 
(say, with human languages), that the arbitrariness is lost. For 
instance, + is the obvious, non-arbitrary choice for the addition 
operator in any programming language using Latin symbols, and probably 
any programming language on Earth. (Not the *only* choice, but the 
obvious one.)

I have a similar dislike for decorator syntax, because @ (at in 
English) has nothing to do with decorations. It's an arbitrary symbol. 
One might argue that $ would have been a more logical choice, because 
we turn numerals into currency by decorating it with a $ sign. (At least 
in the US, Canada, Australia, and a few other countries.) I use 
decorators all the time, and they are a fantastic invention, but the 
arbitrariness of the @ syntax is a negative. Oh well, one negative out of 
a whole lot of positives isn't too bad.

At least I only have to deal with *one* such arbitrary symbol that needs 
memorizing. There's no need to distinguish between @@function_decorator 
and @class_decorator (or should it be the other way around?). Similarly, 
Python's choice of syntax for attributes is consistent: object.attribute 
works for everything, whether object is a class, an instance, a module, 
and whether attribute is callable or not. You can even use it on ints, 
provided you are clever about it:

 42 .__class__
type 'int'



 Somebody who knows more Ruby than me should try writing the Zen of
 Ruby. Something like:
 (snip childish parody of Python Zen)

 Steven, is that any useful ?
 
 It made me feel good.
 
 Why ???
 
 You don't like Ruby ? Fine, don't use it. Period. I can't see the point
 of all these pissing contests.

Criticism of a language is a pissing contest?

Yeah, okay, I was a tad dismissive. I un-apologetically jump to strong 
impressions about languages based on minimal use -- but I'm also willing 
to change my mind. Ruby certainly looks to me like it has some nice 
features. Syntax that looks like Perl isn't one of them though.


 Just because Smalltalk had a particular (mis?)feature
 
 You can drop the 'mis' part IMHO. The point of code blocks in Smalltalk
 is that once you have something as powerful as the message+code blocks
 combo, you just don't need any other 'special form' for control flow.

Well, maybe, but remember, programming languages are only partly for 
communication to the compiler. They also have the requirement to 
communicate with human programmers as well, and that's even more 
important, because 

(1) humans spent a lot more time working with code than compilers do;

(2) human programmers charge much more money than compilers do;

(3) and you can modify the compiler to suit human needs much more easily 
than you can modify programmers to suit the compiler's needs.

So I'd ask, does Smalltalk's message passing model match the way human 
beings think? If not, then that's a good sign it might be a misfeature.


 doesn't mean that
 other languages should copy it.
 
 Nope. But OTHO, Python is famous for all the features it copied from
 other languages !-)

Absolutely! There's nothing wrong with copying *good* features :)




-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-08-04 Thread Bruno Desthuilliers

Steven D'Aprano a écrit :
 On Tue, 04 Aug 2009 10:03:53 +0200, Bruno Desthuilliers wrote:

 Disadvantages: your code is filled with line noise. It's an arbitrary
 choice between @@ meaning instance attribute and @@ meaning class
 attribute -- there's no logical reason for choosing one over the other,
 so you have to memorise which is which. It's easy to get it wrong.
 So far that's something I have no difficulty living with.

 I don't like arbitrary symbols.

Neither do I - when there are too many at least. But I can certainly 
live with a couple ones. Now the point wasn't about my personal tastes, 
but about the fact that this particular pair of arbitrary symbols was 
 IMHO still usable - IOW, I wouldn't dismiss Ruby on this sole point.


 Most people don't -- that's why line
 noise is unpopular. It's hard to read, hard to write, hard to maintain,
 and hard to talk about. The more line-noise, the worse the language.

OTHO, too much verbosity is a pain too. Ever programmed in AppleScript ? 
set the attribute XXX of object YYY of collection ZZZ to SomeValue... 
Yuck. I bet you prefer zzz[yyy].xxx = SomeValue - which uses three 
arbitrary symbols.


(snip)

 Oh well, one negative out of
 a whole lot of positives isn't too bad.

Indeed. You could perhaps learn a bit more about Ruby's positives if you 
don't block on what you perceive (rightfully or not) as negative points ?-)


(snip)

 Somebody who knows more Ruby than me should try writing the Zen of
 Ruby. Something like:
 (snip childish parody of Python Zen)

 Steven, is that any useful ?
 It made me feel good.
 Why ???

 You don't like Ruby ? Fine, don't use it. Period. I can't see the point
 of all these pissing contests.

 Criticism of a language is a pissing contest?

Not necessarily. But:

 Yeah, okay, I was a tad dismissive. I un-apologetically jump to strong
 impressions about languages based on minimal use

Possibly, yes.

 -- but I'm also willing
 to change my mind. Ruby certainly looks to me like it has some nice
 features. Syntax that looks like Perl isn't one of them though.

Not my cup of tea neither FWIW. But Ruby is nowhere near Perl in terms 
of line noise.



 Just because Smalltalk had a particular (mis?)feature
 You can drop the 'mis' part IMHO. The point of code blocks in Smalltalk
 is that once you have something as powerful as the message+code blocks
 combo, you just don't need any other 'special form' for control flow.

 Well, maybe, but remember, programming languages are only partly for
 communication to the compiler. They also have the requirement to
 communicate with human programmers as well, and that's even more
 important, because

 (1) humans spent a lot more time working with code than compilers do;

 (2) human programmers charge much more money than compilers do;

 (3) and you can modify the compiler to suit human needs much more easily
 than you can modify programmers to suit the compiler's needs.

 So I'd ask, does Smalltalk's message passing model match the way human
 beings think?

Does all human beings think the same way ? And aren't human beings able 
to learn new ways ?


Smalltalk's only control flow construct might seem a bit weird at first 
when all you've been exposed to so far are more traditional special 
constructs, but it's not hard to learn and is way more uniform and 
flexible than having special constructs for each and any possible 
situation.


One could ask if functional programming or OO matches the way human 
beings think. From experience, some of us just find FP and / or OO just 
obvious, and some won't never get it.


FWIW, there are quite a few features and idioms in Python that I _now_ 
find readable and obvious, but that would have puzzled me ten years ago. 
This reminds me of a shop where the CTO had forbidden using any OO 
feature of the main language used there because nobody would understand 
it (needless to say, I only stayed there a couple weeks...).



 doesn't mean that
 other languages should copy it.
 Nope. But OTHO, Python is famous for all the features it copied from
 other languages !-)

 Absolutely! There's nothing wrong with copying *good* features :)

Well... at least when they make sense and integrate smoothly into the 
target language.



--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-08-04 Thread Masklinn

On 4 Aug 2009, at 11:28 , Steven D'Aprano wrote:

So I'd ask, does Smalltalk's message passing model match the way human
beings think?

Yes.

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Steven D'Aprano
On Thu, 30 Jul 2009 18:06:31 -0500, Robert Kern wrote:

 On 2009-07-30 16:44, r wrote:
 On Jul 30, 4:29 pm, Emmanuel Surleauemmanuel.surl...@gmail.com wrote:
 1.) No need to use () to call a function with no arguments. Python
 --  obj.m2().m3() --ugly
Ruby --  obj.m1.m2.m3  -- sweeet!
 Man, i must admit i really like this, and your code will look so much
 cleaner.
 It has benefits - code does look better. It has also significant cons
 - it is ambiguous.
 For instance:

 a = b

 Is b a variable or a method called without parameter?

 Hello Emanuel,
 Again, who so ever names a method with such a non-descriptive name will
 get whats coming to him. And if you did for some reason use such a
 cryptic name as b, do yourself (and everyone else) a favor and follow
 it with () to denote the method call. Remember when something is
 optional that means you have an option to use it OR not use it.
 
 I believe his point is that it is ambiguous to the compiler, not humans
 reading the code. Python functions and methods are first class objects.
 They can be passed around. If they were auto-called, then you could not
 do this.

Oh my, r is still around is he??? And now he's singing the praises of 
Ruby, the language which he treated as the Devil's Spawn when he first 
arrived. That's hilarious.

But back on topic... r has missed the point. It's not that a=b is hard 
to understand because b is a poor name. The example could have been:

def factory_function():
magic = time.time()  # or whatever
def inner():
return magic
return inner

my_function = factory_function

It's still ambiguous. Does the programmer intend my_function to become 
factory_function itself, or the output of factory_function?

In Python, it's not ambiguous at all -- my_function is set to 
factory_function, and *not* the output of factory_function, because you 
haven't called the function.

Python's model is consistent and simple: given a function func, you 
*always* refer to the function object itself as func and you *always* 
call it with func(). This applies no matter how many arguments the 
function takes, or what it returns, or where it is defined.

I think it's telling that r the fanboy has rejected Python's advantages 
(simplicity, consistency, unambiguity) in favour of lazily saving two 
keystrokes.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Masklinn

On 30 Jul 2009, at 23:52 , Jan Kaliszewski wrote:
Dnia 30-07-2009 o 22:41:57 Masklinn maskl...@masklinn.net  
napisał(a):

On 30 Jul 2009, at 22:23 , Jan Kaliszewski wrote:

30-07-2009 o 13:36:49 Masklinn maskl...@masklinn.net wrote:

On 30 Jul 2009, at 06:04 , alex23 wrote:

On Jul 30, 1:06 pm, r rt8...@gmail.com wrote:

2.) the .each method
container.each{|localVar| block}
This method can really cleanup some ugly for loops, although i  
really

like the readability of for loops.


map(lambda localVar: block, sequence)

or:

def usefully_named_func(var):
 block
 return var

transformed = [usefully_named_func(v) for v in sequence]

The issue here is of course that `map` and comprehensions are  
transformations. `#each` exists for effectful iterations (Ruby  
has `#map` for the map operation). So the intent expressed by  
`#each` and `map` isn't the same. Furthermore and this is the  
most problematic limitation of Python here, `lambda` doesn't  
allow complex transformations due to its restrictions, so one has  
to switch to named functions which works but isn't sexy (and  
tends to lower readability imo).


I don't see any real limitation. What's wrong in:

for localVar in container:
  block

Well what's wrong with using that rather than `map`, `filter` or a  
list comprehension? (and if you don't see what the limitations of  
`lambda` are, you probably very rarely use it)


I know well about the expression-only-limitation of lambda, fortnately
there is the 'for' loop construct (or, alternatively, you can define
a named function).

And then, what's wrong with using 'for' rather than 'map', 'filter'  
etc.?

Nothing, but then again nothing's wrong using C's for either.

But I do think that using higher-order functions:
* tends to be terser while not going overly terse, it only removes  
boilerplate
* is more composable (it's pretty easy to tack another transformer in  
your chain, the same way defining iterator/generator transformers and  
chaining them is simpler than doing the same thing using explicit  
`for…in`)
* it clearly spells the intent of the programmer, while `for` can be  
anything and everything, and one has to dive into the code to know  
even the high-level operations performed (is it a basic  
transformation? A filtering or partitioning? A reduction? An  
application of side effects?)

Agree, that 'anonymous block syntax' would be nice in some cases, but
I don't see any real limitation caused by lack of it i.e. something  
you

can't (all you can only with unreasonable effort).

There are no limitations, but once again there never are. There are no  
actual limitations to using conditional jumps over iterators either.



And ruby's container.each is very similar to Python's iter()



Uh… not at all…


OK, .each is like Python's iter() + some form of iterating over it
('for' loop or '[i]map'...).
Well of course Enumerable#each is similar to map/imap, it's the same  
core principle.

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Masklinn

On 30 Jul 2009, at 23:57 , Luis Zarrabeitia wrote:
I'd like to ask, what container.each is, exactly? It looks like a  
function
call (as I've learned a few posts ago), but, what are its arguments?  
How the
looping works? Does it receive a code object that it has to  
execute?
Is .each some kind of magic keyword? (This has little to do with  
python or

the current thread, so feel free to reply off-list if you want to...)


#each is simply a method that takes a function (called blocks in  
ruby). One could call it a higher-order method I guess.


It's an implementation of the concept of internal iteration: instead  
of collections yielding iterator objects, and programmers using those  
through specially-built iteration constructs (e.g. `for…in`),  
collections control iteration over themselves (the iteration is  
performed inside the collection, thus the internal part) and the  
programmer provides the operations to perform at each iterative step  
through (usually) a function.


In Python (assuming we had anonymous defs and an each method on  
lists), the following loop:


for item in some_list:
do_something(item)
do_something_else(item)

some_list.each((def (item):
do_something(item)
do_something_else(item)
))

There's absolutely nothing magic there, it's simply using anonymous  
functions and method calls (SmallTalk initiated this approach in the  
70s, and actually went much, much further than Ruby as it did away not  
only with `for…in` but also with `if…else` and `while` and a bunch of  
other stuff).


Now as IV pointed out, #each isn't the most interesting usage of  
blocks/anonymous functions (though I do like it, because it gets rid  
of no less than two keywords… even if Ruby reintroduced them as  
syntactic sugar), higher-order functions (functions which act on other  
functions) are (among other things) ways to create new control  
structures without having to extend the core language (so are lisp- 
style macros, by the way).


Of course Python does have higher-order functions (functions are first- 
class objects, so it's possible and frequent to have functions act on  
other functions), but since Python doesn't have anonymous functions  
that usage tends to be a bit too verbose beyond simple cases (also, of  
course, this kind of usages is neither in the genes nor in the  
stdlib).


In closing, IV has an example of how blocks make `with` unnecessary in  
Ruby (the functionality can be implemented at the library level rather  
than the language one). Generally, anonymous functions in OO languages  
are a way to inject behavior into third-party methods/objects. Kind-of  
a first-class Visitor support.


-m

PS: there's actually a bit of syntactic magic in Ruby's blocks, and  
it's one of the things I hate in the language, but it's not relevant  
to the role of blocks, and unnecessary to it: SmallTalk has no magical  
syntax).

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Steven D'Aprano
On Thu, 30 Jul 2009 18:47:04 +0100, Tim Rowe wrote:

 That and the fact that I couldn't stop laughing for long enough to learn
 any more when I read in the Pragmatic Programmer's Guide that Ruby,
 unlike less flexible languages, lets you alter the value of a constant.
 Yep, as they say Bug = Undocumented feature!

That's no different from Python's constant by convention. We don't even 
get a compiler warning!

On the other hand, we don't have to prefix names with @ and @@, and we 
don't have the compiler trying to *guess* whether we're calling a 
function or referring to a variable.

Somebody who knows more Ruby than me should try writing the Zen of Ruby. 
Something like:

Line noise is beautiful.
Simplicity is for the simple.
Complicated just proves we're smart.
Readability only matters to the schmuck who has to maintain our code.
Special cases require breaking the rules.
In the face of ambiguity, try to guess. Go on, what could go wrong?
The more ways to do it, the better.

Although I'm sure Ruby has its good points. I'm not convinced anonymous 
code blocks are one of them though.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Xavier Ho
On Fri, Jul 31, 2009 at 6:08 PM, Masklinn maskl...@masklinn.net wrote:

 snip... but since Python doesn't have anonymous functions that usage
 tends to be a bit too verbose ... snip


Sorry to interrupt, but wouldn't lambda in Python be considered as
'anonymous functions'?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Chris Rebert
On Fri, Jul 31, 2009 at 1:21 AM, Xavier Hocont...@xavierho.com wrote:
 On Fri, Jul 31, 2009 at 6:08 PM, Masklinn maskl...@masklinn.net wrote:

 snip... but since Python doesn't have anonymous functions that usage
 tends to be a bit too verbose ... snip

 Sorry to interrupt, but wouldn't lambda in Python be considered as
 'anonymous functions'?

I believe full anonymous functions was intended by the author.
lambdas are limited to a single expression. Full anonymous functions
would be allowed to contain multiple statements.

Cheers,
Chris
-- 
http://blog.rebertia.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Xavier Ho
On Fri, Jul 31, 2009 at 6:25 PM, Chris Rebert c...@rebertia.com wrote:

 I believe full anonymous functions was intended by the author.
 lambdas are limited to a single expression. Full anonymous functions
 would be allowed to contain multiple statements.

 Cheers, but what about this:

 def goBig(x):
while True:
x = x ** 2
yield x

for result in goBig(10):
if result  10 ** 100:
break
print result

It's a silly example, but wouldn't goBig(10) in this example be a full
anonymous function?

Just being curious.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Chris Rebert
On Fri, Jul 31, 2009 at 1:31 AM, Xavier Hocont...@xavierho.com wrote:
 On Fri, Jul 31, 2009 at 6:25 PM, Chris Rebert c...@rebertia.com wrote:

 I believe full anonymous functions was intended by the author.
 lambdas are limited to a single expression. Full anonymous functions
 would be allowed to contain multiple statements.

 Cheers, but what about this:

  def goBig(x):
     while True:
     x = x ** 2
     yield x

 for result in goBig(10):
     if result  10 ** 100:
     break
     print result

 It's a silly example, but wouldn't goBig(10) in this example be a full
 anonymous function?

No, because it has a name, namely goBig; this obviously prevents it
from being anonymous.

For comparison, note how the function in the following example is
never given a name, and is thus anonymous:
 (lambda x: x+5)(6)
11

Cheers,
Chris
-- 
http://blog.rebertia.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Xavier Ho
On Fri, Jul 31, 2009 at 6:38 PM, Chris Rebert c...@rebertia.com wrote:

 No, because it has a name, namely goBig; this obviously prevents it
 from being anonymous.

 For comparison, note how the function in the following example is
 never given a name, and is thus anonymous:
  (lambda x: x+5)(6)
 11


Oh, I see. I was thinking in terms of using a variable to give the function
a name. In that case, I understand. Thanks again for bearing me with my
random thoughts.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Jean-Michel Pichavant

r wrote:

The purpose of his thread was to get feedback on how Python
and Ruby ideas could be cumulated into the best high level language.
And being that i am the BDFL of the Confessions of a Python Fanboy
thread, you have my personal permission to continue on with this
subject matter...,

  
Challenging even the most accepted mechanisms of a language is a proof 
of intelligence.


Descartes's doubt method :
The basic strategy of /Descartes/ 
http://www.philosophypages.com/ph/desc.htm's method of doubt 
http://www.philosophypages.com/dy/d9.htm#doubt is to defeat skepticism 
http://www.philosophypages.com/dy/s5.htm#skep on its own ground. Begin 
by doubting the truth of everything—not only the evidence 
http://www.philosophypages.com/dy/e9.htm#evid of the senses and the 
more extravagant cultural presuppositions, but even the fundamental 
process of reasoning itself. If any particular truth about the world can 
survive this extreme skeptical challenge, then it must be truly 
indubitable and therefore a perfectly certain foundation for knowledge


So let's make the method call parenthesis a truly indubitable and 
therefore a perfectly certain foundation.


Those who want to remove the parenthesis on python method calls raise 
the hand !


JM
--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Masklinn

On 31 Jul 2009, at 10:25 , Chris Rebert wrote:
On Fri, Jul 31, 2009 at 1:21 AM, Xavier Hocont...@xavierho.com  
wrote:
On Fri, Jul 31, 2009 at 6:08 PM, Masklinn maskl...@masklinn.net  
wrote:


snip... but since Python doesn't have anonymous functions that  
usage

tends to be a bit too verbose ... snip


Sorry to interrupt, but wouldn't lambda in Python be considered as
'anonymous functions'?


I believe full anonymous functions was intended by the author.
lambdas are limited to a single expression.
Yes, and they're limited to a single *expression*, so before Python 3,  
lambda: print foo is out. Likewise, it isn't possible to have an if/ 
else statement within a lambda (though a ternary is ok), or a with, …  
since Python statements aren't expressions.

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Iain King
On Jul 31, 8:28 am, Steven D'Aprano st...@remove-this-
cybersource.com.au wrote:
 On Thu, 30 Jul 2009 18:06:31 -0500, Robert Kern wrote:
  On 2009-07-30 16:44, r wrote:
  On Jul 30, 4:29 pm, Emmanuel Surleauemmanuel.surl...@gmail.com wrote:
  1.) No need to use () to call a function with no arguments. Python
  --  obj.m2().m3() --ugly
     Ruby --  obj.m1.m2.m3  -- sweeet!
  Man, i must admit i really like this, and your code will look so much
  cleaner.
  It has benefits - code does look better. It has also significant cons
  - it is ambiguous.
  For instance:

  a = b

  Is b a variable or a method called without parameter?

  Hello Emanuel,
  Again, who so ever names a method with such a non-descriptive name will
  get whats coming to him. And if you did for some reason use such a
  cryptic name as b, do yourself (and everyone else) a favor and follow
  it with () to denote the method call. Remember when something is
  optional that means you have an option to use it OR not use it.

  I believe his point is that it is ambiguous to the compiler, not humans
  reading the code. Python functions and methods are first class objects.
  They can be passed around. If they were auto-called, then you could not
  do this.

 Oh my, r is still around is he??? And now he's singing the praises of
 Ruby, the language which he treated as the Devil's Spawn when he first
 arrived. That's hilarious.

 But back on topic... r has missed the point. It's not that a=b is hard
 to understand because b is a poor name. The example could have been:

 def factory_function():
     magic = time.time()  # or whatever
     def inner():
         return magic
     return inner

 my_function = factory_function

 It's still ambiguous. Does the programmer intend my_function to become
 factory_function itself, or the output of factory_function?

Not only that - does 'return inner' return the function inner or the
result of function inner?

How does ruby pass a function as an object?

Iain
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Masklinn

On 31 Jul 2009, at 11:54 , Iain King wrote:

On Jul 31, 8:28 am, Steven D'Aprano st...@remove-this-
cybersource.com.au wrote:

On Thu, 30 Jul 2009 18:06:31 -0500, Robert Kern wrote:

On 2009-07-30 16:44, r wrote:
On Jul 30, 4:29 pm, Emmanuel Surleauemmanuel.surl...@gmail.com  
wrote:
1.) No need to use () to call a function with no arguments.  
Python

--  obj.m2().m3() --ugly
   Ruby --  obj.m1.m2.m3  -- sweeet!
Man, i must admit i really like this, and your code will look  
so much

cleaner.
It has benefits - code does look better. It has also significant  
cons

- it is ambiguous.
For instance:



a = b



Is b a variable or a method called without parameter?



Hello Emanuel,
Again, who so ever names a method with such a non-descriptive  
name will

get whats coming to him. And if you did for some reason use such a
cryptic name as b, do yourself (and everyone else) a favor and  
follow

it with () to denote the method call. Remember when something is
optional that means you have an option to use it OR not use it.


I believe his point is that it is ambiguous to the compiler, not  
humans
reading the code. Python functions and methods are first class  
objects.
They can be passed around. If they were auto-called, then you  
could not

do this.


Oh my, r is still around is he??? And now he's singing the  
praises of
Ruby, the language which he treated as the Devil's Spawn when he  
first

arrived. That's hilarious.

But back on topic... r has missed the point. It's not that a=b is  
hard

to understand because b is a poor name. The example could have been:

def factory_function():
magic = time.time()  # or whatever
def inner():
return magic
return inner

my_function = factory_function

It's still ambiguous. Does the programmer intend my_function to  
become

factory_function itself, or the output of factory_function?


Not only that - does 'return inner' return the function inner or the
result of function inner?

How does ruby pass a function as an object?
Ruby doesn't have functions as such. It has methods and blocks (which  
would be anonymous functions). `def` always creates methods.


To get a (bound) method object, you simply call `method` on an  
instance e.g. `foo.method(:bar)` is equivalent to `foo.bar` in Python  
(it returns a bound method object without calling it).


Blocks are usually created as part of the calls: `foo.bar  
{do_something}` the part between braces (braces included) is a block,  
which will be passed to the method `bar`. Sadly, Ruby's blocks are  
magical syntax (doesn't mean they have to be, in Smalltalk there's  
nothing magical about blocks for instance) so you can't just do `foo =  
{do_something}`, you have to turn them into `Proc` objects with the  
`proc` constructor (or `lambda`, it's equivalent and looks better so  
I'll use that): `foo = lambda {do_something}`. If you use the magical  
syntax previously shown, Ruby handles the turning of a block into an  
actual `Proc` instance.


And since Ruby doesn't have a `()` operator, it uses a method instead  
(`#call`), so you simply do `foo.call` to execute the proc and get its  
value.


All in all, much like Smalltalk, Ruby tends not to favor raw functions  
the way Python does, so a direct translation of the Python code  
doesn't make much sense.

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Bruno Desthuilliers

Steven D'Aprano a écrit :

On Thu, 30 Jul 2009 18:47:04 +0100, Tim Rowe wrote:


That and the fact that I couldn't stop laughing for long enough to learn
any more when I read in the Pragmatic Programmer's Guide that Ruby,
unlike less flexible languages, lets you alter the value of a constant.
Yep, as they say Bug = Undocumented feature!


That's no different from Python's constant by convention.


Well, at least Python doesn't pretend to have real symbolic constants - 
we all know it's only a convention !-)


We don't even 
get a compiler warning!


Of course - from the compiler's POV, it's only usual rebinding.


On the other hand, we don't have to prefix names with @ and @@,


Nope, we have to prefix them with 'self' or 'cls' (or even 
'self.__class__').


and we 
don't have the compiler trying to *guess* whether we're calling a 
function or referring to a variable.


Please re-read a bit more carefully - it's *all* method call. Python is 
'uniform' in obj.name is always an attribute lookup (methods being 
attributes), Ruby is uniform in that 'obj.name' is always a method call.


Somebody who knows more Ruby than me should try writing the Zen of Ruby. 
Something like:


(snip childish parody of Python Zen)

Steven, is that any useful ?



Although I'm sure Ruby has its good points. I'm not convinced anonymous 
code blocks are one of them though.


Ruby's code blocks come from Smalltalk, where they are an absolute 
necessity since message passing (which code blocks are part of) is the 
*only* builtin control flow in Smalltalk - so you just *need* this 
construction to provide branching and iterations.


Wether it makes sense to have code blocks in Ruby is another question 
since Ruby does provide traditional control flow features, but then one 
could question Python's lambda (hem...) too.

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Masklinn

On 31 Jul 2009, at 13:38 , Bruno Desthuilliers wrote:

Steven D'Aprano a écrit :

On Thu, 30 Jul 2009 18:47:04 +0100, Tim Rowe wrote:
That and the fact that I couldn't stop laughing for long enough to  
learn

any more when I read in the Pragmatic Programmer's Guide that Ruby,
unlike less flexible languages, lets you alter the value of a  
constant.

Yep, as they say Bug = Undocumented feature!

That's no different from Python's constant by convention.
Ruby's code blocks come from Smalltalk, where they are an absolute  
necessity since message passing (which code blocks are part of) is  
the *only* builtin control flow in Smalltalk - so you just *need*  
this construction to provide branching and iterations.


I'm not so sure about the way you say it. I'm pretty sure  
traditional flow control structures preceded Smalltalk by a pair of  
decades so it's not that Smalltalk's designers found it necessary to  
use blocks  messages, but that they understood blocks  messages  
could trivially replace most control structures (making *those*  
unnecessary), making the core language simpler and more flexible.


In other words, I see it the other way around.

Wether it makes sense to have code blocks in Ruby is another  
question since Ruby does provide traditional control flow features
Well it does at least allow for the creation of new flow control  
structures in library land when the existing ones aren't enough (e.g.  
allows Ruby not to require the introduction of a `with` statement).  
Though Ruby's blocks are nowhere near as flexible as Smalltalk's.

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Bruno Desthuilliers

Masklinn a écrit :

On 31 Jul 2009, at 13:38 , Bruno Desthuilliers wrote:

Steven D'Aprano a écrit :

On Thu, 30 Jul 2009 18:47:04 +0100, Tim Rowe wrote:
That and the fact that I couldn't stop laughing for long enough to 
learn

any more when I read in the Pragmatic Programmer's Guide that Ruby,
unlike less flexible languages, lets you alter the value of a 
constant.

Yep, as they say Bug = Undocumented feature!

That's no different from Python's constant by convention.
Ruby's code blocks come from Smalltalk, where they are an absolute 
necessity since message passing (which code blocks are part of) is the 
*only* builtin control flow in Smalltalk - so you just *need* this 
construction to provide branching and iterations.



I'm not so sure about the way you say it.


I'm not sure about the way you understand it !-)

I'm pretty sure traditional 
flow control structures preceded Smalltalk by a pair of decades


Yes, of course - and that's not the point. What's important is that:


so it's 
not that Smalltalk's designers found it necessary to use blocks  
messages, but that they understood blocks  messages could trivially 
replace most control structures (making *those* unnecessary), making the 
core language simpler and more flexible.


Exactly.


In other words, I see it the other way around.


My wording may have been a bit confusing, indeed. It was implied (but 
perhaps a bit unclear) that restricting control structures to messages 
and blocks was a design choice.


Wether it makes sense to have code blocks in Ruby is another question 
since Ruby does provide traditional control flow features


Well it does at least allow for the creation of new flow control 
structures in library land when the existing ones aren't enough (e.g. 
allows Ruby not to require the introduction of a `with` statement). 


Yeps. But then other traditionnal control flow features become redundant.


Though Ruby's blocks are nowhere near as flexible as Smalltalk's.

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Masklinn

On 31 Jul 2009, at 15:12 , Bruno Desthuilliers wrote:

Masklinn a écrit :

On 31 Jul 2009, at 13:38 , Bruno Desthuilliers wrote:

Steven D'Aprano a écrit :

On Thu, 30 Jul 2009 18:47:04 +0100, Tim Rowe wrote:
That and the fact that I couldn't stop laughing for long enough  
to learn
any more when I read in the Pragmatic Programmer's Guide that  
Ruby,
unlike less flexible languages, lets you alter the value of a  
constant.

Yep, as they say Bug = Undocumented feature!

That's no different from Python's constant by convention.
Ruby's code blocks come from Smalltalk, where they are an absolute  
necessity since message passing (which code blocks are part of) is  
the *only* builtin control flow in Smalltalk - so you just *need*  
this construction to provide branching and iterations.



[misunderstandings on my part/clarifications on yours]
Well it does at least allow for the creation of new flow control  
structures in library land when the existing ones aren't enough  
(e.g. allows Ruby not to require the introduction of a `with`  
statement).


Yeps. But then other traditionnal control flow features become  
redundant.
They can be anyway: Ruby doesn't deprecate most control flows as the  
actual usages of blocks are a bit restricted (cannot be used for  
`while` as it would require the serialization to a Proc, and Ruby's  
syntax doesn't allow sending multiple blocks to a method so `if…else`  
is out as well). And I assume they reintroduced the for…in sugar to  
ease the transition from more traditional languages (using #each and  
others seems the suggested collection iterators across the community).

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Ethan Furman

Steven D'Aprano wrote:

On Thu, 30 Jul 2009 18:47:04 +0100, Tim Rowe wrote:



That and the fact that I couldn't stop laughing for long enough to learn
any more when I read in the Pragmatic Programmer's Guide that Ruby,
unlike less flexible languages, lets you alter the value of a constant.
Yep, as they say Bug = Undocumented feature!



That's no different from Python's constant by convention. We don't even 
get a compiler warning!




That's quite different, actually.  Python doesn't claim to have 
constants!  Can't misinterpret what you can't have, can you?


[Holds breath while awaiting counter-example... :]

~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Iain King
On Jul 31, 4:08 pm, Ethan Furman et...@stoneleaf.us wrote:
 Steven D'Aprano wrote:
  On Thu, 30 Jul 2009 18:47:04 +0100, Tim Rowe wrote:

 That and the fact that I couldn't stop laughing for long enough to learn
 any more when I read in the Pragmatic Programmer's Guide that Ruby,
 unlike less flexible languages, lets you alter the value of a constant.
 Yep, as they say Bug = Undocumented feature!

  That's no different from Python's constant by convention. We don't even
  get a compiler warning!

 That's quite different, actually.  Python doesn't claim to have
 constants!  Can't misinterpret what you can't have, can you?

 [Holds breath while awaiting counter-example... :]

 ~Ethan~

The convention being detailed in PEP8: http://www.python.org/dev/peps/pep-0008/
basically, anything in ALL_CAPS is a constant, assuming you follow
those style guidelines.

Iain
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Benjamin Kaplan
On Fri, Jul 31, 2009 at 11:35 AM, Iain Kingiaink...@gmail.com wrote:
 On Jul 31, 4:08 pm, Ethan Furman et...@stoneleaf.us wrote:
 Steven D'Aprano wrote:
  On Thu, 30 Jul 2009 18:47:04 +0100, Tim Rowe wrote:

 That and the fact that I couldn't stop laughing for long enough to learn
 any more when I read in the Pragmatic Programmer's Guide that Ruby,
 unlike less flexible languages, lets you alter the value of a constant.
 Yep, as they say Bug = Undocumented feature!

  That's no different from Python's constant by convention. We don't even
  get a compiler warning!

 That's quite different, actually.  Python doesn't claim to have
 constants!  Can't misinterpret what you can't have, can you?

 [Holds breath while awaiting counter-example... :]

 ~Ethan~

 The convention being detailed in PEP8: 
 http://www.python.org/dev/peps/pep-0008/
 basically, anything in ALL_CAPS is a constant, assuming you follow
 those style guidelines.


Right, but that's a style guide and not a language definition. Nobody
claims that anything in there is a part of the language.

 Iain
 --
 http://mail.python.org/mailman/listinfo/python-list

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Steven D'Aprano
On Fri, 31 Jul 2009 13:38:56 +0200, Bruno Desthuilliers wrote:

 On the other hand, we don't have to prefix names with @ and @@,
 
 Nope, we have to prefix them with 'self' or 'cls' (or even
 'self.__class__').

Incorrect.

 class K:
... class_attribute = 'No @@ required.'
...
 K().class_attribute
'No @@ required.'


No 'self' or 'cls' in sight.


I can see a vague advantage to using @ to create instance attributes and 
@@ to creating class attributes -- it makes it easy to create class 
attributes inside a method without needing to do a double lookup. In 
Python terms:

def K:
def method(self):
self.__class__.attr = Class attribute

would be:

def K:
def method(self):
@@attr = Class attribute

Advantages: you save a few characters and (possibly!) a couple of runtime 
lookups.

Disadvantages: your code is filled with line noise. It's an arbitrary 
choice between @@ meaning instance attribute and @@ meaning class 
attribute -- there's no logical reason for choosing one over the other, 
so you have to memorise which is which. It's easy to get it wrong.

'self' and 'cls' at least are words, even if 'cls' is badly misspelled :)



 and we
 don't have the compiler trying to *guess* whether we're calling a
 function or referring to a variable.
 
 Please re-read a bit more carefully - it's *all* method call. 

What did I misread from here?

[quote]
When Ruby sees a name such as ``a'' in an expression, it needs to 
determine if it is a local variable reference or a call to a method with 
no parameters. To decide which is the case, Ruby uses a heuristic. As 
Ruby reads a source file, it keeps track of symbols that have been 
assigned to. It assumes that these symbols are variables. When it 
subsequently comes across a symbol that might be either a variable or a 
method call, it checks to see if it has seen a prior assignment to that 
symbol. If so, it treats the symbol as a variable; otherwise it treats it 
as a method call.
[end quote]

And see the example pathological case comparing a function call (not 
method) and a variable.

http://ruby-doc.org/docs/ProgrammingRuby/html/language.html


 Python is
 'uniform' in obj.name is always an attribute lookup (methods being
 attributes), Ruby is uniform in that 'obj.name' is always a method call.

Which would be relevant if I was talking about method calls, but I wasn't.



 Somebody who knows more Ruby than me should try writing the Zen of
 Ruby. Something like:
 
 (snip childish parody of Python Zen)
 
 Steven, is that any useful ?

It made me feel good.

But seriously, while I admit that I have very little Ruby experience, and 
so aren't in a great position to judge, it seems to me that Ruby doesn't 
have anything like Python's over-riding design principles (the Zen). If 
there is a design principle to Ruby, I can't see what it is.

I'm the first to admit that I'm far too inexperienced with the language 
to make this a fair judgement. Unfair it might be, but it doesn't 
necessarily mean I'm wrong! *wink*

Ruby just seems to be far more complicated than Python: things which 
Python does at runtime, with a function call, Ruby has special syntax for:

a bunch of words.split()
%w(a bunch of words)

ord('a')
?a

That makes the barrier to entry far higher: it's easier to leverage 
existing knowledge to interpret unfamiliar Python code than unfamiliar 
Ruby code. Or so it seems to me.

Oh, and I admit that Python decorators are a conspicuous counter-example. 
I wouldn't do without them, but neither would I expect somebody to intuit 
what they do.


 Although I'm sure Ruby has its good points. I'm not convinced anonymous
 code blocks are one of them though.
 
 Ruby's code blocks come from Smalltalk, where they are an absolute
 necessity since message passing (which code blocks are part of) is the
 *only* builtin control flow in Smalltalk - so you just *need* this
 construction to provide branching and iterations.

Just because Smalltalk had a particular (mis?)feature doesn't mean that 
other languages should copy it. I know, I know, Ruby people swear by 
anonymous code blocks, and I've read Paul Graham too. But I'm really not 
so sure that the benefits of anonymous code blocks are great enough to 
overcome the disadvantages of anonymous code blocks.


 Wether it makes sense to have code blocks in Ruby is another question
 since Ruby does provide traditional control flow features, but then one
 could question Python's lambda (hem...) too.

lambda, by allowing the function to be only a single expression, doesn't 
suffer the disadvantages of anonymous code blocks. lambda, by allowing 
the function to be only a single expression, also has fewer advantages 
than anonymous code blocks. I think lambda ends up on the more 
advantages than disadvantages side. I'm keeping my mind open regarding 
Ruby code blocks.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Masklinn

On 31 Jul 2009, at 17:55 , Steven D'Aprano wrote:
But seriously, while I admit that I have very little Ruby  
experience, and
so aren't in a great position to judge, it seems to me that Ruby  
doesn't
have anything like Python's over-riding design principles (the Zen).  
If

there is a design principle to Ruby, I can't see what it is.

As far as I know, Ruby doesn't have anything like the Zen no. But then  
again, I don't know any language other than Python with such a document.



Ruby just seems to be far more complicated than Python: things which
Python does at runtime, with a function call, Ruby has special  
syntax for:


a bunch of words.split()
%w(a bunch of words)

ord('a')
?a


That's the Perl heritage. And since it inherits from Perl, TIMTOWTDI:
 a bunch of words.split
= [a, bunch, of, words]
 a[0]
= 97
(yes, the indexing operator returns a character code if provided a  
single index. With two, it returns as string slice)


Oh and %w() isn't really equivalent to split(): you don't use it to  
split a string but to create a list of strings, so the equivalent  
expression in Python would be `[a, bunch, of, words]`.



That makes the barrier to entry far higher: it's easier to leverage
existing knowledge to interpret unfamiliar Python code than unfamiliar
Ruby code. Or so it seems to me.


That's probable.

Although I'm sure Ruby has its good points. I'm not convinced  
anonymous

code blocks are one of them though.


Ruby's code blocks come from Smalltalk, where they are an absolute
necessity since message passing (which code blocks are part of) is  
the

*only* builtin control flow in Smalltalk - so you just *need* this
construction to provide branching and iterations.


Just because Smalltalk had a particular (mis?)feature doesn't mean  
that

other languages should copy it. I know, I know, Ruby people swear by
anonymous code blocks, and I've read Paul Graham too. But I'm really  
not

so sure that the benefits of anonymous code blocks are great enough to
overcome the disadvantages of anonymous code blocks.


What are the disadvantages of anonymous functions?

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Terry Reedy

Masklinn wrote:

#each is simply a method that takes a function (called blocks in ruby). 
One could call it a higher-order method I guess.


It's an implementation of the concept of internal iteration: instead of 
collections yielding iterator objects, and programmers using those 
through specially-built iteration constructs (e.g. `for…in`), 
collections control iteration over themselves (the iteration is 
performed inside the collection, thus the internal part) and the 
programmer provides the operations to perform at each iterative step 
through (usually) a function.


Python's iterator protocol was developed in part to avoid the 
(inside-out) callback style of programming. Writing virtual collections 
as generator functions instead of iterator or iterable classes saves a 
lot of boilerplate code. The itertools modules shows how nicely 
iterators can be composed in a way that is much more awkward with callbacks.


In Python (assuming we had anonymous defs and an each method on lists), 
the following loop:


for item in some_list:
do_something(item)
do_something_else(item)

some_list.each((def (item):
do_something(item)
do_something_else(item)
))


And how does Ruby do the equivalent of

def double(it):
  for i in it:
yield 2*i

for i,j in zip(double(some_list), some_gen_func(args)):
  print(do_something(i+j,i-j))

Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Tim Rowe
2009/7/31 Steven D'Aprano st...@remove-this-cybersource.com.au:
 On Thu, 30 Jul 2009 18:47:04 +0100, Tim Rowe wrote:

 That and the fact that I couldn't stop laughing for long enough to learn
 any more when I read in the Pragmatic Programmer's Guide that Ruby,
 unlike less flexible languages, lets you alter the value of a constant.
 Yep, as they say Bug = Undocumented feature!

 That's no different from Python's constant by convention. We don't even
 get a compiler warning!

We don't actually *declare* that something is constant and then have
that declaration ignored. Python doesn't lie to us, although (as in
any language) a programmer might.

-- 
Tim Rowe
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Falcolas
On Jul 31, 3:49 am, Masklinn maskl...@masklinn.net wrote:
 On 31 Jul 2009, at 10:25 , Chris Rebert wrote: On Fri, Jul 31, 2009 at 1:21 
 AM, Xavier Hocont...@xavierho.com  
  wrote:
  On Fri, Jul 31, 2009 at 6:08 PM, Masklinn maskl...@masklinn.net  
  wrote:

  snip... but since Python doesn't have anonymous functions that  
  usage
  tends to be a bit too verbose ... snip

  Sorry to interrupt, but wouldn't lambda in Python be considered as
  'anonymous functions'?

  I believe full anonymous functions was intended by the author.
  lambdas are limited to a single expression.

 Yes, and they're limited to a single *expression*, so before Python 3,  
 lambda: print foo is out. Likewise, it isn't possible to have an if/
 else statement within a lambda (though a ternary is ok), or a with, …  
 since Python statements aren't expressions.

Perhaps you can't do lambda foo: print foo, but you *can* do lambda x:
sys.stdout.write(x).

Combined with the ternary if, it seem sufficient if you want to stick
to the ideal Simple is better than Complex. Sure, with statements
allowed in anonymous functions, you can save on a line of typing (def
blargh(x):), but I don't feel the obfuscation is worth the cost.

~G
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Masklinn

On 31 Jul 2009, at 18:24 , Terry Reedy wrote:

Masklinn wrote:

#each is simply a method that takes a function (called blocks in  
ruby). One could call it a higher-order method I guess.
It's an implementation of the concept of internal iteration:  
instead of collections yielding iterator objects, and programmers  
using those through specially-built iteration constructs (e.g. `for… 
in`), collections control iteration over themselves (the iteration  
is performed inside the collection, thus the internal part) and  
the programmer provides the operations to perform at each iterative  
step through (usually) a function.


Python's iterator protocol was developed in part to avoid the  
(inside-out) callback style of programming. Writing virtual  
collections as generator functions instead of iterator or iterable  
classes saves a lot of boilerplate code. The itertools modules shows  
how nicely iterators can be composed in a way that is much more  
awkward with callbacks.


In Python (assuming we had anonymous defs and an each method on  
lists), the following loop:

   for item in some_list:
   do_something(item)
   do_something_else(item)
   some_list.each((def (item):
   do_something(item)
   do_something_else(item)
   ))


And how does Ruby do the equivalent of

def double(it):
 for i in it:
   yield 2*i

for i,j in zip(double(some_list), some_gen_func(args)):
 print(do_something(i+j,i-j))



Somethign along the lines of

some_list.map{|e| 2*e}.zip(some_gen_func(args)).each {|i, j|
puts(do_something(i+j, i-j))
}

The `#each` call after `#zip` is not actually necessary, but I find it  
clearer. Oh, and some_gen_func and do_something probably wouldn't work  
that way (as I said above, Ruby isn't big on named functions and  
doesn't actually have them)

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Steven D'Aprano
On Fri, 31 Jul 2009 18:15:15 +0200, Masklinn wrote:

  I know, I know, Ruby people swear by
  anonymous code blocks, and I've read Paul Graham too. But I'm really
  not so sure that the benefits of anonymous code blocks are great
  enough to overcome the disadvantages of anonymous code blocks.
 
 What are the disadvantages of anonymous functions?

In no particular order, and not necessarily exhaustive:

* The risk of obfuscation in your code. That's fairly minimal for 
lambdas, because they're just a single expression, but for a large 
anonymous code block (ACB) defined inside a named function, it may be 
difficult for the reader to easily distinguish which bits are the outer 
function and which are the ACB.


* Loss of useful debugging information. Take this example from Python:

 def main(f):
... return f(3)
...
 main(lambda n: 2/(n-3))
Traceback (most recent call last):
  File stdin, line 1, in module
  File stdin, line 2, in main
  File stdin, line 1, in lambda
ZeroDivisionError: integer division or modulo by zero

 def my_special_function(n):
... return 2/(n-3)
...
 main(my_special_function)
Traceback (most recent call last):
  File stdin, line 1, in module
  File stdin, line 2, in main
  File stdin, line 2, in my_special_function
ZeroDivisionError: integer division or modulo by zero

If your code has only one anonymous function (whether a lambda or a full 
multi-line block), then it's easy to identify which lambda raised the 
exception: there is only one it could be. But if your code uses lots of 
lambdas, the lack of a function name makes it hard to distinguish one 
lambda from another lambda. Anonymity makes identification harder.


* Risk of code-duplication and breaking the principle of Once And Only 
Once. Anonymous functions are generally created, used, then immediately 
thrown away -- or at least made more-or-less inaccessible for reuse. An 
anonymous function stored in a callback still exists, but the coder isn't 
able to easily re-use it for another callback somewhere else in the code. 
Consequently, there's a temptation for the coder to write the same 
function multiple times:

add_button(Parrot, colour=blue, callback=lambda x: x.stuff('a'))
add_button(Cheese, flavour=tasty, callback=lambda x: x.thing('b'))
add_button(Canary, colour=yellow, callback=lambda x: x.stuff('a'))

instead of:

def bird_callback(x):
return x.stuff('a')

add_button(Parrot, colour=blue, callback=bird_callback)
add_button(Cheese, flavour=tasty, callback=lambda x: x.thing('b'))
add_button(Canary, colour=yellow, callback=bird_callback)

* Recursion is more or less impossible without fragile tricks.

(At least for Python. I don't know how recursion operates in Ruby.)





-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Emmanuel Surleau
On Friday 31 July 2009 18:54:23 Tim Rowe wrote:
 2009/7/31 Steven D'Aprano st...@remove-this-cybersource.com.au:
  On Thu, 30 Jul 2009 18:47:04 +0100, Tim Rowe wrote:
  That and the fact that I couldn't stop laughing for long enough to learn
  any more when I read in the Pragmatic Programmer's Guide that Ruby,
  unlike less flexible languages, lets you alter the value of a constant.
  Yep, as they say Bug = Undocumented feature!
 
  That's no different from Python's constant by convention. We don't even
  get a compiler warning!

 We don't actually *declare* that something is constant and then have
 that declaration ignored. Python doesn't lie to us, although (as in
 any language) a programmer might.

You could say that Ruby doesn't either, you just need to read the 
documentation. Ruby's unwritten motto is flexibility über alles. In this 
regard, it is consistent (1). Not much is really bolted down in Ruby. You get 
encapsulation, but it's so easy to break that it's mostly symbolic. It's a 
language which gives great power to the programmer. Whether Ruby programmers 
handle this power responsibly is another debate.

Cheers,

Emm

(1) I find Ruby to be pretty consistent in general, which is not always the 
case of Python.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Masklinn

On 31 Jul 2009, at 20:17 , Steven D'Aprano wrote:

On Fri, 31 Jul 2009 18:15:15 +0200, Masklinn wrote:


I know, I know, Ruby people swear by
anonymous code blocks, and I've read Paul Graham too. But I'm really
not so sure that the benefits of anonymous code blocks are great
enough to overcome the disadvantages of anonymous code blocks.


What are the disadvantages of anonymous functions?


In no particular order, and not necessarily exhaustive:

* The risk of obfuscation in your code. That's fairly minimal for
lambdas, because they're just a single expression, but for a large
anonymous code block (ACB) defined inside a named function, it may be
difficult for the reader to easily distinguish which bits are the  
outer

function and which are the ACB.


I believe that one's unadulterated BS.


* Loss of useful debugging information. Take this example from Python:


def main(f):

... return f(3)
...

main(lambda n: 2/(n-3))

Traceback (most recent call last):
 File stdin, line 1, in module
 File stdin, line 2, in main
 File stdin, line 1, in lambda
ZeroDivisionError: integer division or modulo by zero


def my_special_function(n):

... return 2/(n-3)
...

main(my_special_function)

Traceback (most recent call last):
 File stdin, line 1, in module
 File stdin, line 2, in main
 File stdin, line 2, in my_special_function
ZeroDivisionError: integer division or modulo by zero

If your code has only one anonymous function (whether a lambda or a  
full

multi-line block), then it's easy to identify which lambda raised the
exception: there is only one it could be. But if your code uses lots  
of

lambdas, the lack of a function name makes it hard to distinguish one
lambda from another lambda. Anonymity makes identification harder.

The traceback gives you the line of the anonymous function (even in  
python) so unless you have several anonymous functions on the same  
line, there's no reason why that would be much of an issue.  
Furthermore, Python doesn't provide any more information when the  
error happens out of a function (in a `for` or a `with`), so it's not  
like there's much of a difference here between Ruby's block-based  
approach and Python's statements-based approach.



* Risk of code-duplication and breaking the principle of Once And Only
Once. Anonymous functions are generally created, used, then  
immediately
thrown away -- or at least made more-or-less inaccessible for reuse.  
An
anonymous function stored in a callback still exists, but the coder  
isn't
able to easily re-use it for another callback somewhere else in the  
code.

Consequently, there's a temptation for the coder to write the same
function multiple times:

add_button(Parrot, colour=blue, callback=lambda x: x.stuff('a'))
add_button(Cheese, flavour=tasty, callback=lambda x: x.thing('b'))
add_button(Canary, colour=yellow, callback=lambda x: x.stuff('a'))

instead of:

def bird_callback(x):
   return x.stuff('a')

add_button(Parrot, colour=blue, callback=bird_callback)
add_button(Cheese, flavour=tasty, callback=lambda x: x.thing('b'))
add_button(Canary, colour=yellow, callback=bird_callback)

Yes, that one I can give you though I don't think that's a big issue.  
And it's not like it's hard to extract the anonymous function into a  
named one and then use that on the third strike, so I really don't  
believe that point holds much water.



* Recursion is more or less impossible without fragile tricks.

(At least for Python. I don't know how recursion operates in Ruby.)
Code blocks are rarely if ever used recursively. If an operation is  
using anonymous functions recursively, then there's often something  
very wrong with the idea leading to that code. So I find this  
objection irrelevant.

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Steven D'Aprano
On Fri, 31 Jul 2009 20:41:12 +0200, Emmanuel Surleau wrote:

 We don't actually *declare* that something is constant and then have
 that declaration ignored. Python doesn't lie to us, although (as in any
 language) a programmer might.
 
 You could say that Ruby doesn't either, 

Well you could say a lot of things. Admittedly you don't need a separate 
constant declaration, but creating a variable name with an initial 
uppercase letter is sufficient to make it a (supposed) constant:

irb(main):049:0* Thing = 5
= 5
irb(main):050:0 Thing = 7
(irb):50: warning: already initialized constant Thing
= 7

As you can see, Ruby (well, irb at least) considers that Thing is a 
constant, and then goes ahead and changes it anyway.

Apart from the use of an arbitrary naming convention instead of an 
explicit make this constant declaration, and the feeble way Ruby 
capitulates when you change it, I think having actual write-once 
constants is actually a plus.


 you just need to read the
 documentation. Ruby's unwritten motto is flexibility über alles. In
 this regard, it is consistent (1). 

It's consistent in its inconsistency sort of thing perhaps?


 Not much is really bolted down in
 Ruby. You get encapsulation, but it's so easy to break that it's mostly
 symbolic. 

Out of curiosity, can you read/write class and instance attributes from 
outside the class without using a getter/setter?



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-31 Thread Emmanuel Surleau
On Saturday 01 August 2009 03:46:12 Steven D'Aprano wrote:
 On Fri, 31 Jul 2009 20:41:12 +0200, Emmanuel Surleau wrote:
  We don't actually *declare* that something is constant and then have
  that declaration ignored. Python doesn't lie to us, although (as in any
  language) a programmer might.
 
  You could say that Ruby doesn't either,

 Well you could say a lot of things. Admittedly you don't need a separate
 constant declaration, but creating a variable name with an initial
 uppercase letter is sufficient to make it a (supposed) constant:

*shrugs* I see it as a way to encourage (but not force) people to follow a 
coding convention. Is this such a bad thing?

 irb(main):049:0* Thing = 5
 = 5
 irb(main):050:0 Thing = 7
 (irb):50: warning: already initialized constant Thing
 = 7

 As you can see, Ruby (well, irb at least) considers that Thing is a
 constant, and then goes ahead and changes it anyway.

I'm quite aware of how constants work in Ruby, yes :)

 Apart from the use of an arbitrary naming convention instead of an
 explicit make this constant declaration, and the feeble way Ruby
 capitulates when you change it, I think having actual write-once
 constants is actually a plus.

Nothing wrong with naming conventions. This encourages a uniform coding style, 
something which Python could really use.

  you just need to read the
  documentation. Ruby's unwritten motto is flexibility über alles. In
  this regard, it is consistent (1).

 It's consistent in its inconsistency sort of thing perhaps?

No, just consistent.

  Not much is really bolted down in
  Ruby. You get encapsulation, but it's so easy to break that it's mostly
  symbolic.

 Out of curiosity, can you read/write class and instance attributes from
 outside the class without using a getter/setter?

If you have an instance f class with a attribute @foo which doesn't have an 
accessor, you could do:

f.instance_eval(@foo='bar')

And yes, instance_eval is evil.

Cheers,

Emm
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Marco Mariani

r wrote:


My adventures in Ruby.


Oh, it's you.
Good boy.
Now, why don't you have a look at javascript and come back in six months?
Or better yet, haskell and twelve months.

thanks

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Masklinn

On 30 Jul 2009, at 06:04 , alex23 wrote:

On Jul 30, 1:06 pm, r rt8...@gmail.com wrote:

1.) No need to use () to call a function with no arguments.
Python -- obj.m2().m3() --ugly
  Ruby -- obj.m1.m2.m3  -- sweeet!
Man, i must admit i really like this, and your code will look so much
cleaner.


How do you distinguish between calling a method with no arguments, and
getting access to the method object itself (because it _is_ an object,
y'know, it's OO all the way down...)?

As chris pointed out, there's a method for that, to which a symbol is  
provided: `Object#method(methodname)`, which is basically equivalent  
to `getattr(object, methodname)` in Python.



2.) the .each method
container.each{|localVar| block}
This method can really cleanup some ugly for loops, although i really
like the readability of for loops.


map(lambda localVar: block, sequence)

or:

def usefully_named_func(var):
   block
   return var

transformed = [usefully_named_func(v) for v in sequence]

The issue here is of course that `map` and comprehensions are  
transformations. `#each` exists for effectful iterations (Ruby has  
`#map` for the map operation). So the intent expressed by `#each` and  
`map` isn't the same. Furthermore and this is the most problematic  
limitation of Python here, `lambda` doesn't allow complex  
transformations due to its restrictions, so one has to switch to named  
functions which works but isn't sexy (and tends to lower readability  
imo).



3.) true OOP
Now before you go and get all huffy over this statement, hear me
out. Python is the best language in the world. But it damn sure has
some warts! len(this) instead of obj.length max(that) instead of
[1,2,3,4,5].max().


As the Zen says: '[P]racticality beats purity'. Personally, I'm not
sure how a handful of convenient built-in functions make a language in
which _everything is an object_ somehow false OO.

That's an interesting point, but not relevant at the end of the day:  
`foo.length` and `length(foo)` have the same practicality. On the  
other hand Ruby can be praised for the coherence: everything's a  
method period end of the story; while Python does have a dichotomy  
between methods and functions/generic methods (whether or not that  
dichotomy bothers users is another issue).



With max(), this is a built-in that takes _any_ iterable and an
optional key function, and returns the highest value as per the key.
This means that _every_ iterable object - as _well_ as every object
that supports enough of the iterator protocol - can be handed to max()
and a result obtained. So at best, I just need to make sure my new
sequence-type provides the iterator protocol and viola, it works with
max() without me having to hand-code a .max() that's specialised for
my new type, and without Python forcing me to have a complex
inheritance chain just to make sure I include the right
MaxableSequence ancestor to inherit the right .max().

Well interestingly, Ruby works pretty much the same way. Where Python  
asks that you implement the iterator protocol to have `max` work, Ruby  
asks that you implement the `each` method (also called the Enumerable  
protocol) and mixin `Enumerable` (http://ruby-doc.org/core/classes/Enumerable.html 
). Then you get max (and min, map, etc…) for free. Of course you're  
free to re-implement all of them manually if you wish to do so (or if  
you need those operations to return your custom collection rather than  
arrays). Enumerable is merely a convenience mixin. So there's no big  
difference here (and note that mixins aren't necessarily part of the  
inheritance chain, though they're implemented that way in Ruby).


Also, it's voilà not viola (a viola is a bowed string instrument,  
slightly bigger than a violin, whereas voilà is a french interjection  
used to call attention or suggest the appearance of something, as if  
by magic).



PS stay tuned for more from this series


Is this going to be more of you telling us - without any apparent
irony whatsoever - how Ruby has some valid points after all your
vilification last year when we said the same to you?  If so, where can
I sign up?!

I fear I'll have to agree with that sentiment.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread superpollo

Masklinn wrote:
...
That's an interesting point, but not relevant at the end of the day:  
`foo.length` and `length(foo)` have the same practicality. On the  
other hand Ruby can be praised for the coherence: everything's a  method 
period end of the story; while Python does have a dichotomy  between 
methods and functions/generic methods (whether or not that  dichotomy 
bothers users is another issue).

...
how would you correct a newbie (like me) who says:

well, the main difference between a function and a method (from the 
caller's pow) is a syntactic one:


fun(obj, arguments)

as opposed to:

obj.met(arguments)

but the effect is just about the same.

?

bye
--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Jean-Michel Pichavant

superpollo wrote:

Masklinn wrote:
...
That's an interesting point, but not relevant at the end of the day:  
`foo.length` and `length(foo)` have the same practicality. On the  
other hand Ruby can be praised for the coherence: everything's a  
method period end of the story; while Python does have a dichotomy  
between methods and functions/generic methods (whether or not that  
dichotomy bothers users is another issue).

...
how would you correct a newbie (like me) who says:

well, the main difference between a function and a method (from the 
caller's pow) is a syntactic one:


fun(obj, arguments)

as opposed to:

obj.met(arguments)

but the effect is just about the same.

?

bye


My suggestion

- OO programming:
length(foo) calls the foo instance(or class for some language) length method
length(bar) calls the bar instance length method, it is **not** the same 
than the foo method


- non OO programming:
length(foo) calls the length function with foo as parameter
length(bar) calls the **same** length function with the bar parameter 
(so you better make sure length is handling both foo and bar)


So the difference is definitely **not** a syntactic one, but it is true 
that the syntax obj.method() better illustrates the bind mechanism of 
the OO programming.


JM

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Masklinn

On 30 Jul 2009, at 14:03 , superpollo wrote:

Masklinn wrote:
...
That's an interesting point, but not relevant at the end of the  
day:  `foo.length` and `length(foo)` have the same practicality.  
On the other hand Ruby can be praised for the coherence:  
everything's a  method period end of the story; while Python does  
have a dichotomy  between methods and functions/generic methods  
(whether or not that  dichotomy bothers users is another issue).

...
how would you correct a newbie (like me) who says:

well, the main difference between a function and a method (from the  
caller's pow) is a syntactic one:


fun(obj, arguments)

as opposed to:

obj.met(arguments)

but the effect is just about the same.

?
Depending on the way things are implemented, it can be very similar  
(see CLOS' generic functions, which have the same look as functions  
but dispatch based on parameter types).


In Python, the difference would be that functions don't automatically  
dispatch (you have a function for everybody, and any dispatch you  
perform based on argument types or other qualifiers has to be done  
manually) whereas methods do dispatch on the first [implied] argument  
(you execute a precise method corresponding to the object it's being  
called on).


So fun(obj, *arguments) will call the same `fun` whether `obj` is an  
int, a string or an HTTPFactory whereas obj.met(*arguments) will call  
a different `met` each time (they all have the same unqualified name  
[and signature if it's part of a protocol], but might very well be  
implemented completely differently). Therefore -- in python -- the  
effect isn't anywhere just about the same.


--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Colin J. Williams

Some have treated this as a troll.  I don't.
r wrote:
[snip]


1.) No need to use () to call a function with no arguments.
Python -- obj.m2().m3() --ugly
  Ruby -- obj.m1.m2.m3  -- sweeet!
Man, i must admit i really like this, and your code will look so much
cleaner.


+1

2.) the .each method
container.each{|localVar| block}
This method can really cleanup some ugly for loops, although i really
like the readability of for loops.


Not clear.

3.) true OOP
Now before you go and get all huffy over this statement, hear me
out. Python is the best language in the world. But it damn sure has
some warts! len(this) instead of obj.length max(that) instead of
[1,2,3,4,5].max(). You know what i am talking about here people. We
all get complacent and It seems easier to just cope with these
problems instead of fighting for change. But look at the French,  WHAT
THE HELL HAS THAT DONE FOR THEM, *NOTHING*


+0.6
or better [1, 2, 3, 4, 5].len or [1, 2, 3, 4, 5].max

What has this got to do with true OOP?

[snip]
--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Falcolas
On Jul 29, 9:06 pm, r rt8...@gmail.com wrote:

 1.) No need to use () to call a function with no arguments.
 Python -- obj.m2().m3() --ugly
   Ruby -- obj.m1.m2.m3  -- sweeet!
 Man, i must admit i really like this, and your code will look so much
 cleaner.

I personally would not prefer this, and would likely continue to use
(), precisely for code clarity - let me explain:

foo.nextval
foo.val
foo.previousval

Which of the calls above referenced instance variables, and which ones
called functions which changed the internal state of foo? I would have
trouble saying, just based on the calls above. I would have to go back
to the definition or documentation of foo to identify which is doing
what. On the other hand, the following gives a better clue as to what
is happening (granted not perfect, but better):

foo.nextval()
foo.val
foo.previousval()

~G
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Inky 788
On Jul 30, 12:04 am, alex23 wuwe...@gmail.com wrote:
 On Jul 30, 1:06 pm, r rt8...@gmail.com wrote:

  1.) No need to use () to call a function with no arguments.
  Python -- obj.m2().m3() --ugly
    Ruby -- obj.m1.m2.m3  -- sweeet!
  Man, i must admit i really like this, and your code will look so much
  cleaner.

 How do you distinguish between calling a method with no arguments, and
 getting access to the method object itself (because it _is_ an object,
 y'know, it's OO all the way down...)?

I agree with alex here. Will take the explicit syntax over the extra
cognitive load of figuring out exactly what's going on with
`obj.m1.m2.m3`.

Python has its warts, but requiring ()'s on function calls isn't one
of them. :)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread r
On Jul 30, 11:31 am, Falcolas garri...@gmail.com wrote:
 On Jul 29, 9:06 pm, r rt8...@gmail.com wrote:

  1.) No need to use () to call a function with no arguments.
  Python -- obj.m2().m3() --ugly
    Ruby -- obj.m1.m2.m3  -- sweeet!
  Man, i must admit i really like this, and your code will look so much
  cleaner.

 I personally would not prefer this, and would likely continue to use
 (), precisely for code clarity - let me explain:

 foo.nextval
 foo.val
 foo.previousval

 Which of the calls above referenced instance variables, and which ones
 called functions which changed the internal state of foo? I would have
 trouble saying, just based on the calls above. I would have to go back
 to the definition or documentation of foo to identify which is doing
 what. On the other hand, the following gives a better clue as to what
 is happening (granted not perfect, but better):

 foo.nextval()
 foo.val
 foo.previousval()

 ~G

I held your exact same view before i learned the Ruby language. And
your veiw makes some good points, however, naming conventions with
eliminate this problem all together. All method names should use the
underscore to separate words, variable names should use camelCase,
constants in all caps, and class defs in titlecase.

def go_and_do_this_for_me_now(self, *args)
self.variableNameHere
MyClassNameHere
THISISACONSTANT -or- THIS_IS_A_CONSTANT


in your example i would have used the following

foo.next_value
foo.value
foo.prev_value

good naming conventions will make your life (and everybody else's)
much easier when debugging code.



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Masklinn

On 30 Jul 2009, at 18:31 , Falcolas wrote:

On Jul 29, 9:06 pm, r rt8...@gmail.com wrote:


1.) No need to use () to call a function with no arguments.
Python -- obj.m2().m3() --ugly
  Ruby -- obj.m1.m2.m3  -- sweeet!
Man, i must admit i really like this, and your code will look so much
cleaner.


I personally would not prefer this, and would likely continue to use
(), precisely for code clarity - let me explain:

foo.nextval
foo.val
foo.previousval

Which of the calls above referenced instance variables
Well, that's very simple: none of them. In Ruby (as in Smalltalk),  
public instance variables simply don't exist.


and which ones called functions which changed the internal state of  
foo?
That you can't say, but neither can you say in Python as they could  
all be properties. And of course just because it's a method doesn't  
mean it mutates the object.



I would have
trouble saying, just based on the calls above. I would have to go back
to the definition or documentation of foo to identify which is doing
what. On the other hand, the following gives a better clue as to what
is happening (granted not perfect, but better):

Well... it doesn't give much of a clue no really.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Masklinn

On 30 Jul 2009, at 19:01 , Inky 788 wrote:

On Jul 30, 12:04 am, alex23 wuwe...@gmail.com wrote:

On Jul 30, 1:06 pm, r rt8...@gmail.com wrote:


1.) No need to use () to call a function with no arguments.
Python -- obj.m2().m3() --ugly
  Ruby -- obj.m1.m2.m3  -- sweeet!
Man, i must admit i really like this, and your code will look so  
much

cleaner.


How do you distinguish between calling a method with no arguments,  
and
getting access to the method object itself (because it _is_ an  
object,

y'know, it's OO all the way down...)?


I agree with alex here. Will take the explicit syntax over the extra
cognitive load of figuring out exactly what's going on with
`obj.m1.m2.m3`.
There's no cognitive load whatsoever: it's calling methods. Always.  
Ruby simply gives you no other option. Now it could be very simple  
methods to instance attributes, akin to a java getter, but it's still  
only methods.


Furthermore Ruby has a pretty nice convention (sadly not used enough I  
think) taken from Scheme where it's possible to postfix a method name  
with ! (note: the ! is part of the name, there's no magic) to  
indicate that this method modifies the object it's called on rather  
than simply returning stuff.


--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread r
On Jul 30, 12:15 pm, Masklinn maskl...@masklinn.net wrote:
[snip]
 Furthermore Ruby has a pretty nice convention (sadly not used enough I  
 think) taken from Scheme where it's possible to postfix a method name  
 with ! (note: the ! is part of the name, there's no magic) to  
 indicate that this method modifies the object it's called on rather  
 than simply returning stuff.

Another oddity i did not like at first but must admit is growing on me
  vector.reverse -- returns a new reversed vector
  vector.reverse! -- modifies the instance vector in-place

Of course in python you would do...
  vector.reverse -- in-place
  vector.reversed -- in-place

The above example works pretty good, but this doesn't always sound
good. Take for example this...
  point3d.offset -- return a new pt
  point3d.offseted -- What did you say!?!?!

Now try Ruby's way
  point3d.offset!
  point3d.offset

a symbol works better for these things
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread r
Traceback (most recent post last):
  File Confessions of a Python Fanboy, lines (13,14), in post
vector.reverse -- in-place
vector.reversed -- in-place
DumbMistakeError:

Of course in python you would do...
  vector.reverse -- in-place
  vector.reversed -- new vector
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Jean-Michel Pichavant

r wrote:

On Jul 30, 11:31 am, Falcolas garri...@gmail.com wrote:
  

On Jul 29, 9:06 pm, r rt8...@gmail.com wrote:



1.) No need to use () to call a function with no arguments.
Python -- obj.m2().m3() --ugly
  Ruby -- obj.m1.m2.m3  -- sweeet!
Man, i must admit i really like this, and your code will look so much
cleaner.
  

I personally would not prefer this, and would likely continue to use
(), precisely for code clarity - let me explain:

foo.nextval
foo.val
foo.previousval

Which of the calls above referenced instance variables, and which ones
called functions which changed the internal state of foo? I would have
trouble saying, just based on the calls above. I would have to go back
to the definition or documentation of foo to identify which is doing
what. On the other hand, the following gives a better clue as to what
is happening (granted not perfect, but better):

foo.nextval()
foo.val
foo.previousval()

~G



I held your exact same view before i learned the Ruby language. And
your veiw makes some good points, however, naming conventions with
eliminate this problem all together. All method names should use the
underscore to separate words, variable names should use camelCase,
constants in all caps, and class defs in titlecase.

def go_and_do_this_for_me_now(self, *args)
self.variableNameHere
MyClassNameHere
THISISACONSTANT -or- THIS_IS_A_CONSTANT


in your example i would have used the following

foo.next_value
foo.value
foo.prev_value

good naming conventions will make your life (and everybody else's)
much easier when debugging code.



  
How do I know if foo.value is an attribute or if it is a method that 
returns the foo value ? It seems you can make the difference only when 
tokens are composed of more than one word, not very handy don't you think ?


Just feeding the troll.

JM

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread r
On Jul 30, 12:37 pm, Jean-Michel Pichavant jeanmic...@sequans.com
wrote:
 r wrote:
  On Jul 30, 11:31 am, Falcolas garri...@gmail.com wrote:

  On Jul 29, 9:06 pm, r rt8...@gmail.com wrote:

  1.) No need to use () to call a function with no arguments.
  Python -- obj.m2().m3() --ugly
    Ruby -- obj.m1.m2.m3  -- sweeet!
  Man, i must admit i really like this, and your code will look so much
  cleaner.

  I personally would not prefer this, and would likely continue to use
  (), precisely for code clarity - let me explain:

  foo.nextval
  foo.val
  foo.previousval

  Which of the calls above referenced instance variables, and which ones
  called functions which changed the internal state of foo? I would have
  trouble saying, just based on the calls above. I would have to go back
  to the definition or documentation of foo to identify which is doing
  what. On the other hand, the following gives a better clue as to what
  is happening (granted not perfect, but better):

  foo.nextval()
  foo.val
  foo.previousval()

  ~G

  I held your exact same view before i learned the Ruby language. And
  your veiw makes some good points, however, naming conventions with
  eliminate this problem all together. All method names should use the
  underscore to separate words, variable names should use camelCase,
  constants in all caps, and class defs in titlecase.

  def go_and_do_this_for_me_now(self, *args)
  self.variableNameHere
  MyClassNameHere
  THISISACONSTANT -or- THIS_IS_A_CONSTANT

  in your example i would have used the following

  foo.next_value
  foo.value
  foo.prev_value

  good naming conventions will make your life (and everybody else's)
  much easier when debugging code.

 How do I know if foo.value is an attribute or if it is a method that
 returns the foo value ? It seems you can make the difference only when
 tokens are composed of more than one word, not very handy don't you think ?

 Just feeding the troll.

 JM

You can still use empty parenthesis in Ruby if that floats your boat.

obj.method() -- note the empty parenthesis

I am just saying don't make them mandatory, thats all. In any case
where ambiguity abounds, by all means use the damn parenthisis.

Now Ruby will even let you call a method *that has arguments* with no
parenthisis -- however, i do not think this is a good idea. Consider
the following

  Geom::Transformation.rotation pt, vec, ang
  bad coder!, bad!
  ...and leads to worn out eyeball parsers in a hurry

  Geom::Transformation.rotation(pt, vec, ang)
  yes, good boy!


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Carsten Haese
r wrote:
 Of course in python you would do...
   vector.reverse -- in-place
   vector.reversed -- in-place

You do know that only one of those works in-place, right?

 The above example works pretty good, but this doesn't always sound
 good. Take for example this...
   point3d.offset -- return a new pt
   point3d.offseted -- What did you say!?!?!
 
 Now try Ruby's way
   point3d.offset!
   point3d.offset
 
 a symbol works better for these things

Or you could use a better verb:

point3d.move - modifies in place
point3d.moved - returns a new point

-Carsten

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Tim Rowe
2009/7/30 r rt8...@gmail.com:

 Like your
 first lay, your first programing language can leave an indelible mark
 on you

That's true. FOCAL scarred me for life.

 but i now realize Ruby has some good
 things going for it.

Any language that gets any sort of real use has to have. For instance,
I love Ada's numeric types (you can specify either the minimum number
of significant figures or the maximum delta for a real type, and it
will give you a type that satisfies that -- or a compilation error if
it can't.  That matches genuine problem domains far better than having
to remember how many bits in a double on this particular system, and
reduces portability bugs).

 3.) true OOP
 Now before you go and get all huffy over this statement, hear me
 out. Python is the best language in the world. But it damn sure has
 some warts! len(this) instead of obj.length max(that) instead of
 [1,2,3,4,5].max(). You know what i am talking about here people. We
 all get complacent and It seems easier to just cope with these
 problems instead of fighting for change. But look at the French,  WHAT
 THE HELL HAS THAT DONE FOR THEM, *NOTHING*

I seem to recall recent studies showing that the French were on
average happier than Brits or Americans. Don't knock it!

 As for the rest of Ruby, i am not impressed. The redundant usage of
 end over indention perplexes me. The Perlish feel of require and
 the horrifically cryptic idioms of Ruby regular expressions. The
 puts and gets seem childish and the math class does not even have
 a degrees or radians function!

The operating system dependency built into the language did it for me.
That and the fact that I couldn't stop laughing for long enough to
learn any more when I read in the Pragmatic Programmer's Guide that
Ruby, unlike less flexible languages, lets you alter the value of a
constant. Yep, as they say Bug = Undocumented feature!

-- 
Tim Rowe
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Masklinn

On 30 Jul 2009, at 19:37 , Jean-Michel Pichavant wrote:

r wrote:

On Jul 30, 11:31 am, Falcolas garri...@gmail.com wrote:


On Jul 29, 9:06 pm, r rt8...@gmail.com wrote:



1.) No need to use () to call a function with no arguments.
Python -- obj.m2().m3() --ugly
 Ruby -- obj.m1.m2.m3  -- sweeet!
Man, i must admit i really like this, and your code will look so  
much

cleaner.


I personally would not prefer this, and would likely continue to use
(), precisely for code clarity - let me explain:

foo.nextval
foo.val
foo.previousval

Which of the calls above referenced instance variables, and which  
ones
called functions which changed the internal state of foo? I would  
have
trouble saying, just based on the calls above. I would have to go  
back

to the definition or documentation of foo to identify which is doing
what. On the other hand, the following gives a better clue as to  
what

is happening (granted not perfect, but better):

foo.nextval()
foo.val
foo.previousval()

~G



I held your exact same view before i learned the Ruby language. And
your veiw makes some good points, however, naming conventions with
eliminate this problem all together. All method names should use  
the

underscore to separate words, variable names should use camelCase,
constants in all caps, and class defs in titlecase.

def go_and_do_this_for_me_now(self, *args)
self.variableNameHere
MyClassNameHere
THISISACONSTANT -or- THIS_IS_A_CONSTANT


in your example i would have used the following

foo.next_value
foo.value
foo.prev_value

good naming conventions will make your life (and everybody else's)
much easier when debugging code.

How do I know if foo.value is an attribute or if it is a method that  
returns the foo value ?
It cannot be an attribute. Ruby doesn't give access to attributes,  
they're always solely private (as in Smalltalk). Also you shouldn't  
reply to r, he has no idea about what he's talking about.


--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Masklinn

On 30 Jul 2009, at 19:42 , Carsten Haese wrote:

r wrote:

Of course in python you would do...
 vector.reverse -- in-place
 vector.reversed -- in-place


You do know that only one of those works in-place, right?

Well mostly because the other one doesn't exist (as python has  
`lst.reverse()` but `reversed(lst)`) but he was probably talking  
hypothetically. Or something.

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread superpollo

r wrote:

On Jul 30, 12:15 pm, Masklinn maskl...@masklinn.net wrote:
[snip]

Furthermore Ruby has a pretty nice convention (sadly not used enough I  
think) taken from Scheme where it's possible to postfix a method name  
with ! (note: the ! is part of the name, there's no magic) to  
indicate that this method modifies the object it's called on rather  
than simply returning stuff.



Another oddity i did not like at first but must admit is growing on me
  vector.reverse -- returns a new reversed vector
  vector.reverse! -- modifies the instance vector in-place

Of course in python you would do...
  vector.reverse -- in-place
  vector.reversed -- in-place



how to reverse a string in python? must i usa a temp? like:

 s = ciccio
 l = list(s)
 l.reverse()
 s = .join(l)
 s
'oiccic'


???

bye

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Falcolas
On Jul 30, 11:56 am, Masklinn maskl...@masklinn.net wrote:
 On 30 Jul 2009, at 19:37 , Jean-Michel Pichavant wrote:

  r wrote:

  How do I know if foo.value is an attribute or if it is a method that  
  returns the foo value ?

 It cannot be an attribute. Ruby doesn't give access to attributes,  
 they're always solely private (as in Smalltalk). Also you shouldn't  
 reply to r, he has no idea about what he's talking about.

That doesn't sound like a feature I would appreciate much, though I am
a big fan of we're all adults here programming. Though if they are
all functions, then adding parentheses wouldn't make much difference,
so offering the option of getting rid of them makes sense.

 I would have
 trouble saying, just based on the calls above. I would have to go back
 to the definition or documentation of foo to identify which is doing
 what. On the other hand, the following gives a better clue as to what
 is happening (granted not perfect, but better):

 Well... it doesn't give much of a clue no really.

It, with few exceptions, tells me that fetching the value foo.val will
not modify the state of foo. Important stuff, at least to me.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread superpollo

Tim Rowe wrote:

2009/7/30 r rt8...@gmail.com:


Like your
first lay, your first programing language can leave an indelible mark
on you



That's true. FOCAL scarred me for life.



but i now realize Ruby has some good
things going for it.



Any language that gets any sort of real use has to have. For instance,
I love Ada's numeric types (you can specify either the minimum number
of significant figures or the maximum delta for a real type, and it
will give you a type that satisfies that -- or a compilation error if
it can't.  That matches genuine problem domains far better


doesn't the decimal module do some of that too?

bye
--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Masklinn

On 30 Jul 2009, at 20:05 , superpollo wrote:

r wrote:

On Jul 30, 12:15 pm, Masklinn maskl...@masklinn.net wrote:
[snip]
Furthermore Ruby has a pretty nice convention (sadly not used  
enough I  think) taken from Scheme where it's possible to postfix  
a method name  with ! (note: the ! is part of the name,  
there's no magic) to  indicate that this method modifies the  
object it's called on rather  than simply returning stuff.
Another oddity i did not like at first but must admit is growing on  
me

 vector.reverse -- returns a new reversed vector
 vector.reverse! -- modifies the instance vector in-place
Of course in python you would do...
 vector.reverse -- in-place
 vector.reversed -- in-place


how to reverse a string in python? must i usa a temp? like:

 s = ciccio
 l = list(s)
 l.reverse()
 s = .join(l)
 s
'oiccic'


???

bye


s = s[::-1]
--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Masklinn

On 30 Jul 2009, at 20:06 , Falcolas wrote:

On Jul 30, 11:56 am, Masklinn maskl...@masklinn.net wrote:

On 30 Jul 2009, at 19:37 , Jean-Michel Pichavant wrote:


r wrote:



How do I know if foo.value is an attribute or if it is a method that
returns the foo value ?


It cannot be an attribute. Ruby doesn't give access to attributes,
they're always solely private (as in Smalltalk). Also you shouldn't
reply to r, he has no idea about what he's talking about.


That doesn't sound like a feature I would appreciate much, though I am
a big fan of we're all adults here programming. Though if they are
all functions, then adding parentheses wouldn't make much difference,
so offering the option of getting rid of them makes sense.


That's pretty much it.


I would have
trouble saying, just based on the calls above. I would have to go  
back

to the definition or documentation of foo to identify which is doing
what. On the other hand, the following gives a better clue as to  
what

is happening (granted not perfect, but better):



Well... it doesn't give much of a clue no really.


It, with few exceptions, tells me that fetching the value foo.val will
not modify the state of foo. Important stuff, at least to me.
But because of those few exceptions, it really tells you that foo.val  
*probably* doesn't modify the state of foo. Unless you go source- 
diving, you can't know for sure. Only Haskell gives you that kind of  
guarantees (and even then, the code you call could have an unsafe*  
somewhere)

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread superpollo

MRAB wrote:

superpollo wrote:

...

how to reverse a string in python? must i usa a temp? like:

  s = ciccio
  l = list(s)
  l.reverse()
  s = .join(l)
  s
'oiccic'
 

???


Use slicing with a step of -1:

  s = ciccio
  s[::-1]
'oiccic'


lol

bye
--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Jan Kaliszewski

30-07-2009 o 13:36:49 Masklinn maskl...@masklinn.net wrote:


On 30 Jul 2009, at 06:04 , alex23 wrote:

On Jul 30, 1:06 pm, r rt8...@gmail.com wrote:

2.) the .each method
container.each{|localVar| block}
This method can really cleanup some ugly for loops, although i really
like the readability of for loops.


map(lambda localVar: block, sequence)

or:

def usefully_named_func(var):
   block
   return var

transformed = [usefully_named_func(v) for v in sequence]

The issue here is of course that `map` and comprehensions are  
transformations. `#each` exists for effectful iterations (Ruby has  
`#map` for the map operation). So the intent expressed by `#each` and  
`map` isn't the same. Furthermore and this is the most problematic  
limitation of Python here, `lambda` doesn't allow complex  
transformations due to its restrictions, so one has to switch to named  
functions which works but isn't sexy (and tends to lower readability  
imo).


I don't see any real limitation. What's wrong in:

for localVar in container:
block

And ruby's container.each is very similar to Python's iter()

*j

--
Jan Kaliszewski (zuo) z...@chopin.edu.pl
--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Masklinn

On 30 Jul 2009, at 22:23 , Jan Kaliszewski wrote:

30-07-2009 o 13:36:49 Masklinn maskl...@masklinn.net wrote:


On 30 Jul 2009, at 06:04 , alex23 wrote:

On Jul 30, 1:06 pm, r rt8...@gmail.com wrote:

2.) the .each method
container.each{|localVar| block}
This method can really cleanup some ugly for loops, although i  
really

like the readability of for loops.


map(lambda localVar: block, sequence)

or:

def usefully_named_func(var):
  block
  return var

transformed = [usefully_named_func(v) for v in sequence]

The issue here is of course that `map` and comprehensions are  
transformations. `#each` exists for effectful iterations (Ruby has  
`#map` for the map operation). So the intent expressed by `#each`  
and `map` isn't the same. Furthermore and this is the most  
problematic limitation of Python here, `lambda` doesn't allow  
complex transformations due to its restrictions, so one has to  
switch to named functions which works but isn't sexy (and tends to  
lower readability imo).


I don't see any real limitation. What's wrong in:

for localVar in container:
   block

Well what's wrong with using that rather than `map`, `filter` or a  
list comprehension? (and if you don't see what the limitations of  
`lambda` are, you probably very rarely use it)



And ruby's container.each is very similar to Python's iter()


Uh… not at all…

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Terry Reedy

superpollo wrote:

r wrote:



how to reverse a string in python? must i usa a temp? like:

  s = ciccio
  l = list(s)
  l.reverse()
  s = .join(l)
  s
'oiccic'
 

???


No.
 ''.join(list(reversed('abc')))
'cba'
 'abc'[2::-1]
'cba'
 'abc'[10::-1]
'cba'

Any int = len(string)-1 will do, so the call to len will usually not be 
necessary.


Needing strings reversed is not common.  More common might be

for char in reversed(somestring): process(char)

Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread r
On Jul 30, 3:55 pm, Terry Reedy tjre...@udel.edu wrote:
 superpollo wrote:
  r wrote:
  how to reverse a string in python? must i usa a temp? like:
[snip]
 Terry Jan Reedy

No r never wrote anything like that. reversing a string is RTFM
material, this is basic stuff here! Stop quoting me as saying things i
did not say! I never asked how to reverse a string, superpollo
did.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Emmanuel Surleau
 1.) No need to use () to call a function with no arguments.
 Python -- obj.m2().m3() --ugly
   Ruby -- obj.m1.m2.m3  -- sweeet!
 Man, i must admit i really like this, and your code will look so much
 cleaner.

It has benefits - code does look better. It has also significant cons - it is 
ambiguous.
For instance:

a = b

Is b a variable or a method called without parameter?

 2.) the .each method
 container.each{|localVar| block}
 This method can really cleanup some ugly for loops, although i really
 like the readability of for loops.

It's not only the 'each' method. It's anonymous callbacks everywhere, which 
is pretty cool. Certainly one of my favourite features of Ruby.

 3.) true OOP
 Now before you go and get all huffy over this statement, hear me
 out. Python is the best language in the world. But it damn sure has
 some warts! len(this) instead of obj.length max(that) instead of
 [1,2,3,4,5].max(). You know what i am talking about here people. We
 all get complacent and It seems easier to just cope with these
 problems instead of fighting for change.

While ob.length() is more clear to read, it follows the same operator logic 
as __iter__. Which is OK, I suppose.

 But look at the French,  WHAT
 THE HELL HAS THAT DONE FOR THEM, *NOTHING*

I assume this was supposed to be funny?

 As for the rest of Ruby, i am not impressed. The redundant usage of
 end over indention perplexes me.

You have the choice to use {}. If you are confused over languages which do not 
use indentation to delimit code blocks, you should probably try out a few 
languages outside Python.

 The Perlish feel of require and
 the horrifically cryptic idioms of Ruby regular expressions.

Cryptic idioms of Ruby regular expressions? They are Perl-like regular 
expressions, not exactly a far cry from what re does. Also, you can chain 
them, which is extremely nice.

 The puts and gets seem childish

Well, they're short and easy. Writing gets is more intuitive than using 
raw_input()

 and the math class does not even have
 a degrees or radians function!

 Anyway, i thought i would get this off my chest and catch up with old
 friends in the meantime. We can all make Python the perfect language
 it needs to be, but it ain't gonna be easy!
 Thank you all

 PS stay tuned for more from this series

Cheers,

Emm
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Luis Zarrabeitia
On Thursday 30 July 2009 04:41:57 pm Masklinn wrote:
 On 30 Jul 2009, at 22:23 , Jan Kaliszewski wrote:
  30-07-2009 o 13:36:49 Masklinn maskl...@masklinn.net wrote:
 
  I don't see any real limitation. What's wrong in:
 
  for localVar in container:
 block

 Well what's wrong with using that rather than `map`, `filter` or a
 list comprehension?

As I understood the question, it was was wrong in 'for var in container' in 
comparison with ruby's container.each?

What's the (semantic) difference between

for localVar in container:
block

and

container.each{|localVar| block}

?

(the sintactic difference is quite clear... if there is no semantic 
difference, I'd rather use the first version!)

Map, filter and comprehensions have little to do with that (syntactic sugar 
that may allow some optimizations, but that could otherwise be replaced by 
the for loop).

 (and if you don't see what the limitations of 
 `lambda` are, you probably very rarely use it)

I'm not the poster, but: 
* I use lambdas, a lot.
* I know python lambdas are limited, compared with theoretical lambdas.
* I don't [usually] see that as a limitation.

Most of the time, the limitation is the lack of multiline/multiexpression 
lambdas. But I've never seen a case where I would /prefer/ to have a 
multiline function definition inside a comprehension or method invocation, 
instead of a named function defined two lines before it.

(The second famous limitation is the inability to use statements inside 
lambdas... luckily, now that we have a ternary operator and a print function, 
it is less limiting)

  And ruby's container.each is very similar to Python's iter()

 Uh… not at all…

I agree with this. It should have said that they are equivalent in the sense 
that they represent the iterator protocols of both languages, and nothing 
more.

I'd like to ask, what container.each is, exactly? It looks like a function 
call (as I've learned a few posts ago), but, what are its arguments? How the 
looping works? Does it receive a code object that it has to execute? 
Is .each some kind of magic keyword? (This has little to do with python or 
the current thread, so feel free to reply off-list if you want to...)

Regards,

Luis.

-- 
Luis Zarrabeitia (aka Kyrie)
Fac. de Matemática y Computación, UH.
http://profesores.matcom.uh.cu/~kyrie
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread r
On Jul 30, 4:57 pm, Luis Zarrabeitia ky...@uh.cu wrote:
[snip]
 I'd like to ask, what container.each is, exactly? It looks like a function
 call (as I've learned a few posts ago), but, what are its arguments? How the
 looping works? Does it receive a code object that it has to execute?
 Is .each some kind of magic keyword? (This has little to do with python or
 the current thread, so feel free to reply off-list if you want to...)

 Regards,

 Luis.

Hello Luis,

I think your question is completely valid within the context of this
thread. The purpose of his thread was to get feedback on how Python
and Ruby ideas could be cumulated into the best high level language.
And being that i am the BDFL of the Confessions of a Python Fanboy
thread, you have my personal permission to continue on with this
subject matter...,

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Robert Kern

On 2009-07-30 16:44, r wrote:

On Jul 30, 4:29 pm, Emmanuel Surleauemmanuel.surl...@gmail.com
wrote:

1.) No need to use () to call a function with no arguments.
Python --  obj.m2().m3() --ugly
   Ruby --  obj.m1.m2.m3  -- sweeet!
Man, i must admit i really like this, and your code will look so much
cleaner.

It has benefits - code does look better. It has also significant cons - it is
ambiguous.
For instance:

a = b

Is b a variable or a method called without parameter?


Hello Emanuel,
Again, who so ever names a method with such a non-descriptive name
will get whats coming to him. And if you did for some reason use such
a cryptic name as b, do yourself (and everyone else) a favor and
follow it with () to denote the method call. Remember when something
is optional that means you have an option to use it OR not use it.


I believe his point is that it is ambiguous to the compiler, not humans reading 
the code. Python functions and methods are first class objects. They can be 
passed around. If they were auto-called, then you could not do this.


--
Robert Kern

I have come to believe that the whole world is an enigma, a harmless enigma
 that is made terrible by our own mad attempt to interpret it as though it had
 an underlying truth.
  -- Umberto Eco

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Tim Rowe
2009/7/30 superpollo u...@example.net:
 Tim Rowe wrote:

 Any language that gets any sort of real use has to have. For instance,
 I love Ada's numeric types (you can specify either the minimum number
 of significant figures or the maximum delta for a real type, and it
 will give you a type that satisfies that -- or a compilation error if
 it can't.  That matches genuine problem domains far better

 doesn't the decimal module do some of that too?

Not as far as I can tell, no.

-- 
Tim Rowe
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Terry Reedy

r wrote:

On Jul 30, 3:55 pm, Terry Reedy tjre...@udel.edu wrote:

superpollo wrote:

r wrote:
how to reverse a string in python? must i usa a temp? like:

[snip]

Terry Jan Reedy


No r never wrote anything like that. reversing a string is RTFM
material, this is basic stuff here! Stop quoting me as saying things i
did not say! I never asked how to reverse a string, superpollo
did.


Nor did what I posted say that you did. The above says that superpollo 
wrote how to reverse..., as he did. Quotes are indented once more than 
the author. The above says 'r wrote' with no indent and then No..., 
which you did write, indented once.


I agree that since I did not quote anything that you wrote, I should 
also have snipped your name. But I least I do attempt to snip material 
irrelavant to my comments.


Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread I V
On Thu, 30 Jul 2009 17:57:48 -0400, Luis Zarrabeitia wrote:
 As I understood the question, it was was wrong in 'for var in
 container' in comparison with ruby's container.each?
 
 What's the (semantic) difference between
 
 for localVar in container:
 block
 
 and
 
 container.each{|localVar| block}

I don't think each is a particularly compelling example of Ruby's 
blocks - as you say, it's easily replaceable with a Python for-loop. The 
advantage of Ruby's syntax is that it allows you to define further 
functions that are sort-of like new control structures. So you have 
things like:

File.open('myfile', 'r') do |file|
while line = file.gets
puts line
end
end

Which is like a python's:

with open('myfile', 'r) as f:
for line in f:
print f

However, with Ruby, this kind of scoping construct can be added without 
adding new syntax. Another interesting example is the Sinatra web 
framework, which allows you to write a web app with something like:

get '/' do
Index page
end

post '/:name' do 
Posted to  + params[:name]
end

Which looks something like a DSL for web apps, but is accomplished solely 
with normal ruby functions. More: http://www.sinatrarb.com/intro.html

Ruby blocks are, fundamentally, syntactic sugar, but they are kind of 
neat.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-30 Thread Emmanuel Surleau
On Friday 31 July 2009 01:06:31 Robert Kern wrote:
 On 2009-07-30 16:44, r wrote:
  On Jul 30, 4:29 pm, Emmanuel Surleauemmanuel.surl...@gmail.com
 
  wrote:
  1.) No need to use () to call a function with no arguments.
  Python --  obj.m2().m3() --ugly
 Ruby --  obj.m1.m2.m3  -- sweeet!
  Man, i must admit i really like this, and your code will look so much
  cleaner.
 
  It has benefits - code does look better. It has also significant cons -
  it is ambiguous.
  For instance:
 
  a = b
 
  Is b a variable or a method called without parameter?
 
  Hello Emanuel,
  Again, who so ever names a method with such a non-descriptive name
  will get whats coming to him. And if you did for some reason use such
  a cryptic name as b, do yourself (and everyone else) a favor and
  follow it with () to denote the method call. Remember when something
  is optional that means you have an option to use it OR not use it.

 I believe his point is that it is ambiguous to the compiler, not humans
 reading the code.

Actually, both. Use a variable you didn't initialize? This is what you get:

NameError: undefined local variable or method `b' for main:Object
from (irb):1

The compiler has no idea if b is a variable or a method. It also makes it very 
easy to shadow an existing method by declaring a variable of the same name, 
which is problematic. I suppose it is a side-effect of Ruby's Perl 
philosophical inheritance - except that Perl uses sigils to prefix its 
variables, negating this issue.

Cheers,

Emm
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-29 Thread alex23
On Jul 30, 1:06 pm, r rt8...@gmail.com wrote:
 1.) No need to use () to call a function with no arguments.
 Python -- obj.m2().m3() --ugly
   Ruby -- obj.m1.m2.m3  -- sweeet!
 Man, i must admit i really like this, and your code will look so much
 cleaner.

How do you distinguish between calling a method with no arguments, and
getting access to the method object itself (because it _is_ an object,
y'know, it's OO all the way down...)?

 2.) the .each method
 container.each{|localVar| block}
 This method can really cleanup some ugly for loops, although i really
 like the readability of for loops.

map(lambda localVar: block, sequence)

or:

def usefully_named_func(var):
block
return var

transformed = [usefully_named_func(v) for v in sequence]

 3.) true OOP
 Now before you go and get all huffy over this statement, hear me
 out. Python is the best language in the world. But it damn sure has
 some warts! len(this) instead of obj.length max(that) instead of
 [1,2,3,4,5].max().

As the Zen says: '[P]racticality beats purity'. Personally, I'm not
sure how a handful of convenient built-in functions make a language in
which _everything is an object_ somehow false OO.

If you're really that concerned with writing true OO (for some
wildly variable value of true), there's nothing stopping you from
doing so now:

obj.__len__()

With max(), this is a built-in that takes _any_ iterable and an
optional key function, and returns the highest value as per the key.
This means that _every_ iterable object - as _well_ as every object
that supports enough of the iterator protocol - can be handed to max()
and a result obtained. So at best, I just need to make sure my new
sequence-type provides the iterator protocol and viola, it works with
max() without me having to hand-code a .max() that's specialised for
my new type, and without Python forcing me to have a complex
inheritance chain just to make sure I include the right
MaxableSequence ancestor to inherit the right .max().

 PS stay tuned for more from this series

Is this going to be more of you telling us - without any apparent
irony whatsoever - how Ruby has some valid points after all your
vilification last year when we said the same to you?  If so, where can
I sign up?!

(You should consider trading guest spot posts with Xah Lee on your
respective blogs. You both have a very similar approach to programming
 programming languages and I think the synergy would be amazing to
see.)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-29 Thread Chris Rebert
On Wed, Jul 29, 2009 at 9:04 PM, alex23wuwe...@gmail.com wrote:
 On Jul 30, 1:06 pm, r rt8...@gmail.com wrote:
 1.) No need to use () to call a function with no arguments.
 Python -- obj.m2().m3() --ugly
   Ruby -- obj.m1.m2.m3  -- sweeet!
 Man, i must admit i really like this, and your code will look so much
 cleaner.

 How do you distinguish between calling a method with no arguments, and
 getting access to the method object itself (because it _is_ an object,
 y'know, it's OO all the way down...)?

IIRC from the Pickaxe, to get at a method object, you call a method on
the object whose specific job it is to return method objects.
Unsurprisingly, this method is itself named method. So:

foo.bar #calls the bar method on foo
foo.method(:bar) #returns the method bar of foo, as an object

Cheers,
Chris
-- 
http://blog.rebertia.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Confessions of a Python fanboy

2009-07-29 Thread Carl Banks
On Jul 29, 9:04 pm, alex23 wuwe...@gmail.com wrote:
 On Jul 30, 1:06 pm, r rt8...@gmail.com wrote:

  1.) No need to use () to call a function with no arguments.
  Python -- obj.m2().m3() --ugly
    Ruby -- obj.m1.m2.m3  -- sweeet!
  Man, i must admit i really like this, and your code will look so much
  cleaner.

 How do you distinguish between calling a method with no arguments, and
 getting access to the method object itself (because it _is_ an object,
 y'know, it's OO all the way down...)?

  2.) the .each method
  container.each{|localVar| block}
  This method can really cleanup some ugly for loops, although i really
  like the readability of for loops.

 map(lambda localVar: block, sequence)

 or:

 def usefully_named_func(var):
     block
     return var

 transformed = [usefully_named_func(v) for v in sequence]

  3.) true OOP
  Now before you go and get all huffy over this statement, hear me
  out. Python is the best language in the world. But it damn sure has
  some warts! len(this) instead of obj.length max(that) instead of
  [1,2,3,4,5].max().

 As the Zen says: '[P]racticality beats purity'. Personally, I'm not
 sure how a handful of convenient built-in functions make a language in
 which _everything is an object_ somehow false OO.

 If you're really that concerned with writing true OO (for some
 wildly variable value of true), there's nothing stopping you from
 doing so now:

     obj.__len__()

 With max(), this is a built-in that takes _any_ iterable and an
 optional key function, and returns the highest value as per the key.
 This means that _every_ iterable object - as _well_ as every object
 that supports enough of the iterator protocol - can be handed to max()
 and a result obtained. So at best, I just need to make sure my new
 sequence-type provides the iterator protocol and viola, it works with
 max() without me having to hand-code a .max() that's specialised for
 my new type, and without Python forcing me to have a complex
 inheritance chain just to make sure I include the right
 MaxableSequence ancestor to inherit the right .max().

  PS stay tuned for more from this series

 Is this going to be more of you telling us - without any apparent
 irony whatsoever - how Ruby has some valid points after all your
 vilification last year when we said the same to you?  If so, where can
 I sign up?!

 (You should consider trading guest spot posts with Xah Lee on your
 respective blogs. You both have a very similar approach to programming
  programming languages and I think the synergy would be amazing to
 see.)

Here is some wisdom from Guido van Rossum on the matter:

http://mail.python.org/pipermail/python-dev/2006-May/064841.html


Carl Banks
-- 
http://mail.python.org/mailman/listinfo/python-list