digitalmars.D - Arguments and attributes with the same name
- bearophile (16/16) Mar 04 2010 This is correct D code, but I think it's a bad practice to write code li...
- Ary Borenszweig (4/23) Mar 04 2010 This can be solved if the compiler warns when an assignment is from a
- bearophile (6/10) Mar 04 2010 That's nice in general to have, but I think it's not enough, because if ...
- Ary Borenszweig (16/26) Mar 04 2010 class Foo:
- Bane (1/5) Mar 04 2010 Nice and useful.
- =?ISO-8859-1?Q?Pelle_M=E5nsson?= (8/13) Mar 04 2010 struct A {
- bearophile (11/12) Mar 04 2010 This is correct D code:
- Ary Borenszweig (3/20) Mar 04 2010 Now I understand. So you suggest to forbid having an argument name that
- bearophile (5/7) Mar 04 2010 I prefer the compiler to give an error when an argument has the same nam...
- Ary Borenszweig (3/13) Mar 04 2010 But python doesn't do it either. Did you suggest the same thing to the
- bearophile (15/17) Mar 04 2010 :-)
- Steven Schveighoffer (9/17) Mar 04 2010 I think the point is, the statement x = x + 1; isn't any more or less
- bearophile (21/24) Mar 04 2010 It's not the same meaning, this program prints "1":
- Steven Schveighoffer (9/31) Mar 04 2010 That's not the ambiguity being discussed. What is being discussed is wh...
- Nick Sabalausky (13/17) Mar 05 2010 As someone who's still somewhat of a novice at ruby, but trying it out a...
- bearophile (10/11) Mar 06 2010 I know some Python, but I have written only small things in Ruby, so my ...
- Clemens (8/15) Mar 04 2010 I'd rather not have that, I like to write my constructors in the way you...
- Jonathan M Davis (19/38) Mar 04 2010 Agreed. It would be _highly_ annoying if you couldn't have parameters to...
- bearophile (5/6) Mar 04 2010 Thank you for spotting my stupid idea :o)
This is correct D code, but I think it's a bad practice to write code like this, where method arguments have the same name as instance/static attributes of the class/struct. class Foo { int x; this(int x) { this.x = x; } void inc(int x) { this.x += x; } } struct Bar { static int x; void inc(int x) { Bar.x += x; } } void main() {} In Python this problem is less important because the language forces you to always prepend the argument names with "self.", while in D the "this." is optional. In the last years D has added errors for situations where you use duplicated names, for example in nested scopes or in with statement. So do you think it's a good idea to forbid/warn against such name clash? Bye, bearophile
Mar 04 2010
bearophile wrote:This is correct D code, but I think it's a bad practice to write code like this, where method arguments have the same name as instance/static attributes of the class/struct. class Foo { int x; this(int x) { this.x = x; } void inc(int x) { this.x += x; } } struct Bar { static int x; void inc(int x) { Bar.x += x; } } void main() {} In Python this problem is less important because the language forces you to always prepend the argument names with "self.", while in D the "this." is optional. In the last years D has added errors for situations where you use duplicated names, for example in nested scopes or in with statement. So do you think it's a good idea to forbid/warn against such name clash?This can be solved if the compiler warns when an assignment is from a variable to the same one. x = x; // error: assignment has no effect
Mar 04 2010
Ary Borenszweig:This can be solved if the compiler warns when an assignment is from a variable to the same one. x = x; // error: assignment has no effectThat's nice in general to have, but I think it's not enough, because if I want to assign to an attribute an incremented value: x = x+1; What is that x? The attribute or the argument? Bye, bearophile
Mar 04 2010
bearophile wrote:Ary Borenszweig:class Foo: def __init__(self, x): x = x + 1 This compiles just fine in pyhtoh. What is x here? The argument, of course, because that's how it works in python. You forgot to put self before x. class Foo { int x; this(int x) { x = x + 1; } } What is x here? The argument, of course, because that's how it works in python. You forgot to put this before x. How is python safer than D in that sense?This can be solved if the compiler warns when an assignment is from a variable to the same one. x = x; // error: assignment has no effectThat's nice in general to have, but I think it's not enough, because if I want to assign to an attribute an incremented value: x = x+1; What is that x? The attribute or the argument?
Mar 04 2010
This can be solved if the compiler warns when an assignment is from a variable to the same one. x = x; // error: assignment has no effectNice and useful.
Mar 04 2010
On 03/04/2010 02:44 PM, Bane wrote:struct A { int i; void opAssign(A a) { i = a.i + 1; } } why not?This can be solved if the compiler warns when an assignment is from a variable to the same one. x = x; // error: assignment has no effectNice and useful.
Mar 04 2010
Ary Borenszweig:How is python safer than D in that sense?This is correct D code: class Foo { int x; this() { x = 5; } } void main() {} In Python "self." is always needed to refer to the attribute, and "x" refers to the argument (or a global name, but then you need a global statement). So the eyes of Python programmers are trained to remember such difference. In D the "this." is optional, even in the constructor. So it's more ambiguous, you have to look at the signature of the method you are inside (or the IDE has to color your names differently). Bye, bearophile
Mar 04 2010
bearophile wrote:Ary Borenszweig:Now I understand. So you suggest to forbid having an argument name that matches an attribute name? Or require this. for attribute access?How is python safer than D in that sense?This is correct D code: class Foo { int x; this() { x = 5; } } void main() {} In Python "self." is always needed to refer to the attribute, and "x" refers to the argument (or a global name, but then you need a global statement). So the eyes of Python programmers are trained to remember such difference. In D the "this." is optional, even in the constructor. So it's more ambiguous, you have to look at the signature of the method you are inside (or the IDE has to color your names differently). Bye, bearophile
Mar 04 2010
Ary Borenszweig:So you suggest to forbid having an argument name that matches an attribute name? Or require this. for attribute access?I prefer the compiler to give an error when an argument has the same name of an attribute, it's tidier. If you think that solution is too much restricting, there's a second solution: in only those case, where there can be ambiguity for the eyes of a programmer the compiler can require the use of "this.". Bye, bearophile
Mar 04 2010
bearophile wrote:Ary Borenszweig:But python doesn't do it either. Did you suggest the same thing to the python devs? :-)So you suggest to forbid having an argument name that matches an attribute name? Or require this. for attribute access?I prefer the compiler to give an error when an argument has the same name of an attribute, it's tidier.If you think that solution is too much restricting, there's a second solution: in only those case, where there can be ambiguity for the eyes of a programmer the compiler can require the use of "this.". Bye, bearophile
Mar 04 2010
Ary Borenszweig:But python doesn't do it either. Did you suggest the same thing to the python devs? :-):-) Well, when I teach Python I give the advice of not using the same names for arguments and attributes. So it's a programming practice. Here the situation in D is worse, because in Python there's always a "self." before attribute names, so there's no real ambiguity. Python is the language I currently prefer, but it's not perfect, and every Python programmer knows it has some messy corners. Even Python programmers recognize that Python can enjoy some of the features D already has, like transitive immutability: http://groups.google.com/group/comp.lang.python/browse_thread/thread/7ef75c20d1be370d/ Or the scope exit: http://groups.google.com/group/comp.lang.python/browse_thread/thread/8c752e871801c223 Or the underscore inside number literals (many people want them, but Hettinger has said that normal Python programs have few literals, and such change requires too much big changes in the Python parser, so they have refused it). I can show you other examples of messy things in Python, like the "confusion" between class instance attributes and class attributes (you can call class attributes even with an instance syntax, with the self). Python was born to write scripts, not to write large multi-programmer applications. Later they have patched some holes, but some of the original more "relaxed" nature of Python shows still (Ruby is worse than Python regarding large multiprogrammer programs). I have just filed the bug: http://d.puremagic.com/issues/show_bug.cgi?id=3878 Bye, bearophile
Mar 04 2010
On Thu, 04 Mar 2010 11:06:15 -0500, bearophile <bearophileHUGS lycos.com> wrote:Ary Borenszweig:I think the point is, the statement x = x + 1; isn't any more or less ambiguous in D than it is in python. There is a well-defined meaning (and in fact the same meaning). However, your point that it should be more difficult to make such mistakes is a good one. I just don't think it translates at all to "Python's way is better" :) -SteveBut python doesn't do it either. Did you suggest the same thing to the python devs? :-):-) Well, when I teach Python I give the advice of not using the same names for arguments and attributes. So it's a programming practice. Here the situation in D is worse, because in Python there's always a "self." before attribute names, so there's no real ambiguity.
Mar 04 2010
Steven Schveighoffer:I think the point is, the statement x = x + 1; isn't any more or less ambiguous in D than it is in python. There is a well-defined meaning (and in fact the same meaning).It's not the same meaning, this program prints "1": import std.c.stdio: printf; class Foo { int x; this() {} void foo() { x = x + 1; } } void main() { Foo f = new Foo(); f.foo(); printf("%d\n", f.x); // prints 1 } An equivalent Python program with "x = x + 1;" prints: UnboundLocalError: local variable 'x' referenced before assignment Because the usage of "self." is obligatory. Anyway, this whole thread is not about Python, it's about D. Bye, bearophile
Mar 04 2010
On Thu, 04 Mar 2010 11:49:13 -0500, bearophile <bearophileHUGS lycos.com> wrote:Steven Schveighoffer:That's not the ambiguity being discussed. What is being discussed is when there is a local parameter with the same name as an instance field. In that context, (at least from what I read in this thread) D and python are the same. Anyway, it's not important. I agree that it may be good to disallow this from happening in the first place. -SteveI think the point is, the statement x = x + 1; isn't any more or less ambiguous in D than it is in python. There is a well-defined meaning (and in fact the same meaning).It's not the same meaning, this program prints "1": import std.c.stdio: printf; class Foo { int x; this() {} void foo() { x = x + 1; } } void main() { Foo f = new Foo(); f.foo(); printf("%d\n", f.x); // prints 1 } An equivalent Python program with "x = x + 1;" prints: UnboundLocalError: local variable 'x' referenced before assignment Because the usage of "self." is obligatory.
Mar 04 2010
"bearophile" <bearophileHUGS lycos.com> wrote in message news:hmolpn$1fnv$1 digitalmars.com...Python was born to write scripts, not to write large multi-programmer applications. Later they have patched some holes, but some of the original more "relaxed" nature of Python shows still (Ruby is worse than Python regarding large multiprogrammer programs).As someone who's still somewhat of a novice at ruby, but trying it out a little (b/c it seems to be kind of like a python without indentation-scoping), I'm curious what you see in ruby as being worse for large programs than python. In ruby, I've already been bit by the fact that any explicit "return" from a closure returns from not just the closure itself, but also from the function that called the closure, all the way through the stack, and finally returning from the function that the closure was defined in (unless you remembered to create the closure using the "lambda" keyword). I can imagine a host of problems stemming from that, but not a single useful use-case. I assume you've seen some other large-project drawbacks in ruby besides that?
Mar 05 2010
Nick Sabalausky:I'm curious what you see in ruby as being worse for large programs than python.<I know some Python, but I have written only small things in Ruby, so my judgement doesn't have strong roots. From what I have seen Ruby: - Has more syntax freedom, this allows you to create a sublanguage fit for a problem, but also makes Ruby code more variable; - Its syntax is sometimes more handy, like the function parenthesis that can be omitted, the automatic return value, but this also increases the possible bugs a little; - Ruby monkey patching can be done in Python too, but it's considered a bad practice because it's not scoped. This Ruby practice sometimes causes problems. Python looks like a little more tidy and regular language compared to Ruby. I associate this to the ability to write a little larger programs safely. But such difference between Ruby and Python isn't large, they are two similar languages (more than Pascal and C were). It's also a matter of programmer taste, there are people that like a little more freedom (Perl, Ruby, C), and people that like a "safer" language (Java, Ada, and probably Haskell too). D2 is a bit safer than C. In any language you can define a style guide to help you write bigger amounts of code, this is the Google Style Guide for Python: http://google-styleguide.googlecode.com/svn/trunk/pyguide.html Bye, bearophile
Mar 06 2010
bearophile Wrote:Ary Borenszweig:I'd rather not have that, I like to write my constructors in the way you have shown in your first post: class Foo { int x; this(int x) { this.x = x; } } Saves me from inventing silly names for the parameters (like "theX") or appending ugly pre-/suffixes like an underscore.So you suggest to forbid having an argument name that matches an attribute name? Or require this. for attribute access?I prefer the compiler to give an error when an argument has the same name of an attribute, it's tidier.If you think that solution is too much restricting, there's a second solution: in only those case, where there can be ambiguity for the eyes of a programmer the compiler can require the use of "this.".I don't understand this suggestion. As soon as you have an instance variable x and a function parameter x, there will *always* be ambiguity (unless you don't use the parameter). Requiring the use of "this." amounts to disallowing access to the parameter x. Or do you suggest making the distinction based on whether x is used as an lvalue or a rvalue?
Mar 04 2010
Clemens wrote:bearophile Wrote:Agreed. It would be _highly_ annoying if you couldn't have parameters to member functions (constructors or otherwise) which had the same names as member variables. And if you have protected member variables with the same name as a parameter, it would get even worse. Not to mention, properties (which may not be associated with a member variable at all) would likely fall in the same category and it would be even worse. x = x; is clearly an error. No, x = x + 1; is not, but it's not at all ambiguous. If you want to make absolutely certain that you never have this issue, either always use this or use the more common solution of appending your member variable's names with _ or m_, so you'd get _x = x; I really don't think that this is a big problem. And it would be really annoying if you were to restrict parameter names based on the names of member variables or properties. - Jonathan M DavisAry Borenszweig:I'd rather not have that, I like to write my constructors in the way you have shown in your first post: class Foo { int x; this(int x) { this.x = x; } } Saves me from inventing silly names for the parameters (like "theX") or appending ugly pre-/suffixes like an underscore.So you suggest to forbid having an argument name that matches an attribute name? Or require this. for attribute access?I prefer the compiler to give an error when an argument has the same name of an attribute, it's tidier.
Mar 04 2010
Clemens:As soon as you have an instance variable x and a function parameter x, there will *always* be ambiguity (unless you don't use the parameter). Requiring the use of "this." amounts to disallowing access to the parameter x.<Thank you for spotting my stupid idea :o) I will update the enhancement request with this note of yours. Bye, bearophile
Mar 04 2010