Re: a Python person's experience with Ruby

2007-12-11 Thread Lou Pecora
In article <[EMAIL PROTECTED]>,
 Bruno Desthuilliers <[EMAIL PROTECTED]> wrote:

> Lou Pecora a écrit :
> > In article <[EMAIL PROTECTED]>,
> >  Bruno Desthuilliers <[EMAIL PROTECTED]> wrote:
> > 
> > 
> >>>Thus: close;
> >>>could replace close();
> 
> *Please* give proper attribution. I'd *never* suggest such a thing.

I apologize.

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

Re: a Python person's experience with Ruby

2007-12-10 Thread Chris Mellon
On Dec 9, 2007 5:11 AM, Arnaud Delobelle <[EMAIL PROTECTED]> wrote:
> On Dec 9, 12:15 am, Bruno Desthuilliers
> <[EMAIL PROTECTED]> wrote:
> > Richard Jones a écrit :
> >
> >
> >
> > > Bruno Desthuilliers wrote:
> >
> > >>class A(object):
> > >>   @apply
> > >>   def a():
> > >> def fget(self):
> > >>   return self._a
> > >> def fset(self, val):
> > >>   self._a = val
> > >> return property(**locals())
> > >>   def __init__(self):
> > >> self.a = "foo"
> >
> > > That property setup seems overly complicated. As far as I can see, it only
> > > avoids defining the setter in the class namespace,
> >
> > Yes. That's mosly the point.
> >
> > > yet is more complicated
> > > and obfuscated to boot ;)
> >
> > Well, that's your POV, so what can I say ? It's indeed a bit hackish,
> > and requires a couple minutes of attention the first time you see it.
> > And you just have to learn it once !-)
>
> Perhaps 'return property(fget, fset)' would be easier to make sense of
> than **locals()
>
> > Now I'd certainly prefer something like:
> >
> > class A(object):
> > @propget
> > def a(self):
> >   return self._a
> > @propset
> > def a(self, val):
> >   self._a = val
> >
> > But until there's something similar *builtin*, I'll stick to the @apply
> > trick.
>
> At first sight, I like the look of this. Obviously I can't provide a
> builtin implementation, but there's an easy way to achieve this.  It
> uses sys._getframe but there is no need to fiddle with metaclasses:
>


Something very like this will be in 3k, and I believe is also being
backported to 2.6. See python-dev archives for more.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: a Python person's experience with Ruby

2007-12-10 Thread Bruno Desthuilliers
MonkeeSage a écrit :
> On Dec 9, 6:23 pm, MonkeeSage <[EMAIL PROTECTED]> wrote:
>> Hi Bruno,
>>
>> I think that we've been having a mainly "semantic" (pun intended)
>> dispute. I think you're right, that we've been using the same words
>> with different meanings.

Fine. So we may have a chance to get out there !-)

(snip)
>> I would like to (try to) clarify a little about my use of wording. By
>> "attribute" I was referring to a member of an object (*other than*
>> toplevel). I was of course using "method" to refer to callable
>> attributes (and I would use "function" for callable attributes bound
>> to toplevel), and I was using "variable" to refer to non-callable
>> attributes. By "tagging" I meant that attributes without a
>> "tag" (e.g., __call__) are not included in the MRO for an object; they
>> must be "tagged" as something other than a "variable".

Nope. We've been thru the distinction between a callable attribute and a 
methodin another nearby thread, so won't come back on this. wrt/ mro, 
it's being used for *all* attributes. That is, the look up rule for an 
attribute is :

1. instance's __dict__
2. class's __dict__
3. all classes __dict__s in the class's mro

NB : not taking __getattribute__ and __getattr__ hooks into account here.

>> As for ruby, I think the opcodes will help me clarify...

Not for me, sorry - my time to deal with my own ignorance !-)

 require 'parse_tree'
>> => true
 ParseTree.translate(%q{
>> class A
>>   def foo
>> "bar"
>>   end
>> end
>> A.new.foo})
>>
>> => [:block, [:class, :A, nil, [:scope, [:defn, :foo, [:scope, [:block,
>> [:args], [:str, "bar"]], [:call, [:call,
>> [:const, :A], :new], :foo]]
>>
>> Notice that #new and #foo are both CALL ops. All attribute access is
>> CALL (i.e., "method"). There really is no such thing as a non-callable
>> "attribute" in ruby.

For a definition of attribute being different from 'member variable'. 
But what we disagreed was more about the definitions of 'attribute' and 
'callable' !-)

>> Given this, I see the addition the instance variable also being an
>> attribute as a *huge* difference between the ruby code and your
>> initial example. An attribute can be named the same as an lval and
>> return or set the value of the lval (e.g., @a), but it's no different
>> from any other method.

You still have both a member variable and an 'attribute'. And the member 
variable is stored in the instance, while the 'attribute' (that is, the 
getter and setter methods) are stored with the class. From this POV, 
this is the equivalent of the Python snippet using a property.

>> But at the same time, I can see how my python example can be seen as
>> *wildly* different (WTF?) as well.

The WTF was about the class attribute. Did you try it with a mutable 
object instead of a string, and more than one instance ?-)

>> Maybe there is no easy way to
>> provide a true formally equivalent translation due to the
>> implementation differences of the languages

That's why I think the important point here is the semantic, not the 
implementation (while talking about the method/non-method distinction in 
Python is clearly about implementation).

>> Anyhow, sorry for the confusion.

You don't have to be sorry. We're both guilty (if guilty of anything) 
and honestly, I tend to be a bit on the nit-pick side, which sometimes 
doesn't help.

> Ps. To answer a question you asked, "callable" objects don't generally
> implement a #call method--just Proc objects and method references
> [class Method instances] do, which even though they have a #call
> method, aren't usually considered "callable" since you can't call them
> directly--the #call method could as easily be named #run or #evaluate
> or whatever. Accessing a name in ruby basically does something like:
> VCALL name (== if parens on name like a() skip to call step, otherwise
> check for LVAL in scope and return value if found, otherwise FCALL/
> CALL and return result). You can use the #define_method method to
> create a new "callable."

Thanks for the precisions.

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


Re: a Python person's experience with Ruby

2007-12-10 Thread Virgil Dupras
On Dec 9, 1:15 am, Bruno Desthuilliers
<[EMAIL PROTECTED]> wrote:
> Richard Jones a écrit :
>
>
>
> > Bruno Desthuilliers wrote:
>
> >>class A(object):
> >>   @apply
> >>   def a():
> >> def fget(self):
> >>   return self._a
> >> def fset(self, val):
> >>   self._a = val
> >> return property(**locals())
> >>   def __init__(self):
> >> self.a = "foo"
>
> > That property setup seems overly complicated. As far as I can see, it only
> > avoids defining the setter in the class namespace,
>
> Yes. That's mosly the point.
>
> > yet is more complicated
> > and obfuscated to boot ;)
>
> Well, that's your POV, so what can I say ? It's indeed a bit hackish,
> and requires a couple minutes of attention the first time you see it.
> And you just have to learn it once !-)
>
> Now I'd certainly prefer something like:
>
> class A(object):
> @propget
> def a(self):
>   return self._a
> @propset
> def a(self, val):
>   self._a = val
>
> But until there's something similar *builtin*, I'll stick to the @apply
> trick.

I like Guido's proposal for read/write properties.
http://mail.python.org/pipermail/python-dev/2007-November/075182.html

It works pretty well and is readable.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: a Python person's experience with Ruby

2007-12-09 Thread Steve Howell

--- MonkeeSage <[EMAIL PROTECTED]> wrote:

> On Dec 9, 6:23 pm, MonkeeSage <[EMAIL PROTECTED]>
> wrote:
> > Hi Bruno,
> >
> > I think that we've been having a mainly "semantic"
> (pun intended)
> > dispute. I think you're right, that we've been
> using the same words
> > with different meanings.
> >

I think Ruby and Python have lots of false cognates,
or faux amis.

> > 
> > But at the same time, I can see how my python
> example can be seen as
> > *wildly* different (WTF?) as well. Maybe there is
> no easy way to
> > provide a true formally equivalent translation due
> to the
> > implementation differences of the languages (or if
> Saphir-Whorf is
> > right, maybe we just can't think of it! ;)
> >

I think that there is an inherent difficulty in
translation here.  To give a metaphor, it's
impossible, or at least very difficult, to explain, in
French, how certain English phrases translate to
French, without your French sounding a little English,
or just downright wrong.  And vice versa.






  

Be a better friend, newshound, and 
know-it-all with Yahoo! Mobile.  Try it now.  
http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ 

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


Re: a Python person's experience with Ruby

2007-12-09 Thread MonkeeSage
On Dec 9, 6:23 pm, MonkeeSage <[EMAIL PROTECTED]> wrote:
> Hi Bruno,
>
> I think that we've been having a mainly "semantic" (pun intended)
> dispute. I think you're right, that we've been using the same words
> with different meanings.
>
> I would like to say firstly that I've been using python for a few
> years now (about three I think), and I think I have a basic grasp of
> the object system and so forth (e.g., I understood your example with
> the apply decorator and properties). I read the docs when I first
> started learning python (along with Fredrik Lundh's page about python
> objects and more recently "call by object"). But I also own up to my
> ignorance. I'm not a guru by any means. So you'll have to forgive me
> if my ignorance has gotten in the way. I'll definitely re-read the
> docs tonight.
>
> I would like to (try to) clarify a little about my use of wording. By
> "attribute" I was referring to a member of an object (*other than*
> toplevel). I was of course using "method" to refer to callable
> attributes (and I would use "function" for callable attributes bound
> to toplevel), and I was using "variable" to refer to non-callable
> attributes. By "tagging" I meant that attributes without a
> "tag" (e.g., __call__) are not included in the MRO for an object; they
> must be "tagged" as something other than a "variable".
>
> As for ruby, I think the opcodes will help me clarify...
>
> >> require 'parse_tree'
> => true
> >> ParseTree.translate(%q{
>
> class A
>   def foo
> "bar"
>   end
> end
> A.new.foo})
>
> => [:block, [:class, :A, nil, [:scope, [:defn, :foo, [:scope, [:block,
> [:args], [:str, "bar"]], [:call, [:call,
> [:const, :A], :new], :foo]]
>
> Notice that #new and #foo are both CALL ops. All attribute access is
> CALL (i.e., "method"). There really is no such thing as a non-callable
> "attribute" in ruby. Within the scope of a class (block, &c), there
> can be non-callable members of course (LVAL), but "foo" can mean
> either LVAL *or* FCALL, because there is no "tagging", it's just
> whatever is in context and/or parsed first as a given type of object
> (well there are a few other rules, but that's the main idea), with
> "()" is a hint to help the parser when the expression is ambiguous:
>
> a = 1
> def a; 2; end
> a   # [:lval :a] == a = 1
> a() # [:fcall :a] == def ...
>
> Given this, I see the addition the instance variable also being an
> attribute as a *huge* difference between the ruby code and your
> initial example. An attribute can be named the same as an lval and
> return or set the value of the lval (e.g., @a), but it's no different
> from any other method.
>
> class A
>   def initialize; @a = "blah"; end
>   attr_reader :a
>   def cheese; @a; end # exactly equivalent
> end
>
> But at the same time, I can see how my python example can be seen as
> *wildly* different (WTF?) as well. Maybe there is no easy way to
> provide a true formally equivalent translation due to the
> implementation differences of the languages (or if Saphir-Whorf is
> right, maybe we just can't think of it! ;)
>
> Anyhow, sorry for the confusion.
>
> Regards,
> Jordan

Ps. To answer a question you asked, "callable" objects don't generally
implement a #call method--just Proc objects and method references
[class Method instances] do, which even though they have a #call
method, aren't usually considered "callable" since you can't call them
directly--the #call method could as easily be named #run or #evaluate
or whatever. Accessing a name in ruby basically does something like:
VCALL name (== if parens on name like a() skip to call step, otherwise
check for LVAL in scope and return value if found, otherwise FCALL/
CALL and return result). You can use the #define_method method to
create a new "callable."

Regards,
Jordan
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: a Python person's experience with Ruby

2007-12-09 Thread MonkeeSage
Hi Bruno,

I think that we've been having a mainly "semantic" (pun intended)
dispute. I think you're right, that we've been using the same words
with different meanings.

I would like to say firstly that I've been using python for a few
years now (about three I think), and I think I have a basic grasp of
the object system and so forth (e.g., I understood your example with
the apply decorator and properties). I read the docs when I first
started learning python (along with Fredrik Lundh's page about python
objects and more recently "call by object"). But I also own up to my
ignorance. I'm not a guru by any means. So you'll have to forgive me
if my ignorance has gotten in the way. I'll definitely re-read the
docs tonight.

I would like to (try to) clarify a little about my use of wording. By
"attribute" I was referring to a member of an object (*other than*
toplevel). I was of course using "method" to refer to callable
attributes (and I would use "function" for callable attributes bound
to toplevel), and I was using "variable" to refer to non-callable
attributes. By "tagging" I meant that attributes without a
"tag" (e.g., __call__) are not included in the MRO for an object; they
must be "tagged" as something other than a "variable".

As for ruby, I think the opcodes will help me clarify...

>> require 'parse_tree'
=> true
>> ParseTree.translate(%q{
class A
  def foo
"bar"
  end
end
A.new.foo
})
=> [:block, [:class, :A, nil, [:scope, [:defn, :foo, [:scope, [:block,
[:args], [:str, "bar"]], [:call, [:call,
[:const, :A], :new], :foo]]

Notice that #new and #foo are both CALL ops. All attribute access is
CALL (i.e., "method"). There really is no such thing as a non-callable
"attribute" in ruby. Within the scope of a class (block, &c), there
can be non-callable members of course (LVAL), but "foo" can mean
either LVAL *or* FCALL, because there is no "tagging", it's just
whatever is in context and/or parsed first as a given type of object
(well there are a few other rules, but that's the main idea), with
"()" is a hint to help the parser when the expression is ambiguous:

a = 1
def a; 2; end
a   # [:lval :a] == a = 1
a() # [:fcall :a] == def ...

Given this, I see the addition the instance variable also being an
attribute as a *huge* difference between the ruby code and your
initial example. An attribute can be named the same as an lval and
return or set the value of the lval (e.g., @a), but it's no different
from any other method.

class A
  def initialize; @a = "blah"; end
  attr_reader :a
  def cheese; @a; end # exactly equivalent
end

But at the same time, I can see how my python example can be seen as
*wildly* different (WTF?) as well. Maybe there is no easy way to
provide a true formally equivalent translation due to the
implementation differences of the languages (or if Saphir-Whorf is
right, maybe we just can't think of it! ;)

Anyhow, sorry for the confusion.

Regards,
Jordan
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: a Python person's experience with Ruby

2007-12-09 Thread Steve Howell

--- Bruno Desthuilliers
<[EMAIL PROTECTED]> wrote:

> Steve Howell a écrit :
> (snip)
> > 
> > Jordan and others, thanks for all your posts; I am
> > learning a lot about both languages.
> > 
> > This is what I've gathered so far.
> > 
> > Python philosophy:
> >passing around references to methods should be
> > natural (i.e. my_binary_op = math.add)
> >calling methods should be explicit (use parens)
> >the use of setters/getters varies among Python
> > programmers; properties, decorators, special
> methods,
> > etc. can be used judiciously to affect the
> interface
> 
> You can forget decorators here - the examples in
> this thread were mostly 
> tricky ways to define properties. To be more
> general, the Python way to 
> implement transparent computed attributes is to hook
> into the lookup 
> mechanism, usually thru the descriptor protocol (the
> property class 
> being one possible implementation), but also using
> the __getattr__ / 
> __getattribute / __setattr__ hooks.
>

Ok, that makes sense.
 
> > Ruby philosophy:
> >a method itself should be callable without
> parens
> >you can get a reference to a chunk of code, but
> > then you need a little extra syntax, beyond just a
> > variable name and parens, to eventually call it
> > (yield, &, call, etc.)
> >when referring to methods, you can use :symbols
> to
> > name the method you're interested in without
> actually
> > calling it
> > 
> > My personal experience:
> > 
> (snip)
>  >
> >I was surprised in Ruby by how seldom I really
> pass
> > references to methods around,
> 
> This probably has to do with this nice feature named
> 'blocks' !-)
> 

Partly.  It's also due to the fact that my experience
so far in Ruby has mostly been writing code at the top
layer of a fairly vanilla Rails MVC app, whereas in
Python I've done a much wider variety of tasks.




  

Be a better friend, newshound, and 
know-it-all with Yahoo! Mobile.  Try it now.  
http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ 

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


Re: a Python person's experience with Ruby

2007-12-09 Thread Bruno Desthuilliers
Steve Howell a écrit :
(snip)
> 
> Jordan and others, thanks for all your posts; I am
> learning a lot about both languages.
> 
> This is what I've gathered so far.
> 
> Python philosophy:
>passing around references to methods should be
> natural (i.e. my_binary_op = math.add)
>calling methods should be explicit (use parens)
>the use of setters/getters varies among Python
> programmers; properties, decorators, special methods,
> etc. can be used judiciously to affect the interface

You can forget decorators here - the examples in this thread were mostly 
tricky ways to define properties. To be more general, the Python way to 
implement transparent computed attributes is to hook into the lookup 
mechanism, usually thru the descriptor protocol (the property class 
being one possible implementation), but also using the __getattr__ / 
__getattribute / __setattr__ hooks.

> Ruby philosophy:
>a method itself should be callable without parens
>you can get a reference to a chunk of code, but
> then you need a little extra syntax, beyond just a
> variable name and parens, to eventually call it
> (yield, &, call, etc.)
>when referring to methods, you can use :symbols to
> name the method you're interested in without actually
> calling it
> 
> My personal experience:
> 
(snip)
 >
>I was surprised in Ruby by how seldom I really pass
> references to methods around,

This probably has to do with this nice feature named 'blocks' !-)

> but it is definitely
> something I want to understand better.
> 
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: a Python person's experience with Ruby

2007-12-09 Thread Bruno Desthuilliers
MonkeeSage a écrit :
> On Dec 9, 1:58 pm, MonkeeSage <[EMAIL PROTECTED]> wrote:
> 
> 
>> Sure. But as I understand, every attribute in python is a value,
> 
> 
> sorry...*references* a value
> 
So make it: 'reference an object'
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: a Python person's experience with Ruby

2007-12-09 Thread Bruno Desthuilliers
MonkeeSage a écrit :
> On Dec 8, 4:54 pm, Bruno Desthuilliers
> <[EMAIL PROTECTED]> wrote:
> 
>>MonkeeSage a écrit :
>>
>>
>>
>>
>>>On Dec 8, 12:42 pm, Bruno Desthuilliers
>>><[EMAIL PROTECTED]> wrote:
>>
MonkeeSage a écrit :
>>
>On Dec 7, 11:08 pm, Steve Howell <[EMAIL PROTECTED]> wrote:
>>
(snip)
>>
>>4) Ruby forces you to explicitly make attributes for
>>instance variables.  At first I found this clumsy, but
>>I've gotten used to it, and I actually kind of like it
>>in certain circumstances.
>>
>4.) Yeah, it's hard when learning ruby, especially if coming from
>languages that distinguish between methods and attributes,
>>
which is not the case in Python
>>
>>>It is, I just wasn't absolutely precise (uh-oh, here comes the
>>>semantics police! -- don't pass GO, don't collect $200, go strait to
>>>jail!). Python *does* distinguish between instance/class vars and
>>>instance/class methods. But in ruby no such distinction exists.
>>>Accessing a "variable" in ruby == calling object.var. I.e., in ruby,
>>>when you say "blah.x" that translates to "blah.send(:x)", whether :x
>>>is a "variable" or a "method," since *everything* is a method. The
>>>call model of ruby is more like smalltalk.
>>
>>I'm sorry to have to insist: Python doesn't distinguish between methods
>>and attributes. Calling a method in Python is really 1/ looking up an
>>attribute then 2/ applying the call operator on what the lookup eval'd
>>to. As a matter of fact, you can stop at the first step, and you'll have
>>a reference to whatever the lookup mechanism yielded for the given
>>attribute name on the given object. FWIW, Python's functions are plain
>>objects, and when used as attributes are stored in the same place as any
>>other attribute.
> 
> 
> Except that pthon does differentiate, as python variables are not
> callable, 

I beg your pardon ?

Python 2.4.3 (#1, Mar 12 2007, 23:32:01)
[GCC 3.3.4 20040623 (Gentoo Linux 3.3.4-r1, ssp-3.3.2-2, pie-8.7.6)] on 
linux2
Type "help", "copyright", "credits" or "license" for more information.
 >>> class Toto(object):
... def test(self): print self
... def __call__(self): print self
...
 >>> def boo(): print "boo"
...
 >>> Toto

 >>> # Toto is a variable. Is it callable ?
...
 >>> callable(Toto)
True
 >>> Toto()
<__main__.Toto object at 0x4033492c>
 >>> t = Toto()
 >>> t
<__main__.Toto object at 0x403344cc>
 >>> # t is a variable. Is it callable ?
... callable(t)
True
 >>> t()
<__main__.Toto object at 0x403344cc>
 >>> t.test
>
 >>> # t.test is a variable. is it callable ?
... callable(t.test)
True
 >>> t.test()
<__main__.Toto object at 0x403344cc>
 >>> t.foo
Traceback (most recent call last):
   File "", line 1, in ?
AttributeError: 'Toto' object has no attribute 'foo'
 >>> t.foo = boo
 >>> t.foo

 >>> # t.foo is a variable. Is it callable ?
... callable(t.foo)
True
 >>> t.foo()
boo
 >>>

> whereas everything in ruby is callable. blah.a in ruby means
> blah.send(:a). 

Ok, I see where the problem is. We definitively don't have the same 
definition of 'callable'. In Python, a callable is an object that can be 
called - that is, you can apply the call operator to it. You'd better 
get use to this definition when talking about Python, FWIW !-)

What you say is that in Ruby, you're *always* going thru a method call 
when accessing an attribute (from outside at least). The fact is that 
Ruby is built on 'true' (ie: à la Smalltalk) message passing, when 
Python is built on the attribute lookup operator and the call operator. 
As I said, while Python and Ruby have similarities, they are built on 
totally disjoint object models - different ways to get at the same thing...

> Which is why you need an accessor to get at instance
> variables, since as variables they exist in the scope scope of the
> class, but they are not callable so they are not attributes of the
> instance.

I would certainly not define it that way, but anyway...


>to get used
>to thinking of "a.a" and "a.a=" as method calls and defining accessors
>for those methods  (or using one of the attr_* keywords) in the class
>body.
>>
Python has an equivalent support for computed attributes, using property
or a custom descriptors. While it's a bit lower-level than Ruby, it's
still quite easy to use and IMHO a bit more powerful.
>>
>The equivalent python idiom is something like:
>>
>class A:
> __a = "foo"
> def __init__(self):
>   self.a = A.__a
>>
WTF ???
>>
>Which roughly translates to this in ruby:
>>
>class A
> attr_accessor :a
> def initialize
>   @a = "foo"
> end
>end
>>
The Python translation of the above Ruby snippet is actually way more
simple:
>>
class A(object):
  def __init__(self):
self.a = "foo"
>>
>>>Not really.
>>
>>Yes, really. Sorry to have to insist, but...
>>
>>
>>>In ruby an ivar is accessible within the class *only*, but
>>>not from without (like a mangled python class var), un

Re: a Python person's experience with Ruby

2007-12-09 Thread MonkeeSage
On Dec 9, 3:10 pm, I V <[EMAIL PROTECTED]> wrote:
> On Sun, 09 Dec 2007 11:58:05 -0800, MonkeeSage wrote:
> > class A
> >   attr_accessor :a # == self.a,
> ># accessible to instances of A
> >   def initialize
> > @a = "foo" # A.__a
> ># only accessible from class scope of A
> >   end
> > end
>
> > Once again, there is no such thing as an attribute that is not a method
> > in ruby, and there is no such thing as setting an *attribute* ("=" is a
> > method also). You're trying to *re-implement* rubys mechanism in python
> > in your example, but in pythons mechanism, all attributes already have
> > built-in getter/setter. So the correct analogy is a variable that is
> > accessible from within the classes scope only (A.__a), and then exposed
> > to instances through an attribute (self.a). Your example leaves out a
> > variable accessible only from within the scope of the class, and adds a
> > new attribute accessible from the instance (_a).
>
> Either I'm not understanding you, or you're not understanding what A.__a
> means in python. A.__a is a class attribute, not an instance attribute -
> it's equivalent to @@a in ruby, not @a.

I said previously that A.__a is a class variable. Since I was only
using it to show that @a is not exposed as an attribute, I just used
A.__a, but you're right, it would have been better to use self.__a.

> If I understand what you're
> saying, a better python example to make your point might be:
>
> class A(object):
> def __init__(self):
> self.__a = "foo" # equivalent to @a
> self.a = self.__a # exposes self.__a

Thanks.

> Except that this only allows you to access '__a' via the exposed
> attribute 'a', not bind it to a new object. If you do:
>
> inst = A()
> inst.a = "bar"
>
> you don't modify inst.__a, unlike the following ruby code, which does
> modify @a .
>
> inst = A.new
> inst.a = "bar"

I understand. That's why I said it was a rough translation of the ruby
code. I was only trying to say that it's strange when learning ruby,
to get your head around the idea that instance (and class) variables
are not attributes; that all attributes are callable. The example was
merely to demonstrate the distinction between instance method and
instance variable in ruby. The python isn't supposed to have the exact
same behavior, just a similar semantic.

Regards,
Jordan
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: a Python person's experience with Ruby

2007-12-09 Thread I V
On Sun, 09 Dec 2007 11:58:05 -0800, MonkeeSage wrote:
> class A
>   attr_accessor :a # == self.a,
># accessible to instances of A
>   def initialize
> @a = "foo" # A.__a
># only accessible from class scope of A
>   end
> end
> 
> Once again, there is no such thing as an attribute that is not a method
> in ruby, and there is no such thing as setting an *attribute* ("=" is a
> method also). You're trying to *re-implement* rubys mechanism in python
> in your example, but in pythons mechanism, all attributes already have
> built-in getter/setter. So the correct analogy is a variable that is
> accessible from within the classes scope only (A.__a), and then exposed
> to instances through an attribute (self.a). Your example leaves out a
> variable accessible only from within the scope of the class, and adds a
> new attribute accessible from the instance (_a).

Either I'm not understanding you, or you're not understanding what A.__a 
means in python. A.__a is a class attribute, not an instance attribute - 
it's equivalent to @@a in ruby, not @a. If I understand what you're 
saying, a better python example to make your point might be:

class A(object):
def __init__(self):
self.__a = "foo" # equivalent to @a
self.a = self.__a # exposes self.__a

Except that this only allows you to access '__a' via the exposed 
attribute 'a', not bind it to a new object. If you do:

inst = A()
inst.a = "bar"

you don't modify inst.__a, unlike the following ruby code, which does 
modify @a .

inst = A.new
inst.a = "bar"
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: a Python person's experience with Ruby

2007-12-09 Thread Steve Howell

--- MonkeeSage <[EMAIL PROTECTED]> wrote:
> 
> Not just callable, but interchangeable. My point was
> that in ruby, if
> you use a block or a lambda as a HOF, you have to
> use #call / #[] /
> yield keyword on it to call it.
> 
> def foo(a)
>   puts a
> end
> bar = lambda { | a | puts a }
> 
> # these do the same thing
> [1,2,3].each(&bar)
> [1,2,3].each(&method(:foo))
> 
> That's not to say it's better than python (like I
> said, I personally I
> like pythons referencing / calling convention a
> little better), it's
> just that since Proc objects already have that call
> syntax in ruby,
> making method references use it also allows them to
> be interchanged (w/
> o having to do method(:foo).to_proc).
> 

Jordan and others, thanks for all your posts; I am
learning a lot about both languages.

This is what I've gathered so far.

Python philosophy:
   passing around references to methods should be
natural (i.e. my_binary_op = math.add)
   calling methods should be explicit (use parens)
   the use of setters/getters varies among Python
programmers; properties, decorators, special methods,
etc. can be used judiciously to affect the interface
   
Ruby philosophy:
   a method itself should be callable without parens
   you can get a reference to a chunk of code, but
then you need a little extra syntax, beyond just a
variable name and parens, to eventually call it
(yield, &, call, etc.)
   when referring to methods, you can use :symbols to
name the method you're interested in without actually
calling it

My personal experience:

   Even after doing lots of Python, I occasionally got
bitten by the pitfall of omitting the parens when I
meant to call something, but it was never major pain.
(I never made the opposite mistake, in case you're
wondering.)

   Despite the pitfall above, I always liked the
tradeoff that Python gave me more natural syntax for
passing around methods.  (And, more fundamentally, I
like the Python notion of binding "general" things to
a  name.)

   As somebody just starting to use Ruby, I actually
like omitting parens in method calls, which I view as
the more common case.  I admit some cost here, though,
in simple churn of the code due to the fact that some
people like having parens for aesthetic reasons.

   I was surprised in Ruby by how seldom I really pass
references to methods around, but it is definitely
something I want to understand better.

I hope this adds a little perspective, and please feel
free to correct me in cases where I'm either imprecise
or just flat out wrong.



  

Never miss a thing.  Make Yahoo your home page. 
http://www.yahoo.com/r/hs
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: a Python person's experience with Ruby

2007-12-09 Thread MonkeeSage
On Dec 9, 1:58 pm, MonkeeSage <[EMAIL PROTECTED]> wrote:

>  Sure. But as I understand, every attribute in python is a value,

sorry...*references* a value

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


Re: a Python person's experience with Ruby

2007-12-09 Thread MonkeeSage
On Dec 8, 4:54 pm, Bruno Desthuilliers
<[EMAIL PROTECTED]> wrote:
> MonkeeSage a écrit :
>
>
>
> > On Dec 8, 12:42 pm, Bruno Desthuilliers
> > <[EMAIL PROTECTED]> wrote:
>
> >>MonkeeSage a écrit :
>
> >>>On Dec 7, 11:08 pm, Steve Howell <[EMAIL PROTECTED]> wrote:
>
> >>(snip)
>
>  4) Ruby forces you to explicitly make attributes for
> instance variables.  At first I found this clumsy, but
> I've gotten used to it, and I actually kind of like it
> in certain circumstances.
>
> >>>4.) Yeah, it's hard when learning ruby, especially if coming from
> >>>languages that distinguish between methods and attributes,
>
> >>which is not the case in Python
>
> > It is, I just wasn't absolutely precise (uh-oh, here comes the
> > semantics police! -- don't pass GO, don't collect $200, go strait to
> > jail!). Python *does* distinguish between instance/class vars and
> > instance/class methods. But in ruby no such distinction exists.
> > Accessing a "variable" in ruby == calling object.var. I.e., in ruby,
> > when you say "blah.x" that translates to "blah.send(:x)", whether :x
> > is a "variable" or a "method," since *everything* is a method. The
> > call model of ruby is more like smalltalk.
>
> I'm sorry to have to insist: Python doesn't distinguish between methods
> and attributes. Calling a method in Python is really 1/ looking up an
> attribute then 2/ applying the call operator on what the lookup eval'd
> to. As a matter of fact, you can stop at the first step, and you'll have
> a reference to whatever the lookup mechanism yielded for the given
> attribute name on the given object. FWIW, Python's functions are plain
> objects, and when used as attributes are stored in the same place as any
> other attribute.

Except that pthon does differentiate, as python variables are not
callable, whereas everything in ruby is callable. blah.a in ruby means
blah.send(:a). Which is why you need an accessor to get at instance
variables, since as variables they exist in the scope scope of the
class, but they are not callable so they are not attributes of the
instance.

> >>>to get used
> >>>to thinking of "a.a" and "a.a=" as method calls and defining accessors
> >>>for those methods  (or using one of the attr_* keywords) in the class
> >>>body.
>
> >>Python has an equivalent support for computed attributes, using property
> >>or a custom descriptors. While it's a bit lower-level than Ruby, it's
> >>still quite easy to use and IMHO a bit more powerful.
>
> >>>The equivalent python idiom is something like:
>
> >>>class A:
> >>>  __a = "foo"
> >>>  def __init__(self):
> >>>self.a = A.__a
>
> >>WTF ???
>
> >>>Which roughly translates to this in ruby:
>
> >>>class A
> >>>  attr_accessor :a
> >>>  def initialize
> >>>@a = "foo"
> >>>  end
> >>>end
>
> >>The Python translation of the above Ruby snippet is actually way more
> >>simple:
>
> >>class A(object):
> >>   def __init__(self):
> >> self.a = "foo"
>
> > Not really.
>
> Yes, really. Sorry to have to insist, but...
>
> > In ruby an ivar is accessible within the class *only*, but
> > not from without (like a mangled python class var), unless you declare
> > an accessor (or write the accessor methods yourself).
>
> Your Ruby snippets uses attr_accessor, which gives direct, uncontrolled
> read/write access to the attribute. So I maintain that the *exact*
> semantic equivalent in Python of your Ruby snippet is a plain attribute.
>
> > So my example is
> > closer, and is not a WTF, if you know how ruby works.
>
> I know enough about Ruby to understand this snippet, and enough about
> Python to tell your Python example is a WTF.
>
> FWIW, your Python snippet ends up doing the same thing as mine - that
> is, it defines a plain instance attribute named 'a' - but uses a
> reference to class attribute instead of a string literal as the initial
> value of the instance attribute. Since Python strings are immutable, the
> final result is the same wrt/ the instance attribute - it's just overly
> complicated, hence the WTF label.
>
> OTHO, your Python code also defines a class attribute which doesn't
> exist in the Ruby snippet. Mine doesn't imply any class attribute. So my
> Python translation is way closer to the Ruby original !-)
>
> If you what you had in mind was an example of a computed attribute,
> here's the correct code:
>
> class A(object):
>@apply
>def a():
>  def fget(self):
>return self._a
>  def fset(self, val):
>self._a = val
>  return property(**locals())
>def __init__(self):
>  self.a = "foo"
>
> Now since we're just getting/setting the attribute, all these
> indirection levels are totally useless, so in such a case we just use a
> plain attribute. So my first exemple (plain attribute) is effectively
> the *exact* semantic equivalent of your Ruby snippet. CQFD.

No, it's not at all.

class A
  attr_accessor :a # == self.a,
   # accessible to instances of A
  def initialize
@a = "foo" # A.__a
 

Re: a Python person's experience with Ruby

2007-12-09 Thread Bruno Desthuilliers
Lou Pecora a écrit :
> In article <[EMAIL PROTECTED]>,
>  Bruno Desthuilliers <[EMAIL PROTECTED]> wrote:
> 
> 
>>>Thus: close;
>>>could replace close();

*Please* give proper attribution. I'd *never* suggest such a thing.

> 
> Wouldn't this give an ambiguity?  
> 
> afcn=close   # make an "alias" to the close function
> val=close()  # set val to the return value of the close function
> 

The point of Colin (who was the one making this suggestion) was that 
parens could be omitted if there was no LHS.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: a Python person's experience with Ruby

2007-12-09 Thread Steve Howell
After starting this discussion thread, I found the
link below:

http://www.b-list.org/weblog/2006/jun/18/lets-talk-about-python-and-ruby/

If you're like me--struggling to learn Ruby while
having Python as your primary point of reference--you
might find some of the points informative.  I suspect
vice versa as well.





  

Be a better friend, newshound, and 
know-it-all with Yahoo! Mobile.  Try it now.  
http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ 

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


Re: a Python person's experience with Ruby

2007-12-09 Thread Lou Pecora
In article <[EMAIL PROTECTED]>,
 Bruno Desthuilliers <[EMAIL PROTECTED]> wrote:

> > Thus: close;
> > could replace close();

Wouldn't this give an ambiguity?  

afcn=close   # make an "alias" to the close function
val=close()  # set val to the return value of the close function

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


Re: a Python person's experience with Ruby

2007-12-09 Thread Arnaud Delobelle
On Dec 9, 12:15 am, Bruno Desthuilliers
<[EMAIL PROTECTED]> wrote:
> Richard Jones a écrit :
>
>
>
> > Bruno Desthuilliers wrote:
>
> >>class A(object):
> >>   @apply
> >>   def a():
> >> def fget(self):
> >>   return self._a
> >> def fset(self, val):
> >>   self._a = val
> >> return property(**locals())
> >>   def __init__(self):
> >> self.a = "foo"
>
> > That property setup seems overly complicated. As far as I can see, it only
> > avoids defining the setter in the class namespace,
>
> Yes. That's mosly the point.
>
> > yet is more complicated
> > and obfuscated to boot ;)
>
> Well, that's your POV, so what can I say ? It's indeed a bit hackish,
> and requires a couple minutes of attention the first time you see it.
> And you just have to learn it once !-)

Perhaps 'return property(fget, fset)' would be easier to make sense of
than **locals()

> Now I'd certainly prefer something like:
>
> class A(object):
> @propget
> def a(self):
>   return self._a
> @propset
> def a(self, val):
>   self._a = val
>
> But until there's something similar *builtin*, I'll stick to the @apply
> trick.

At first sight, I like the look of this. Obviously I can't provide a
builtin implementation, but there's an easy way to achieve this.  It
uses sys._getframe but there is no need to fiddle with metaclasses:

from sys import _getframe

def _makeprop(frame, name, **d):
p = frame.f_locals.get(name, None)
args = {}
if isinstance(p, property):
args = dict(fget=p.fget, fset=p.fset, fdel=p.fdel,
doc=p.__doc__)
args.update(d)
return property(**args)

def propget(f):
return _makeprop(_getframe(1), f.__name__, fget=f)

def propset(f):
return _makeprop(_getframe(1), f.__name__, fset=f)

def propdel(f):
return _makeprop(_getframe(1), f.__name__, fdel=f)

if __name__ == '__main__':
class Foo(object):
a = property(doc="mod10 attribute")
@propget
def a(self):
return self._a
@propset
def a(self, a):
self._a = a % 10
@propdel
def a(self):
del self._a

f = Foo()
f.a = 42
assert f.a == 42 % 10
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: a Python person's experience with Ruby

2007-12-08 Thread Kay Schluehr
On Dec 8, 8:56 pm, Steve Howell <[EMAIL PROTECTED]> wrote:
> --- Bruno Desthuilliers
>
> <[EMAIL PROTECTED]> wrote:
> > Colin J. Williams a écrit :
> > > I'm not sure that I like add 3, 5, 7
>
> > > but it would be nice to be able to drop the
> > parentheses
> > > when no argument is required.
>
> > > Thus: close;
> > > could replace close();
>
> > This just could not work given Python's object
> > model. The parens
> > actually *are* the call operator.
>
> I mostly agree with you, but in the specific use case
> of having just a single token on a line, you could
> argue that Python could DWIM on calling an object if
> the object is callable, since otherwise it's just a
> no-op.

Argh! I smell context sensitive semantics which is the road to
language design hell. Fortunately this hell is already occupied by
Perl and Larry Wall is a charming and funky guy. You know what look
for.

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


Re: a Python person's experience with Ruby

2007-12-08 Thread Bruno Desthuilliers
Richard Jones a écrit :
> Bruno Desthuilliers wrote:
> 
>>class A(object):
>>   @apply
>>   def a():
>> def fget(self):
>>   return self._a
>> def fset(self, val):
>>   self._a = val
>> return property(**locals())
>>   def __init__(self):
>> self.a = "foo"
> 
> 
> That property setup seems overly complicated. As far as I can see, it only
> avoids defining the setter in the class namespace,

Yes. That's mosly the point.

> yet is more complicated
> and obfuscated to boot ;)

Well, that's your POV, so what can I say ? It's indeed a bit hackish, 
and requires a couple minutes of attention the first time you see it. 
And you just have to learn it once !-)

Now I'd certainly prefer something like:

class A(object):
@propget
def a(self):
  return self._a
@propset
def a(self, val):
  self._a = val

But until there's something similar *builtin*, I'll stick to the @apply 
trick.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: a Python person's experience with Ruby

2007-12-08 Thread Steve Howell

--- Richard Jones <[EMAIL PROTECTED]>
wrote:
> 
> class A(object):
> def set_a(self, value):
> self._a = value
> a = property(lambda self: self._a, set_a)
> 
> Note that this differs from a regular attribute
> because "a" is not deletable
> from instances (the property defines no deleter).
> 

The use case I was actually considering actually
doesn't require much magic in either language.

I commonly want to write code like this:

   e = Employee('jim', 'accounting', 50)
   print e.name
   print e.department
   print e.salary
   e.update_salary(percent=.10)
   e.update_salary(percent=.5)

I want the name, department, and salary always exposed
to me.  But suppose in Employee's innards, it keeps a
cache of the number of raises Jim has been given, and
this cache is very implementation-sensitive.

The way I achieve this is different in each language:

  1) In Python I get name, department, and salary
exposed for free, but I need to make a more conscious
decision to hide e.compensation_tracker, which I do by
renaming it to e.__compensation_tracker.

  2) In Ruby I get compensation_tracker fully
hidden/encapsulated for free, but I have to make a
more conscious decision to expose name, department,
and salary, which I get by saying:

   attr_reader :name, :department, :salary

Obviously, things can get a lot more complicated than
this scenario, and I think both languages are pretty
flexible, but flexible in a different way.










  

Be a better friend, newshound, and 
know-it-all with Yahoo! Mobile.  Try it now.  
http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ 

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


Re: a Python person's experience with Ruby

2007-12-08 Thread Steve Howell

--- Bruno Desthuilliers > 
> > Another aspect of Ruby is that the final
> expression
> > evaluated in a method actually gets returned as
> the
> > result of a method,
> 
> Unless there's an explict return before...
> 
> > which has further implications on
> > whether "close" is simply evaluated or called.
> 
> I'm sorry but I'm not sure I get the point here.

I'm just giving another example that the following
seemingly innocuous line of code has lots of side
effects in both languages, but the two languages
differ:

transaction.finish # last line in method

1) Some one new to Python might be surprised that
finish never gets invoked.

2) Some new to Ruby might be surprised that the
command above might actually cause the enclosing
method to return a non-nil value.

For this code:

   return table.get_apples # last line of get_getter()

1) Some one new to Python might be surprised to see
this code when get_apples is not explicitly written in
MyTable.

2) Some one new to Ruby might be surprised that
get_getter()() does not work as expected. 





  

Never miss a thing.  Make Yahoo your home page. 
http://www.yahoo.com/r/hs
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: a Python person's experience with Ruby

2007-12-08 Thread Richard Jones
Bruno Desthuilliers wrote:
> class A(object):
>@apply
>def a():
>  def fget(self):
>return self._a
>  def fset(self, val):
>self._a = val
>  return property(**locals())
>def __init__(self):
>  self.a = "foo"

That property setup seems overly complicated. As far as I can see, it only
avoids defining the setter in the class namespace, yet is more complicated
and obfuscated to boot ;)

class A(object):
def set_a(self, value):
self._a = value
a = property(lambda self: self._a, set_a)

Note that this differs from a regular attribute because "a" is not deletable
from instances (the property defines no deleter).


 Richard

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


Re: a Python person's experience with Ruby

2007-12-08 Thread Bruno Desthuilliers
Steve Howell a écrit :
> --- Bruno Desthuilliers
> <[EMAIL PROTECTED]> wrote:
> 
> 
>>Colin J. Williams a écrit :
>>
>>>I'm not sure that I like add 3, 5, 7
>>>
>>>but it would be nice to be able to drop the
>>
>>parentheses
>>
>>>when no argument is required.
>>>
>>>Thus: close;
>>>could replace close();
>>
>>This just could not work given Python's object
>>model. The parens 
>>actually *are* the call operator.
>>
> 
> 
> I mostly agree with you, but in the specific use case
> of having just a single token on a line, you could
> argue that Python could DWIM on calling an object if
> the object is callable, since otherwise it's just a
> no-op. 

It's not. If the name is not defined, it raises an exception (either a 
NameError or an AttributeError). And if the name resolves to a computed 
attribute, the getter for this computed attribute will be invoked - with 
possible side effects.

> I think the argument against doing that is
> more based on explicit-vs.-implicit principle versus
> actual constraints of the object model.

I'd say that the object model being the work of a strong proponent of 
the explicit-vs.-implicit principle, it's probably another 
chicken-and-egg problem - so we are both right here !-)

> Another aspect of Ruby is that the final expression
> evaluated in a method actually gets returned as the
> result of a method,

Unless there's an explict return before...

> which has further implications on
> whether "close" is simply evaluated or called.

I'm sorry but I'm not sure I get the point here.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: a Python person's experience with Ruby

2007-12-08 Thread Bruno Desthuilliers
MonkeeSage a écrit :
> On Dec 8, 12:42 pm, Bruno Desthuilliers
> <[EMAIL PROTECTED]> wrote:
> 
>>MonkeeSage a écrit :
>>
>>
>>>On Dec 7, 11:08 pm, Steve Howell <[EMAIL PROTECTED]> wrote:
>>
>>(snip)
>>
 4) Ruby forces you to explicitly make attributes for
instance variables.  At first I found this clumsy, but
I've gotten used to it, and I actually kind of like it
in certain circumstances.
>>>
>>>4.) Yeah, it's hard when learning ruby, especially if coming from
>>>languages that distinguish between methods and attributes,
>>
>>which is not the case in Python
> 
> 
> It is, I just wasn't absolutely precise (uh-oh, here comes the
> semantics police! -- don't pass GO, don't collect $200, go strait to
> jail!). Python *does* distinguish between instance/class vars and
> instance/class methods. But in ruby no such distinction exists.
> Accessing a "variable" in ruby == calling object.var. I.e., in ruby,
> when you say "blah.x" that translates to "blah.send(:x)", whether :x
> is a "variable" or a "method," since *everything* is a method. The
> call model of ruby is more like smalltalk.

I'm sorry to have to insist: Python doesn't distinguish between methods 
and attributes. Calling a method in Python is really 1/ looking up an 
attribute then 2/ applying the call operator on what the lookup eval'd 
to. As a matter of fact, you can stop at the first step, and you'll have 
a reference to whatever the lookup mechanism yielded for the given 
attribute name on the given object. FWIW, Python's functions are plain 
objects, and when used as attributes are stored in the same place as any 
other attribute.

> 
>>>to get used
>>>to thinking of "a.a" and "a.a=" as method calls and defining accessors
>>>for those methods  (or using one of the attr_* keywords) in the class
>>>body.
>>
>>Python has an equivalent support for computed attributes, using property
>>or a custom descriptors. While it's a bit lower-level than Ruby, it's
>>still quite easy to use and IMHO a bit more powerful.
>>
>>
>>>The equivalent python idiom is something like:
>>
>>>class A:
>>>  __a = "foo"
>>>  def __init__(self):
>>>self.a = A.__a
>>
>>WTF ???
>>
>>
>>>Which roughly translates to this in ruby:
>>
>>>class A
>>>  attr_accessor :a
>>>  def initialize
>>>@a = "foo"
>>>  end
>>>end
>>
>>The Python translation of the above Ruby snippet is actually way more
>>simple:
>>
>>class A(object):
>>   def __init__(self):
>> self.a = "foo"
>>
>  
> Not really. 

Yes, really. Sorry to have to insist, but...

> In ruby an ivar is accessible within the class *only*, but
> not from without (like a mangled python class var), unless you declare
> an accessor (or write the accessor methods yourself).

Your Ruby snippets uses attr_accessor, which gives direct, uncontrolled 
read/write access to the attribute. So I maintain that the *exact* 
semantic equivalent in Python of your Ruby snippet is a plain attribute.

> So my example is
> closer, and is not a WTF, if you know how ruby works.

I know enough about Ruby to understand this snippet, and enough about 
Python to tell your Python example is a WTF.

FWIW, your Python snippet ends up doing the same thing as mine - that 
is, it defines a plain instance attribute named 'a' - but uses a 
reference to class attribute instead of a string literal as the initial 
value of the instance attribute. Since Python strings are immutable, the 
final result is the same wrt/ the instance attribute - it's just overly 
complicated, hence the WTF label.

OTHO, your Python code also defines a class attribute which doesn't 
exist in the Ruby snippet. Mine doesn't imply any class attribute. So my 
Python translation is way closer to the Ruby original !-)

If you what you had in mind was an example of a computed attribute, 
here's the correct code:

class A(object):
   @apply
   def a():
 def fget(self):
   return self._a
 def fset(self, val):
   self._a = val
 return property(**locals())
   def __init__(self):
 self.a = "foo"

Now since we're just getting/setting the attribute, all these 
indirection levels are totally useless, so in such a case we just use a 
plain attribute. So my first exemple (plain attribute) is effectively 
the *exact* semantic equivalent of your Ruby snippet. CQFD.


>>>1.) I also found python's style of method referencing to be a lot more
>>>intuitive than using something like ruby's "m = method('foo');
>>>m.call('bar')" to get a reference to foo() and call it. It's alot
>>>cleaner to say "m = foo; m('bar')", imo. But this goes back to the
>>>omitting parens thing, which makes it impossible to do it that way in
>>>ruby.
>>
>>Yeps. This is where the real and fundamental difference between Ruby and
>>Python becomes evident. Both have support for transparent computed
>>attributes, but the way it's implemented is totally different - in Ruby,
>>by not having a call operator at all (I mean, the parens), in Python by
>>having both an explicit call operator and an expli

Re: a Python person's experience with Ruby

2007-12-08 Thread I V
On Sat, 08 Dec 2007 11:23:57 -0800, MonkeeSage wrote:
>> > The equivalent python idiom is something like:
>>
>> > class A:
>> >   __a = "foo"
>> >   def __init__(self):
>> > self.a = A.__a
[...]
>> > Which roughly translates to this in ruby:
>>
>> > class A
>> >   attr_accessor :a
>> >   def initialize
>> > @a = "foo"
>> >   end
>> > end
[...]
> Not really. In ruby an ivar is accessible within the class *only*, but
> not from without (like a mangled python class var), unless you declare
> an accessor (or write the accessor methods yourself). So my example is
> closer, and is not a WTF, if you know how ruby works.

In your python example, the class attribute is mangled, but the instance 
attribute isn't, whereas your ruby code has no class attribute, and an 
instance attribute that isn't (directly) accessible outside the class. 
The equivalent in python would involve a mangled instance attribute,  
like:

class A(object):
def __init__(self):
self.__a = "foo"
def get_a(self):
return self.__a
def set_a(self, val):
self.__a = val
a = property(get_a, set_a)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: a Python person's experience with Ruby

2007-12-08 Thread Steve Howell
--- Bruno Desthuilliers
<[EMAIL PROTECTED]> wrote:

> Colin J. Williams a écrit :
> > I'm not sure that I like add 3, 5, 7
> > 
> > but it would be nice to be able to drop the
> parentheses
> > when no argument is required.
> > 
> > Thus: close;
> > could replace close();
> 
> This just could not work given Python's object
> model. The parens 
> actually *are* the call operator.
> 

I mostly agree with you, but in the specific use case
of having just a single token on a line, you could
argue that Python could DWIM on calling an object if
the object is callable, since otherwise it's just a
no-op.  I think the argument against doing that is
more based on explicit-vs.-implicit principle versus
actual constraints of the object model.

Another aspect of Ruby is that the final expression
evaluated in a method actually gets returned as the
result of a method, which has further implications on
whether "close" is simply evaluated or called.




  

Never miss a thing.  Make Yahoo your home page. 
http://www.yahoo.com/r/hs
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: a Python person's experience with Ruby

2007-12-08 Thread MonkeeSage
On Dec 8, 12:42 pm, Bruno Desthuilliers
<[EMAIL PROTECTED]> wrote:
> MonkeeSage a écrit :
>
> > On Dec 7, 11:08 pm, Steve Howell <[EMAIL PROTECTED]> wrote:
>
> (snip)
> >>  4) Ruby forces you to explicitly make attributes for
> >> instance variables.  At first I found this clumsy, but
> >> I've gotten used to it, and I actually kind of like it
> >> in certain circumstances.
> > 4.) Yeah, it's hard when learning ruby, especially if coming from
> > languages that distinguish between methods and attributes,
>
> which is not the case in Python

It is, I just wasn't absolutely precise (uh-oh, here comes the
semantics police! -- don't pass GO, don't collect $200, go strait to
jail!). Python *does* distinguish between instance/class vars and
instance/class methods. But in ruby no such distinction exists.
Accessing a "variable" in ruby == calling object.var. I.e., in ruby,
when you say "blah.x" that translates to "blah.send(:x)", whether :x
is a "variable" or a "method," since *everything* is a method. The
call model of ruby is more like smalltalk.

> > to get used
> > to thinking of "a.a" and "a.a=" as method calls and defining accessors
> > for those methods  (or using one of the attr_* keywords) in the class
> > body.
>
> Python has an equivalent support for computed attributes, using property
> or a custom descriptors. While it's a bit lower-level than Ruby, it's
> still quite easy to use and IMHO a bit more powerful.
>
> > The equivalent python idiom is something like:
>
> > class A:
> >   __a = "foo"
> >   def __init__(self):
> > self.a = A.__a
>
> WTF ???
>
> > Which roughly translates to this in ruby:
>
> > class A
> >   attr_accessor :a
> >   def initialize
> > @a = "foo"
> >   end
> > end
>
> The Python translation of the above Ruby snippet is actually way more
> simple:
>
> class A(object):
>def __init__(self):
>  self.a = "foo"
>
> > Python:

Not really. In ruby an ivar is accessible within the class *only*, but
not from without (like a mangled python class var), unless you declare
an accessor (or write the accessor methods yourself). So my example is
closer, and is not a WTF, if you know how ruby works.

> > 1.) I also found python's style of method referencing to be a lot more
> > intuitive than using something like ruby's "m = method('foo');
> > m.call('bar')" to get a reference to foo() and call it. It's alot
> > cleaner to say "m = foo; m('bar')", imo. But this goes back to the
> > omitting parens thing, which makes it impossible to do it that way in
> > ruby.
>
> Yeps. This is where the real and fundamental difference between Ruby and
> Python becomes evident. Both have support for transparent computed
> attributes, but the way it's implemented is totally different - in Ruby,
> by not having a call operator at all (I mean, the parens), in Python by
> having both an explicit call operator and an explicit protocol for
> computed attributes (the descriptor protocol). Not to say one is better
> than the other, but that while both languages have similar features
> (and, at first look, similar syntaxes), they really have totally
> different object models.

Yes and no. I'll leave it at that. If you want to know more, do your
homework. :P

> > Though, ruby does allow some interesting things by having it
> > that way, e.g., letting you substitute a Proc object (e.g., a block or
> > lambda) for a method reference transparently.
>
> Care to give an example ? I don't have enough working experience with
> Ruby to be sure I understand what you mean here.

For example, any place expecting a foo (method reference), can be
exchanged with a { "bar" } block or a lambda { "baz" }.

> > 2.) I also find layout to be a nice feature. And since I've recently
> > been using Haskell, it has only re-inforced that opinion. But when I
> > first started using python, I got bitten by IndentationError quite
> > often. And I kept wanting to type some closing symbol, heh. ;)
>
> The nice thing with Python is that it lets you use the closing symbol
> you want, as long as you prefix it with a '#' !-)

LOL. Well, yes, I used to do that, but I got over that irrational
urge. ;)

Regards,
Jordan
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: a Python person's experience with Ruby

2007-12-08 Thread Bruno Desthuilliers
Colin J. Williams a écrit :
> Steve Howell wrote:>
> Thanks for the interesting comparison.
> 
> [snip]
> 
>>   3) I actually like being able to omit parentheses in
>> method definitions and method calls.  In Ruby you can
>> express "add(3,5,7)" as both "add(3,5,7)" and "add 3,
>> 5, 7."  The latter syntax is obviously more error
>> prone, but I don't think I've ever actually gotten bit
>> by it, and the code appears more clean to me.
>>
> [snip]
> 
> I'm not sure that I like add 3, 5, 7
> 
> but it would be nice to be able to drop the parentheses
> when no argument is required.
> 
> Thus: close;
> could replace close();

This just could not work given Python's object model. The parens 
actually *are* the call operator.

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


Re: a Python person's experience with Ruby

2007-12-08 Thread Bruno Desthuilliers
MonkeeSage a écrit :
> On Dec 7, 11:08 pm, Steve Howell <[EMAIL PROTECTED]> wrote:
> 
(snip)
>>  4) Ruby forces you to explicitly make attributes for
>> instance variables.  At first I found this clumsy, but
>> I've gotten used to it, and I actually kind of like it
>> in certain circumstances.

> 4.) Yeah, it's hard when learning ruby, especially if coming from
> languages that distinguish between methods and attributes,

which is not the case in Python

> to get used
> to thinking of "a.a" and "a.a=" as method calls and defining accessors
> for those methods  (or using one of the attr_* keywords) in the class
> body. 

Python has an equivalent support for computed attributes, using property 
or a custom descriptors. While it's a bit lower-level than Ruby, it's 
still quite easy to use and IMHO a bit more powerful.

> The equivalent python idiom is something like:
> 
> class A:
>   __a = "foo"
>   def __init__(self):
> self.a = A.__a

WTF ???

> Which roughly translates to this in ruby:
> 
> class A
>   attr_accessor :a
>   def initialize
> @a = "foo"
>   end
> end

The Python translation of the above Ruby snippet is actually way more 
simple:

class A(object):
   def __init__(self):
 self.a = "foo"


> Python:
> 
> 1.) I also found python's style of method referencing to be a lot more
> intuitive than using something like ruby's "m = method('foo');
> m.call('bar')" to get a reference to foo() and call it. It's alot
> cleaner to say "m = foo; m('bar')", imo. But this goes back to the
> omitting parens thing, which makes it impossible to do it that way in
> ruby.

Yeps. This is where the real and fundamental difference between Ruby and 
Python becomes evident. Both have support for transparent computed 
attributes, but the way it's implemented is totally different - in Ruby, 
by not having a call operator at all (I mean, the parens), in Python by 
having both an explicit call operator and an explicit protocol for 
computed attributes (the descriptor protocol). Not to say one is better 
than the other, but that while both languages have similar features 
(and, at first look, similar syntaxes), they really have totally 
different object models.

> Though, ruby does allow some interesting things by having it
> that way, e.g., letting you substitute a Proc object (e.g., a block or
> lambda) for a method reference transparently.

Care to give an example ? I don't have enough working experience with 
Ruby to be sure I understand what you mean here.

> 2.) I also find layout to be a nice feature. And since I've recently
> been using Haskell, it has only re-inforced that opinion. But when I
> first started using python, I got bitten by IndentationError quite
> often. And I kept wanting to type some closing symbol, heh. ;)

The nice thing with Python is that it lets you use the closing symbol 
you want, as long as you prefix it with a '#' !-)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: a Python person's experience with Ruby

2007-12-08 Thread James Matthews
I have been waiting for something like this! Thanks!

On Dec 8, 2007 6:08 AM, Steve Howell <[EMAIL PROTECTED]> wrote:

> Python is my favorite programming language.  I've used
> it as my primary language for about six years now,
> including four years of using it full-time in my day
> job.  Three months ago I decided to take a position
> with a team that does a lot of things very well, but
> they don't use Python.  We use Ruby instead.  I'd like
> to share my observations about Ruby, because I think
> they say important things about Python, which has been
> my frame of reference.
>
> First of all, I actually enjoy programming in Ruby.
> Although I'm still fairly early on the learning curve,
> I feel like I've achieved basic fluency, and it
> generally stays out of the way.
>
> (A quick disclaimer is that some of the observations I
> make about Ruby may simply reflect my ignorance about
> the language.  I'm still learning it.)
>
> The thing that I like least about Ruby is its
> "require" mechanism.  Basically, when you do "require"
> in Ruby, it sort of pollutes your namespace.  I much
> prefer Python's explicitness.
>
> Some surprising things that I like about Ruby:
>
>  1) It has the Perlish natural language syntax of
> "raise 'foo' if condition."  I never missed having
> that syntax in Python, but now that I have it in Ruby,
> I use it quite often.
>
>  2) On a general note, Ruby is enough like Python
> that it doesn't bend my brain.
>
>  3) I actually like being able to omit parentheses in
> method definitions and method calls.  In Ruby you can
> express "add(3,5,7)" as both "add(3,5,7)" and "add 3,
> 5, 7."  The latter syntax is obviously more error
> prone, but I don't think I've ever actually gotten bit
> by it, and the code appears more clean to me.
>
>  4) Ruby forces you to explicitly make attributes for
> instance variables.  At first I found this clumsy, but
> I've gotten used to it, and I actually kind of like it
> in certain circumstances.
>
> What I miss about Python:
>
>  1) I like the fact that Python's syntax for passing
> around methods is very natural. Ruby's syntax is much
> more clumsy.
>
>  2) I miss indentation.  I get bitten by kEnd in Ruby
> all the time.
>
>  3) I miss Python's maturity.  Just to give a small
> example, Python's interpreter gives more readable
> syntax error messages.
>
> Those are the things that jump out for me.  I'm
> curious to hear what other people have learned about
> Python after maybe going away from it for a while.
>
>
>
>
>
>  
> 
> Be a better friend, newshound, and
> know-it-all with Yahoo! Mobile.  Try it now.
> http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ
>
> --
> http://mail.python.org/mailman/listinfo/python-list
>



-- 
http://search.goldwatches.com/?Search=Movado+Watches
http://www.jewelerslounge.com
http://www.goldwatches.com
-- 
http://mail.python.org/mailman/listinfo/python-list

Re: a Python person's experience with Ruby

2007-12-08 Thread Arkanes
Colin J. Williams wrote:
> Steve Howell wrote:>
> Thanks for the interesting comparison.
>
> [snip]
>   
>>   3) I actually like being able to omit parentheses in
>> method definitions and method calls.  In Ruby you can
>> express "add(3,5,7)" as both "add(3,5,7)" and "add 3,
>> 5, 7."  The latter syntax is obviously more error
>> prone, but I don't think I've ever actually gotten bit
>> by it, and the code appears more clean to me.
>>
>> 
> [snip]
>
> I'm not sure that I like add 3, 5, 7
>
> but it would be nice to be able to drop 
> the parentheses
> when no argument is required.
>
> Thus: close;
> could replace close();
>
>   

The fact that you can do this in Ruby and not in Python is why passing 
callables in Ruby is awkward and it's extremely natural in Python. In 
Ruby, of course, you don't pass callables around as much, using blocks 
instead, so it works out there. But it's an example of some of the 
fundamental syntax differences between the languages.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: a Python person's experience with Ruby

2007-12-08 Thread Colin J. Williams
MonkeeSage wrote:
> On Dec 7, 11:08 pm, Steve Howell <[EMAIL PROTECTED]> wrote:
>> Python is my favorite programming language.  I've used
>> it as my primary language for about six years now,
>> including four years of using it full-time in my day
>> job.  Three months ago I decided to take a position
>> with a team that does a lot of things very well, but
>> they don't use Python.  We use Ruby instead.  I'd like
>> to share my observations about Ruby, because I think
>> they say important things about Python, which has been
>> my frame of reference.
>>
>> First of all, I actually enjoy programming in Ruby.
>> Although I'm still fairly early on the learning curve,
>> I feel like I've achieved basic fluency, and it
>> generally stays out of the way.
>>
>> (A quick disclaimer is that some of the observations I
>> make about Ruby may simply reflect my ignorance about
>> the language.  I'm still learning it.)
>>
>> The thing that I like least about Ruby is its
>> "require" mechanism.  Basically, when you do "require"
>> in Ruby, it sort of pollutes your namespace.  I much
>> prefer Python's explicitness.
>>
>> Some surprising things that I like about Ruby:
>>
>>   1) It has the Perlish natural language syntax of
>> "raise 'foo' if condition."  I never missed having
>> that syntax in Python, but now that I have it in Ruby,
>> I use it quite often.
This could be done in Python if raise 
became a function,
as it has for print.

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


Re: a Python person's experience with Ruby

2007-12-08 Thread Colin J. Williams
Steve Howell wrote:>
Thanks for the interesting comparison.

[snip]
>   3) I actually like being able to omit parentheses in
> method definitions and method calls.  In Ruby you can
> express "add(3,5,7)" as both "add(3,5,7)" and "add 3,
> 5, 7."  The latter syntax is obviously more error
> prone, but I don't think I've ever actually gotten bit
> by it, and the code appears more clean to me.
> 
[snip]

I'm not sure that I like add 3, 5, 7

but it would be nice to be able to drop 
the parentheses
when no argument is required.

Thus: close;
could replace close();

Colin W.

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


Re: a Python person's experience with Ruby

2007-12-07 Thread MonkeeSage
On Dec 7, 11:08 pm, Steve Howell <[EMAIL PROTECTED]> wrote:
> Python is my favorite programming language.  I've used
> it as my primary language for about six years now,
> including four years of using it full-time in my day
> job.  Three months ago I decided to take a position
> with a team that does a lot of things very well, but
> they don't use Python.  We use Ruby instead.  I'd like
> to share my observations about Ruby, because I think
> they say important things about Python, which has been
> my frame of reference.
>
> First of all, I actually enjoy programming in Ruby.
> Although I'm still fairly early on the learning curve,
> I feel like I've achieved basic fluency, and it
> generally stays out of the way.
>
> (A quick disclaimer is that some of the observations I
> make about Ruby may simply reflect my ignorance about
> the language.  I'm still learning it.)
>
> The thing that I like least about Ruby is its
> "require" mechanism.  Basically, when you do "require"
> in Ruby, it sort of pollutes your namespace.  I much
> prefer Python's explicitness.
>
> Some surprising things that I like about Ruby:
>
>   1) It has the Perlish natural language syntax of
> "raise 'foo' if condition."  I never missed having
> that syntax in Python, but now that I have it in Ruby,
> I use it quite often.
>
>   2) On a general note, Ruby is enough like Python
> that it doesn't bend my brain.
>
>   3) I actually like being able to omit parentheses in
> method definitions and method calls.  In Ruby you can
> express "add(3,5,7)" as both "add(3,5,7)" and "add 3,
> 5, 7."  The latter syntax is obviously more error
> prone, but I don't think I've ever actually gotten bit
> by it, and the code appears more clean to me.
>
>   4) Ruby forces you to explicitly make attributes for
> instance variables.  At first I found this clumsy, but
> I've gotten used to it, and I actually kind of like it
> in certain circumstances.
>
> What I miss about Python:
>
>   1) I like the fact that Python's syntax for passing
> around methods is very natural. Ruby's syntax is much
> more clumsy.
>
>   2) I miss indentation.  I get bitten by kEnd in Ruby
> all the time.
>
>   3) I miss Python's maturity.  Just to give a small
> example, Python's interpreter gives more readable
> syntax error messages.
>
> Those are the things that jump out for me.  I'm
> curious to hear what other people have learned about
> Python after maybe going away from it for a while.
>
>   
> 
> Be a better friend, newshound, and
> know-it-all with Yahoo! Mobile.  Try it now.  
> http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ

Hello,

Standard disclaimer: This response is in the spirit of sharing
knowledge and experience, as I take your post to be, not in the spirit
of advocacy of any language. All opinions I express are simply that:
my opinion.

I use both python and ruby quite often. But I came from the other
direction, starting with ruby then learning python. Overall, I think
they are both great languages, and I believe the choice in whether to
use one or the other (or both!) is determined mainly by expedience and
preference. I'll try to give my thoughts on your points, which I had
as I was learning python a few years ago, along with my current
opinions:

Ruby:

0.) I found python's concept of namespaces as defined by imported
modules (i.e., files) to be strange at first. I used "from foo import
*" a lot starting out. The main thing that I had to get my mind around
was that in ruby a namespace applies to an object (even "main", i.e.,
toplevel, is an instance of class Object), and you can "re-open"
objects to extend their namespace (or mix in "modules", which in ruby
are like a container of unbound methods that you can "include" in
another object and thereby bind those methods to that object). So
rather than "import" a module with the namespace "string," as in
python, in ruby you'd require a file that re-opens class String and
extends it. They are two different approaches (and two different ideas
of namespace pollution), but once you get your mind around both, they
are very easy to use. I almost never use "from foo import *" now in
python.

1.) I missed the infix version of conditionals that ruby provides at
first, and I would often write things like "if foo: bar" in python if
the line was short. Now it just feels more natural to write it on two
lines in python most of the time, though in ruby I still use the other
notation if the line is short.

2.) I found the same was true. I could basically translate 90% of the
ruby idioms directly into python (minor syntax issues aside), and vise
versa.

3.) I never have liked omitting parens in ruby method calls (with the
exception of methods taking no arguments, but I didn't even do that
for a long time), though many/most rubyists do use that style. One
problem with it is that it leads to ambiguities, and the parser
complains in thos

a Python person's experience with Ruby

2007-12-07 Thread Steve Howell
Python is my favorite programming language.  I've used
it as my primary language for about six years now,
including four years of using it full-time in my day
job.  Three months ago I decided to take a position
with a team that does a lot of things very well, but
they don't use Python.  We use Ruby instead.  I'd like
to share my observations about Ruby, because I think
they say important things about Python, which has been
my frame of reference.  

First of all, I actually enjoy programming in Ruby. 
Although I'm still fairly early on the learning curve,
I feel like I've achieved basic fluency, and it
generally stays out of the way.  

(A quick disclaimer is that some of the observations I
make about Ruby may simply reflect my ignorance about
the language.  I'm still learning it.)

The thing that I like least about Ruby is its
"require" mechanism.  Basically, when you do "require"
in Ruby, it sort of pollutes your namespace.  I much
prefer Python's explicitness.

Some surprising things that I like about Ruby:

  1) It has the Perlish natural language syntax of
"raise 'foo' if condition."  I never missed having
that syntax in Python, but now that I have it in Ruby,
I use it quite often.

  2) On a general note, Ruby is enough like Python
that it doesn't bend my brain.

  3) I actually like being able to omit parentheses in
method definitions and method calls.  In Ruby you can
express "add(3,5,7)" as both "add(3,5,7)" and "add 3,
5, 7."  The latter syntax is obviously more error
prone, but I don't think I've ever actually gotten bit
by it, and the code appears more clean to me.

  4) Ruby forces you to explicitly make attributes for
instance variables.  At first I found this clumsy, but
I've gotten used to it, and I actually kind of like it
in certain circumstances.

What I miss about Python:

  1) I like the fact that Python's syntax for passing
around methods is very natural. Ruby's syntax is much
more clumsy.

  2) I miss indentation.  I get bitten by kEnd in Ruby
all the time.

  3) I miss Python's maturity.  Just to give a small
example, Python's interpreter gives more readable
syntax error messages.

Those are the things that jump out for me.  I'm
curious to hear what other people have learned about
Python after maybe going away from it for a while.




  

Be a better friend, newshound, and 
know-it-all with Yahoo! Mobile.  Try it now.  
http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ 

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