www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - byKey and byValue: properties or methods?

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
I hate I must ask this:

int[string] aa;
foreach (k; aa.byKey) { ... }

or

int[string] aa;
foreach (k; aa.byKey()) { ... }



Thanks,

Andrei "I told you" Alexandrescu
Jan 16 2012
next sibling parent Mail Mantis <mail.mantis.88 gmail.com> writes:
2012/1/17 Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:
 I hate I must ask this:

Can't find any arguments for either version, but subjectively I like non-property version more.
Jan 16 2012
prev sibling next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message 
news:jf35jr$e2k$1 digitalmars.com...
I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }

Property. It's not an action, you're just accessing a particular interface of aa.
Jan 16 2012
parent "Nick Sabalausky" <a a.a> writes:
"Nick Sabalausky" <a a.a> wrote in message 
news:jf36tf$g3g$1 digitalmars.com...
 "Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message 
 news:jf35jr$e2k$1 digitalmars.com...
I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }

Property. It's not an action, you're just accessing a particular interface of aa.

Another way you can look at it to make it clear: As far as the caller is concerened, it would have made equal sense if byKey were implemented as a nested struct. Ie, it's data, not action. Just because your implementation happens to involve an imperative block of statements doesn't change the user's perspective of byKey's semantics. Nick "Yes, it is still clear-cut" Sabalausky ;)
Jan 16 2012
prev sibling next sibling parent reply =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <xtzgzorex gmail.com> writes:
On 17-01-2012 07:48, Andrei Alexandrescu wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }



 Thanks,

 Andrei "I told you" Alexandrescu

My thoughts: The "by" in the name is way too awkward for a property. If it was just named "keys" and "values", it would've been perfectly fine to make them properties, but the "by" just looks awkward when you "call" them as properties. As far as efficiency goes, I don't think these perform any work that is heavy enough to warrant not making them properties. (I can't say that same for .dup/.idup... I still don't get why those are properties, at all.) -- - Alex
Jan 17 2012
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, January 17, 2012 09:07:04 Alex R=C3=B8nne Petersen wrote:
 On 17-01-2012 07:48, Andrei Alexandrescu wrote:
 I hate I must ask this:
=20
 int[string] aa;
 foreach (k; aa.byKey) { ... }
=20
 or
=20
 int[string] aa;
 foreach (k; aa.byKey()) { ... }
=20
=20
=20
 Thanks,
=20
 Andrei "I told you" Alexandrescu

My thoughts: =20 The "by" in the name is way too awkward for a property. If it was jus=

 named "keys" and "values", it would've been perfectly fine to make th=

 properties, but the "by" just looks awkward when you "call" them as
 properties.
=20
 As far as efficiency goes, I don't think these perform any work that =

 heavy enough to warrant not making them properties. (I can't say that=

 same for .dup/.idup... I still don't get why those are properties, at=

Agreed. If it were keys and values, then a property would make sense. H= owever,=20 since it's byKey and byValue, I don't think that it makes as much sense= . It=20 _is_ a bit of a weird case though, since byKey and byValue are neither = nouns=20 nor verbs. - Jonathan M Davis
Jan 17 2012
parent reply "Nick Sabalausky" <a a.a> writes:
"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message 
news:mailman.496.1326793835.16222.digitalmars-d puremagic.com...
On Tuesday, January 17, 2012 09:07:04 Alex Rønne Petersen wrote:
 On 17-01-2012 07:48, Andrei Alexandrescu wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }

The "by" in the name is way too awkward for a property. If it was just named "keys" and "values", it would've been perfectly fine to make them properties, but the "by" just looks awkward when you "call" them as properties. As far as efficiency goes, I don't think these perform any work that is heavy enough to warrant not making them properties. (I can't say that same for .dup/.idup... I still don't get why those are properties, at all.)

Agreed. If it were keys and values, then a property would make sense. However, since it's byKey and byValue, I don't think that it makes as much sense. It _is_ a bit of a weird case though, since byKey and byValue are neither nouns nor verbs.

You're all getting hung up on the trivial detail of the names. Look at the semantics: They retreive a range associated with the aa, right? Right. Property. It's a plain old classic getter.
Jan 17 2012
next sibling parent reply =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <xtzgzorex gmail.com> writes:
On 17-01-2012 13:41, Nick Sabalausky wrote:
 "Jonathan M Davis"<jmdavisProg gmx.com>  wrote in message
 news:mailman.496.1326793835.16222.digitalmars-d puremagic.com...
 On Tuesday, January 17, 2012 09:07:04 Alex Rønne Petersen wrote:
 On 17-01-2012 07:48, Andrei Alexandrescu wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }

The "by" in the name is way too awkward for a property. If it was just named "keys" and "values", it would've been perfectly fine to make them properties, but the "by" just looks awkward when you "call" them as properties. As far as efficiency goes, I don't think these perform any work that is heavy enough to warrant not making them properties. (I can't say that same for .dup/.idup... I still don't get why those are properties, at all.)

Agreed. If it were keys and values, then a property would make sense. However, since it's byKey and byValue, I don't think that it makes as much sense. It _is_ a bit of a weird case though, since byKey and byValue are neither nouns nor verbs.

You're all getting hung up on the trivial detail of the names. Look at the semantics: They retreive a range associated with the aa, right? Right. Property. It's a plain old classic getter.

That doesn't make the name any less bad. Naming is important IMHO. Hence why I'm also complaining about .dup/.idup. -- - Alex
Jan 17 2012
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/17/2012 02:14 PM, Alex Rønne Petersen wrote:
 On 17-01-2012 13:41, Nick Sabalausky wrote:
 "Jonathan M Davis"<jmdavisProg gmx.com> wrote in message
 news:mailman.496.1326793835.16222.digitalmars-d puremagic.com...
 On Tuesday, January 17, 2012 09:07:04 Alex Rønne Petersen wrote:
 On 17-01-2012 07:48, Andrei Alexandrescu wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }

The "by" in the name is way too awkward for a property. If it was just named "keys" and "values", it would've been perfectly fine to make them properties, but the "by" just looks awkward when you "call" them as properties. As far as efficiency goes, I don't think these perform any work that is heavy enough to warrant not making them properties. (I can't say that same for .dup/.idup... I still don't get why those are properties, at all.)

Agreed. If it were keys and values, then a property would make sense. However, since it's byKey and byValue, I don't think that it makes as much sense. It _is_ a bit of a weird case though, since byKey and byValue are neither nouns nor verbs.

You're all getting hung up on the trivial detail of the names. Look at the semantics: They retreive a range associated with the aa, right? Right. Property. It's a plain old classic getter.

That doesn't make the name any less bad. Naming is important IMHO. Hence why I'm also complaining about .dup/.idup.

I think the compiler should just allow .dup()/.idup(). It would not break any existing code.
Jan 17 2012
next sibling parent =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <xtzgzorex gmail.com> writes:
On 17-01-2012 19:41, Timon Gehr wrote:
 On 01/17/2012 02:14 PM, Alex Rønne Petersen wrote:
 On 17-01-2012 13:41, Nick Sabalausky wrote:
 "Jonathan M Davis"<jmdavisProg gmx.com> wrote in message
 news:mailman.496.1326793835.16222.digitalmars-d puremagic.com...
 On Tuesday, January 17, 2012 09:07:04 Alex Rønne Petersen wrote:
 On 17-01-2012 07:48, Andrei Alexandrescu wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }

The "by" in the name is way too awkward for a property. If it was just named "keys" and "values", it would've been perfectly fine to make them properties, but the "by" just looks awkward when you "call" them as properties. As far as efficiency goes, I don't think these perform any work that is heavy enough to warrant not making them properties. (I can't say that same for .dup/.idup... I still don't get why those are properties, at all.)

Agreed. If it were keys and values, then a property would make sense. However, since it's byKey and byValue, I don't think that it makes as much sense. It _is_ a bit of a weird case though, since byKey and byValue are neither nouns nor verbs.

You're all getting hung up on the trivial detail of the names. Look at the semantics: They retreive a range associated with the aa, right? Right. Property. It's a plain old classic getter.

That doesn't make the name any less bad. Naming is important IMHO. Hence why I'm also complaining about .dup/.idup.

I think the compiler should just allow .dup()/.idup(). It would not break any existing code.

+1. -- - Alex
Jan 17 2012
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/18/12 7:20 AM, Steven Schveighoffer wrote:
 I think the compiler should not be in the business of generating methods
 or properties that could be trivially handled by the library.

Yes. I'm fighting Walter tooth and nail over that, with pale success.
 The only array-specific properties of an array that the compiler should
 worry about are ptr and length. Everything else should be a library
 function.

Even ptr and length should be in the library. The slice structure should be defined in object.d. The only business the compiler has is to lower the T[] type syntax and the [ ... ] literal syntax to .object.Slice!T and .object.slice(...) form, and to make sure that typeof(T[]) is not struct (although factually it is). Andrei
Jan 18 2012
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2012-01-18 14:59, Andrei Alexandrescu wrote:
 On 1/18/12 7:20 AM, Steven Schveighoffer wrote:
 I think the compiler should not be in the business of generating methods
 or properties that could be trivially handled by the library.

Yes. I'm fighting Walter tooth and nail over that, with pale success.
 The only array-specific properties of an array that the compiler should
 worry about are ptr and length. Everything else should be a library
 function.

Even ptr and length should be in the library. The slice structure should be defined in object.d. The only business the compiler has is to lower the T[] type syntax and the [ ... ] literal syntax to .object.Slice!T and .object.slice(...) form, and to make sure that typeof(T[]) is not struct (although factually it is). Andrei

But a library can't handle common properties like "mangleof" and "stringof"? -- /Jacob Carlborg
Jan 18 2012
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/18/12 12:04 PM, Steven Schveighoffer wrote:
 On Wed, 18 Jan 2012 08:59:57 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 1/18/12 7:20 AM, Steven Schveighoffer wrote:
 The only array-specific properties of an array that the compiler should
 worry about are ptr and length. Everything else should be a library
 function.

Even ptr and length should be in the library. The slice structure should be defined in object.d. The only business the compiler has is to lower the T[] type syntax and the [ ... ] literal syntax to .object.Slice!T and .object.slice(...) form, and to make sure that typeof(T[]) is not struct (although factually it is).

That is debatable. The exact semantics of length are not repeatable in the library, where a get is a simple field access, yet a set calls a method. To achieve the same you would have to require -inline on the compile line. At that point, we have to say "what does it buy us". The function to set the length is already a library function, which is changable outside the compiler. What do we gain besides saying the language is purer?

1. Offer the runtime the possibility of tweaking the efficiency of the abstraction 2. Smaller and simpler compiler 3. Detecting design and implementation bugs in the language (we found a lot while porting the associative arrays) 4. Uniform built-in type behavior and user-defined type behavior, which is a boon for generic code and generally for the language size and understandability As a related example, look at how simple and efficient byKey and byValue are thanks to migrating hashes into the runtime. Andrei
Jan 18 2012
prev sibling parent "Nick Sabalausky" <a a.a> writes:
"Alex Rønne Petersen" <xtzgzorex gmail.com> wrote in message 
news:jf3s86$1opl$1 digitalmars.com...
 On 17-01-2012 13:41, Nick Sabalausky wrote:
 You're all getting hung up on the trivial detail of the names. Look at 
 the
 semantics: They retreive a range associated with the aa, right? Right.
 Property. It's a plain old classic getter.

That doesn't make the name any less bad. Naming is important IMHO.

Right, I was only addressing the original matter "property or function?"
 Hence why I'm also complaining about .dup/.idup.

Yes, dup/idup are clearly not properties. But they're from way before property, so of course that's why they are how they are (Not that it's good for them to be that way). I'm also in favor of the suggestion of at least optionally allowing dup()/idup().
Jan 17 2012
prev sibling next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/17/2012 01:41 PM, Nick Sabalausky wrote:
 "Jonathan M Davis"<jmdavisProg gmx.com>  wrote in message
 news:mailman.496.1326793835.16222.digitalmars-d puremagic.com...
 On Tuesday, January 17, 2012 09:07:04 Alex Rønne Petersen wrote:
 On 17-01-2012 07:48, Andrei Alexandrescu wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }

The "by" in the name is way too awkward for a property. If it was just named "keys" and "values", it would've been perfectly fine to make them properties, but the "by" just looks awkward when you "call" them as properties. As far as efficiency goes, I don't think these perform any work that is heavy enough to warrant not making them properties. (I can't say that same for .dup/.idup... I still don't get why those are properties, at all.)

Agreed. If it were keys and values, then a property would make sense. However, since it's byKey and byValue, I don't think that it makes as much sense. It _is_ a bit of a weird case though, since byKey and byValue are neither nouns nor verbs.

You're all getting hung up on the trivial detail of the names. Look at the semantics: They retreive a range associated with the aa, right? Right. Property. It's a plain old classic getter.

In fact, it creates a new copy that can be iterated on.
Jan 17 2012
prev sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, January 17, 2012 14:14:46 Alex Rønne Petersen wrote:
 That doesn't make the name any less bad. Naming is important IMHO. Hence
 why I'm also complaining about .dup/.idup.

save for forward ranges is pretty much the same. It's a property even though it's name and usage suggests otherwise. But we're pretty much stuck with all three of those at this point. Arguing about it is pretty much quibbling over straws, and some - Andrei in particular - are becoming increasingly adverse to arguing over such small changes to existing code for minimal benefit. - Jonathan M Davis
Jan 17 2012
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 17 Jan 2012 13:41:07 -0500, Timon Gehr <timon.gehr gmx.ch> wrote=
:

 On 01/17/2012 02:14 PM, Alex R=C3=B8nne Petersen wrote:
 On 17-01-2012 13:41, Nick Sabalausky wrote:
 "Jonathan M Davis"<jmdavisProg gmx.com> wrote in message
 news:mailman.496.1326793835.16222.digitalmars-d puremagic.com...
 On Tuesday, January 17, 2012 09:07:04 Alex R=C3=B8nne Petersen wrot=




 On 17-01-2012 07:48, Andrei Alexandrescu wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }

The "by" in the name is way too awkward for a property. If it was =





 just
 named "keys" and "values", it would've been perfectly fine to make=





 them
 properties, but the "by" just looks awkward when you "call" them a=





 properties.

 As far as efficiency goes, I don't think these perform any work th=





 is
 heavy enough to warrant not making them properties. (I can't say t=





 same for .dup/.idup... I still don't get why those are properties,=





 all.)

Agreed. If it were keys and values, then a property would make sens=




 However,
 since it's byKey and byValue, I don't think that it makes as much
 sense. It
 _is_ a bit of a weird case though, since byKey and byValue are neit=




 nouns
 nor verbs.

You're all getting hung up on the trivial detail of the names. Look =



 the
 semantics: They retreive a range associated with the aa, right? Righ=



 Property. It's a plain old classic getter.

That doesn't make the name any less bad. Naming is important IMHO. He=


 why I'm also complaining about .dup/.idup.

I think the compiler should just allow .dup()/.idup(). It would not =

 break any existing code.

I think the compiler should not be in the business of generating methods= = or properties that could be trivially handled by the library. The only array-specific properties of an array that the compiler should = = worry about are ptr and length. Everything else should be a library = function. -Steve
Jan 18 2012
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 18 Jan 2012 08:59:57 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 1/18/12 7:20 AM, Steven Schveighoffer wrote:
 The only array-specific properties of an array that the compiler should
 worry about are ptr and length. Everything else should be a library
 function.

Even ptr and length should be in the library. The slice structure should be defined in object.d. The only business the compiler has is to lower the T[] type syntax and the [ ... ] literal syntax to .object.Slice!T and .object.slice(...) form, and to make sure that typeof(T[]) is not struct (although factually it is).

That is debatable. The exact semantics of length are not repeatable in the library, where a get is a simple field access, yet a set calls a method. To achieve the same you would have to require -inline on the compile line. At that point, we have to say "what does it buy us". The function to set the length is already a library function, which is changable outside the compiler. What do we gain besides saying the language is purer? If we change dup and idup to be library defined, we can get benefits, such as taking advantage of pure being able to implicitly cast to immutable. -Steve
Jan 18 2012
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 18 Jan 2012 14:11:16 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 1/18/12 12:04 PM, Steven Schveighoffer wrote:
 On Wed, 18 Jan 2012 08:59:57 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 1/18/12 7:20 AM, Steven Schveighoffer wrote:
 The only array-specific properties of an array that the compiler  
 should
 worry about are ptr and length. Everything else should be a library
 function.

Even ptr and length should be in the library. The slice structure should be defined in object.d. The only business the compiler has is to lower the T[] type syntax and the [ ... ] literal syntax to .object.Slice!T and .object.slice(...) form, and to make sure that typeof(T[]) is not struct (although factually it is).

That is debatable. The exact semantics of length are not repeatable in the library, where a get is a simple field access, yet a set calls a method. To achieve the same you would have to require -inline on the compile line. At that point, we have to say "what does it buy us". The function to set the length is already a library function, which is changable outside the compiler. What do we gain besides saying the language is purer?

1. Offer the runtime the possibility of tweaking the efficiency of the abstraction

The runtime already implements the abstraction. All that the compiler does special is glue the property to the function call.
 2. Smaller and simpler compiler

Maybe relevant for new compilers.
 3. Detecting design and implementation bugs in the language (we found a  
 lot while porting the associative arrays)

There is only one function to set length. It's not quite comparable to the entire set of associative array functionality. Though as someone who has mostly rewritten it, I can say it's not a trivial function, and may still have bugs in it. However, I don't see changing the entity who glues the property to the function is going to find bugs in the function.
 4. Uniform built-in type behavior and user-defined type behavior, which  
 is a boon for generic code and generally for the language size and  
 understandability

This I agree with, it makes the language uniformly implemented, which makes things simpler to understand/implement. But it already works, and works rather well. This is my point, all we gain is being able to say the language is simpler/purer.
 As a related example, look at how simple and efficient byKey and byValue  
 are thanks to migrating hashes into the runtime.

Not to mention *possible* :) -Steve
Jan 18 2012
prev sibling next sibling parent Jose Armando Garcia <jsancio gmail.com> writes:
On Tue, Jan 17, 2012 at 4:48 AM, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }

If it is any help, Scala libraries use by convention that methods that have a side should be called with '()' while methods that don't have a side effect should be called without the '()'. In scala this translate to: aa.sideEffectWhenCalled() aa.noSideEffect which looks as follow in the definition: def sideEffectWhenCalled() = { ... } def noSideEffect = { ... } I think that this translate really well to D's property. Photos can try to implement the policy that read properties shouldn't have side effects (externally observable side effect). The language doesn't need to enforce but it would be nice if Photos would follow it. Thoughts? Thanks, -Jose
 Thanks,

 Andrei "I told you" Alexandrescu

Jan 17 2012
prev sibling next sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2012-01-17 06:48:26 +0000, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 I hate I must ask this:
 
 int[string] aa;
 foreach (k; aa.byKey) { ... }
 
 or
 
 int[string] aa;
 foreach (k; aa.byKey()) { ... }

Is it a verb? If not, it is a property. But why "by"? Why not just "aa.keys"? It's much more natural. Is "byKey" going to consume the associative array like "byLine" does for files? Obviously no. So I don't see why you need "by" here. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 17 2012
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/17/12 11:09 AM, Michel Fortin wrote:
 On 2012-01-17 06:48:26 +0000, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> said:

 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }

Is it a verb? If not, it is a property. But why "by"? Why not just "aa.keys"? It's much more natural. Is "byKey" going to consume the associative array like "byLine" does for files? Obviously no. So I don't see why you need "by" here.

"Iterate collection by key". aa.keys is taken btw. Andrei
Jan 17 2012
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:

 "Iterate collection by key".

Is this code now working? (I have tried it hours ago): import std.stdio, std.algorithm; void main () { auto aa = ["a":1, "b":2]; writeln(aa.byValue()); writeln( map!q{ a * a }(aa.byValue()) ); } Bye, bearophile
Jan 17 2012
parent bearophile <bearophileHUGS lycos.com> writes:
 Is this code now working? (I have tried it hours ago):

After the last change it now works, thank you. I will close/update the relative Bugzilla Issues. Bye, bearophile
Jan 17 2012
prev sibling parent reply Alvaro <alvaroDotSegura gmail.com> writes:
El 17/01/2012 18:24, Andrei Alexandrescu escribió:
 On 2012-01-17 06:48:26 +0000, Andrei Alexandrescu


 aa.keys is taken btw.

OK, I see, .keys and .values currently return dynamic arrays. But the most appropriate property name for the above range should indeed be .keys ! Now, wouldn't it be be better to turn .keys into the proposed range? Let's see. What is the use of .keys? I searched phobos and found that .keys is mostly used to itarate over the keys in a foreach loop. With the problem that is needs to allocate a dynamic array. If silently changed to the proposed range, the foreach loop would do the same and without an allocation. In a few unittests, .keys is followed by .sort, usually to print the keys in order. That would not work... unless the produced range includes a .sort method. Alternatively a .sortedKeys property can be added. The other use I see in phobos is just a typeof(a.keys[0]), which could be replaced by typeof(a.keys.front) What is the benefit of .keys as a range? it does not allocate an array, just gives the keys. And if an array is needed, it is easy to turn a range into an array. [Well, I'm missing a more direct way of doing that than using foreach and appending]
Jan 17 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/17/2012 11:19 PM, Alvaro wrote:
 El 17/01/2012 18:24, Andrei Alexandrescu escribió:
 On 2012-01-17 06:48:26 +0000, Andrei Alexandrescu


 aa.keys is taken btw.

OK, I see, .keys and .values currently return dynamic arrays. But the most appropriate property name for the above range should indeed be .keys ! Now, wouldn't it be be better to turn .keys into the proposed range? Let's see. What is the use of .keys? I searched phobos and found that .keys is mostly used to itarate over the keys in a foreach loop. With the problem that is needs to allocate a dynamic array. If silently changed to the proposed range, the foreach loop would do the same and without an allocation. In a few unittests, .keys is followed by .sort, usually to print the keys in order. That would not work... unless the produced range includes a .sort method. Alternatively a .sortedKeys property can be added. The other use I see in phobos is just a typeof(a.keys[0]), which could be replaced by typeof(a.keys.front) What is the benefit of .keys as a range? it does not allocate an array, just gives the keys. And if an array is needed, it is easy to turn a range into an array. [Well, I'm missing a more direct way of doing that than using foreach and appending]

See std.array.array.
Jan 17 2012
parent reply Alvaro <alvaroDotSegura gmail.com> writes:
El 17/01/2012 23:32, Timon Gehr escribió:
 On 01/17/2012 11:19 PM, Alvaro wrote:
 El 17/01/2012 18:24, Andrei Alexandrescu escribió:
 On 2012-01-17 06:48:26 +0000, Andrei Alexandrescu


 aa.keys is taken btw.

OK, I see, .keys and .values currently return dynamic arrays. But the most appropriate property name for the above range should indeed be .keys ! Now, wouldn't it be be better to turn .keys into the proposed range? Let's see. What is the use of .keys? I searched phobos and found that .keys is mostly used to itarate over the keys in a foreach loop. With the problem that is needs to allocate a dynamic array. If silently changed to the proposed range, the foreach loop would do the same and without an allocation. In a few unittests, .keys is followed by .sort, usually to print the keys in order. That would not work... unless the produced range includes a .sort method. Alternatively a .sortedKeys property can be added. The other use I see in phobos is just a typeof(a.keys[0]), which could be replaced by typeof(a.keys.front) What is the benefit of .keys as a range? it does not allocate an array, just gives the keys. And if an array is needed, it is easy to turn a range into an array. [Well, I'm missing a more direct way of doing that than using foreach and appending]

See std.array.array.

Oops. Yes, thanks. So, not bad. In those [infrequent, I'd say] cases needing an array one would do: auto keys = array(aa.keys); even: (unsure if this would work, but somethig similar maybe) foreach(k; array(aa.keys).sort) { ... use the ordered keys }
Jan 17 2012
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Alvaro:

 So, not bad. In those [infrequent, I'd say] cases needing an array one 
 would do:
 
   auto keys = array(aa.keys);

Unfortunately in D you often need arrays, so those cases are frequent.
 even: (unsure if this would work, but somethig similar maybe)
 
   foreach(k; array(aa.keys).sort)
   {
      ... use the ordered keys
   }

sort property is deprecated (or going to be). Bye, bearophile
Jan 17 2012
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Alvaro" <alvaroDotSegura gmail.com> wrote in message 
news:jf4tr4$lnv$1 digitalmars.com...
 El 17/01/2012 23:32, Timon Gehr escribió:
 On 01/17/2012 11:19 PM, Alvaro wrote:
 El 17/01/2012 18:24, Andrei Alexandrescu escribió:
 On 2012-01-17 06:48:26 +0000, Andrei Alexandrescu


 aa.keys is taken btw.

OK, I see, .keys and .values currently return dynamic arrays. But the most appropriate property name for the above range should indeed be .keys ! Now, wouldn't it be be better to turn .keys into the proposed range? Let's see. What is the use of .keys? I searched phobos and found that .keys is mostly used to itarate over the keys in a foreach loop. With the problem that is needs to allocate a dynamic array. If silently changed to the proposed range, the foreach loop would do the same and without an allocation. In a few unittests, .keys is followed by .sort, usually to print the keys in order. That would not work... unless the produced range includes a .sort method. Alternatively a .sortedKeys property can be added. The other use I see in phobos is just a typeof(a.keys[0]), which could be replaced by typeof(a.keys.front) What is the benefit of .keys as a range? it does not allocate an array, just gives the keys. And if an array is needed, it is easy to turn a range into an array. [Well, I'm missing a more direct way of doing that than using foreach and appending]

See std.array.array.

Oops. Yes, thanks. So, not bad. In those [infrequent, I'd say] cases needing an array one would do: auto keys = array(aa.keys);

My thoughts exactly. The current .keys made sense back in the days before ranges, std.algorithm, etc, but not so much anymore. Vote++
Jan 17 2012
next sibling parent deadalnix <deadalnix gmail.com> writes:
Le 18/01/2012 01:02, Nick Sabalausky a écrit :
 "Alvaro"<alvaroDotSegura gmail.com>  wrote in message
 news:jf4tr4$lnv$1 digitalmars.com...
 El 17/01/2012 23:32, Timon Gehr escribi�:
 On 01/17/2012 11:19 PM, Alvaro wrote:
 El 17/01/2012 18:24, Andrei Alexandrescu escribi�:
 On 2012-01-17 06:48:26 +0000, Andrei Alexandrescu


 aa.keys is taken btw.

OK, I see, .keys and .values currently return dynamic arrays. But the most appropriate property name for the above range should indeed be .keys ! Now, wouldn't it be be better to turn .keys into the proposed range? Let's see. What is the use of .keys? I searched phobos and found that .keys is mostly used to itarate over the keys in a foreach loop. With the problem that is needs to allocate a dynamic array. If silently changed to the proposed range, the foreach loop would do the same and without an allocation. In a few unittests, .keys is followed by .sort, usually to print the keys in order. That would not work... unless the produced range includes a .sort method. Alternatively a .sortedKeys property can be added. The other use I see in phobos is just a typeof(a.keys[0]), which could be replaced by typeof(a.keys.front) What is the benefit of .keys as a range? it does not allocate an array, just gives the keys. And if an array is needed, it is easy to turn a range into an array. [Well, I'm missing a more direct way of doing that than using foreach and appending]

See std.array.array.

Oops. Yes, thanks. So, not bad. In those [infrequent, I'd say] cases needing an array one would do: auto keys = array(aa.keys);

My thoughts exactly. The current .keys made sense back in the days before ranges, std.algorithm, etc, but not so much anymore. Vote++

++ here. keys is the perfect name for that stuff.
Jan 18 2012
prev sibling parent =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <xtzgzorex gmail.com> writes:
On 18-01-2012 01:02, Nick Sabalausky wrote:
 "Alvaro"<alvaroDotSegura gmail.com>  wrote in message
 news:jf4tr4$lnv$1 digitalmars.com...
 El 17/01/2012 23:32, Timon Gehr escribió:
 On 01/17/2012 11:19 PM, Alvaro wrote:
 El 17/01/2012 18:24, Andrei Alexandrescu escribió:
 On 2012-01-17 06:48:26 +0000, Andrei Alexandrescu


 aa.keys is taken btw.

OK, I see, .keys and .values currently return dynamic arrays. But the most appropriate property name for the above range should indeed be .keys ! Now, wouldn't it be be better to turn .keys into the proposed range? Let's see. What is the use of .keys? I searched phobos and found that .keys is mostly used to itarate over the keys in a foreach loop. With the problem that is needs to allocate a dynamic array. If silently changed to the proposed range, the foreach loop would do the same and without an allocation. In a few unittests, .keys is followed by .sort, usually to print the keys in order. That would not work... unless the produced range includes a .sort method. Alternatively a .sortedKeys property can be added. The other use I see in phobos is just a typeof(a.keys[0]), which could be replaced by typeof(a.keys.front) What is the benefit of .keys as a range? it does not allocate an array, just gives the keys. And if an array is needed, it is easy to turn a range into an array. [Well, I'm missing a more direct way of doing that than using foreach and appending]

See std.array.array.

Oops. Yes, thanks. So, not bad. In those [infrequent, I'd say] cases needing an array one would do: auto keys = array(aa.keys);

My thoughts exactly. The current .keys made sense back in the days before ranges, std.algorithm, etc, but not so much anymore. Vote++

Vote++ from me as well. -- - Alex
Jan 18 2012
prev sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 17 Jan 2012 19:02:03 -0500, Nick Sabalausky <a a.a> wrote:

 "Alvaro" <alvaroDotSegura gmail.com> wrote in message

 Oops. Yes, thanks.

 So, not bad. In those [infrequent, I'd say] cases needing an array one
 would do:

  auto keys = array(aa.keys);

My thoughts exactly. The current .keys made sense back in the days before ranges, std.algorithm, etc, but not so much anymore. Vote++

There is one significant problem with changing aa.keys to be a lazy range instead of an array. This is valid code (and does exist in the wild): foreach(k; aa.keys) { if(shouldRemove(k)) aa.remove(k); } This would silently start crashing programs if we changed the behavior of keys. I don't see any way around this... -Steve
Jan 18 2012
parent bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:

 There is one significant problem with changing aa.keys to be a lazy range  
 instead of an array.  This is valid code (and does exist in the wild):
 
 foreach(k; aa.keys)
 {
     if(shouldRemove(k))
        aa.remove(k);
 }
 
 This would silently start crashing programs if we changed the behavior of  
 keys.

On this topic see also: http://d.puremagic.com/issues/show_bug.cgi?id=4179 Bye, bearophile
Jan 18 2012
prev sibling next sibling parent =?utf-8?Q?Simen_Kj=C3=A6r=C3=A5s?= <simen.kjaras gmail.com> writes:
On Tue, 17 Jan 2012 07:48:26 +0100, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }



 Thanks,

 Andrei "I told you" Alexandrescu

Property.
Jan 17 2012
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/17/2012 07:48 AM, Andrei Alexandrescu wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }



 Thanks,

 Andrei "I told you" Alexandrescu

IMO it does not matter. I think we should just deprecate the -property switch instead of engaging into that kind of fruitless discussion every now and then. ;)
Jan 17 2012
next sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, January 17, 2012 19:38:47 Timon Gehr wrote:
 IMO it does not matter. I think we should just deprecate the -property
 switch instead of engaging into that kind of fruitless discussion every
 now and then. ;)

Then we might as well throw out property and change TDPL. There's no point to property without enforcement. I think that that ship has pretty much sailed already. - Jonathan M Davis
Jan 17 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/17/2012 07:55 PM, Jonathan M Davis wrote:
 On Tuesday, January 17, 2012 19:38:47 Timon Gehr wrote:
 IMO it does not matter. I think we should just deprecate the -property
 switch instead of engaging into that kind of fruitless discussion every
 now and then. ;)

Then we might as well throw out property and change TDPL. There's no point to property without enforcement. I think that that ship has pretty much sailed already. - Jonathan M Davis

Since -property is optional I think the relevant ships are still in the haven.
Jan 17 2012
parent reply Peter Alexander <peter.alexander.au gmail.com> writes:
On 17/01/12 10:11 PM, Jonathan M Davis wrote:
 You would need to come up with some really solid arguments why it should be
 thrown out (and what we should do instead) and get both Walter and Andrei (if
 not the community at large) to agree that they not only prefer your proposal
 but that it's worth the issues that the changes are going to cause at this
 stage.

There's a few good reasons to throw it out: 1. Avoids pointless discussions like this one. These discussions add nothing, it's just mindless bike shedding. 2. The -property flag *creates* a new kind of error, but doesn't actually help find real problems with your code. Without properties, member function access would always be a.b(), and this artificial error could be avoided. 3. Properties introduce another thing to remember, with no value ("was it byKeys, or byKeys()?"). Without properties, it would be byKeys(). No need to remember. 4. Properties obfuscate code. Is (a.b = c) a variable assignment or arbitrary function call? Who knows! Is a.b an actual variable? Can I write &a.b to get its address, or is it a function masquerading as a variable? 5. One less language feature to implement, learn, document, debug, and discuss. Is it practical or realistic to throw it out at this stage? I don't know. But there are reasons to.
Jan 17 2012
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/17/12 5:13 PM, Peter Alexander wrote:
 On 17/01/12 10:11 PM, Jonathan M Davis wrote:
 You would need to come up with some really solid arguments why it
 should be
 thrown out (and what we should do instead) and get both Walter and
 Andrei (if
 not the community at large) to agree that they not only prefer your
 proposal
 but that it's worth the issues that the changes are going to cause at
 this
 stage.

There's a few good reasons to throw it out: 1. Avoids pointless discussions like this one. These discussions add nothing, it's just mindless bike shedding.

Yes.
 2. The -property flag *creates* a new kind of error, but doesn't
 actually help find real problems with your code. Without properties,
 member function access would always be a.b(), and this artificial error
 could be avoided.

Yes! I can't believe we have a check that has _zero_ contribution to improving code.
 3. Properties introduce another thing to remember, with no value ("was
 it byKeys, or byKeys()?"). Without properties, it would be byKeys(). No
 need to remember.

YES!!!
 4. Properties obfuscate code. Is (a.b = c) a variable assignment or
 arbitrary function call? Who knows! Is a.b an actual variable? Can I
 write &a.b to get its address, or is it a function masquerading as a
 variable?

Hm, actually that's not bad.
 5. One less language feature to implement, learn, document, debug, and
 discuss.

Back to yes.
 Is it practical or realistic to throw it out at this stage? I don't
 know. But there are reasons to.

Me neither. If I had my way I'd carefully redo the feature to only require property on rare cases that would otherwise be ambiguous, and make parens optional everywhere else. Andrei
Jan 17 2012
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/18/12 7:44 AM, Steven Schveighoffer wrote:
 The solution is easy, just don't start the discussion. Make a decision
 (property or no), and that's the end of it. My intuition says that you
 will purposely make the *wrong* choice just to try and get others to
 complain so you can "be right".

Well in this case I am right :o). We did a poor job at designing properties. Anyhow, I honestly asked simply because I found no clear cut decision. My intuition was that byXxx should be a property but I asked Walter whose intuition said it should be a method. So we agreed to ask the newsgroup.
 The point of required property semantics is that the name of the
 function includes whether you need parentheses or not. a.empty does not
 have the same tone as a.empty(). The former looks like a field, the
 latter looks like an action. It's a subtle bikeshed issue, but so is
 naming functions anyways!

Yes, but the problem is this adds additional bikeshedding for no benefit.
 If you think the names of things aren't
 important, name them whatever you want, but at least you as the author
 get to choose instead of the user.

I understand this point. It doesn't reduce the frustration that we have a feature that does not palpably improve the language.
 And if I may add my opinion, byValue and byKey are properties.

I agree. The current code has them as properties. My thoughts are, a property should reasonably replace a member variable (of which syntax it mimics). So x.length should be property, x.dup shouldn't. Now byXxx can be considered member variables but only as long as it's not considered an lvalue: r.byKey.popFront() does nothing interesting, but would do if r.byKey were actually a member variable. I think that distinction still does not impair byXxx's right to be a property. Andrei
Jan 18 2012
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/18/12 8:34 AM, Steven Schveighoffer wrote:
 On Wed, 18 Jan 2012 09:13:37 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 1/18/12 7:44 AM, Steven Schveighoffer wrote:
 The solution is easy, just don't start the discussion. Make a decision
 (property or no), and that's the end of it. My intuition says that you
 will purposely make the *wrong* choice just to try and get others to
 complain so you can "be right".

Well in this case I am right :o). We did a poor job at designing properties. Anyhow, I honestly asked simply because I found no clear cut decision. My intuition was that byXxx should be a property but I asked Walter whose intuition said it should be a method. So we agreed to ask the newsgroup.

Then I withdraw the "being spiteful" suggestion, it was probably unfair. But the "I told you" didn't set the tone very well for this discussion :)

Indeed I told you all! Every time we add anything, there's going to be sh... stuff like this.
 I understand this point. It doesn't reduce the frustration that we
 have a feature that does not palpably improve the language.

Disagree on both points :) property with enforcement is the right answer, it improves the language significantly, bringing it in line with most other property-enabled C-like languages.

This is not an argument. It's good because it's like in other languages where it's supposed to be good. And it's not "the right answer" when there's nothing to be answered.
 And if I may add my opinion, byValue and byKey are properties.

I agree. The current code has them as properties. My thoughts are, a property should reasonably replace a member variable (of which syntax it mimics). So x.length should be property, x.dup shouldn't. Now byXxx can be considered member variables but only as long as it's not considered an lvalue: r.byKey.popFront() does nothing interesting, but would do if r.byKey were actually a member variable. I think that distinction still does not impair byXxx's right to be a property.

I think the difference between what should be a property and what shouldn't is not black and white. There is no easy way to define it.

If that's the case, then there shouldn't be a black-and-white distinction in the language about it.
 The best I can come up with is, if it gets something that is logically a
 piece of the object, then it should be a property (even if it makes a
 copy of that something). If it creates something separate from the
 object, or modifies the object, it should be a method.

The fact that reasonable people disagree, and that choosing one way or another has zero impact on the quality of the code, makes this feature a costly mistake. Andrei
Jan 18 2012
prev sibling parent Ary Manzana <ary esperanto.org.ar> writes:
On 1/17/12 8:29 PM, Andrei Alexandrescu wrote:
 On 1/17/12 5:13 PM, Peter Alexander wrote:
 On 17/01/12 10:11 PM, Jonathan M Davis wrote:
 You would need to come up with some really solid arguments why it
 should be
 thrown out (and what we should do instead) and get both Walter and
 Andrei (if
 not the community at large) to agree that they not only prefer your
 proposal
 but that it's worth the issues that the changes are going to cause at
 this
 stage.

There's a few good reasons to throw it out: 1. Avoids pointless discussions like this one. These discussions add nothing, it's just mindless bike shedding.

Yes.
 2. The -property flag *creates* a new kind of error, but doesn't
 actually help find real problems with your code. Without properties,
 member function access would always be a.b(), and this artificial error
 could be avoided.

Yes! I can't believe we have a check that has _zero_ contribution to improving code.
 3. Properties introduce another thing to remember, with no value ("was
 it byKeys, or byKeys()?"). Without properties, it would be byKeys(). No
 need to remember.

YES!!!
 4. Properties obfuscate code. Is (a.b = c) a variable assignment or
 arbitrary function call? Who knows! Is a.b an actual variable? Can I
 write &a.b to get its address, or is it a function masquerading as a
 variable?

Hm, actually that's not bad.
 5. One less language feature to implement, learn, document, debug, and
 discuss.

Back to yes.
 Is it practical or realistic to throw it out at this stage? I don't
 know. But there are reasons to.

Me neither. If I had my way I'd carefully redo the feature to only require property on rare cases that would otherwise be ambiguous, and make parens optional everywhere else. Andrei

Before I knew Ruby I was in favor of property. Now I'm against it.
Jan 19 2012
prev sibling next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Peter Alexander" <peter.alexander.au gmail.com> wrote in message 
news:jf4ull$n6b$1 digitalmars.com...
 On 17/01/12 10:11 PM, Jonathan M Davis wrote:
 You would need to come up with some really solid arguments why it should 
 be
 thrown out (and what we should do instead) and get both Walter and Andrei 
 (if
 not the community at large) to agree that they not only prefer your 
 proposal
 but that it's worth the issues that the changes are going to cause at 
 this
 stage.

There's a few good reasons to throw it out: 1. Avoids pointless discussions like this one. These discussions add nothing, it's just mindless bike shedding.

Andrei's the only one that ever starts any of this "Is this a property or func?!?" nonsense, because he's been against the distinction from the start. We finally got him to give in due to the delegate ambiguity, and he's been bitching about it at every opportinity since.
 2. The -property flag *creates* a new kind of error, but doesn't actually 
 help find real problems with your code. Without properties, member 
 function access would always be a.b(), and this artificial error could be 
 avoided.

Bullshit. Without properties, member function access *ANY* many value accesses are "a.b()". Is this member value a plain-old-var or a function? Who knows! It's a leeked out implementation detail, hooray!
 3. Properties introduce another thing to remember, with no value ("was it 
 byKeys, or byKeys()?"). Without properties, it would be byKeys(). No need 
 to remember.

Of *course* there's a need to remember useless shit: There's a need to remember that it's implemented as a function and not just simply as a member variable. In this *particular* case it may be a little easier since we know it returns range, but what about "aa.keys"? What about every other property out there?
 4. Properties obfuscate code. Is (a.b = c) a variable assignment or 
 arbitrary function call? Who knows! Is a.b an actual variable?

Who the hell cares? The whole damn *point* is that you don't have to give a shit about the member's implementation on *every* fucking member access. If you want transparency, use assembler.
 Can I write &a.b to get its address, or is it a function masquerading as a 
 variable?

That's only an issue when you actually want to take the address of something (and there are ways to improve that situation anyway). But forcing every property to be used as if it were a function instead of data access forces the user to figure out how it's implemented *EVERY* time it's accessed.
 5. One less language feature to implement, learn, document, debug, and 
 discuss.

So we're taking the Java/JavaScript/Brainfuck route of "minimal language == good langauge" now?
 Is it practical or realistic to throw it out at this stage?

I wouldn't think so even if I wanted them gone.
 I don't know. But there are reasons to.

No there aren't. The only reason to throw it out is that Andrei keeps whining and moaning about it just because it's something he can't/won't grok. But being that he's Andrei, that just might end up being enough of a reason, which is why I'm so insistent about the matter.
Jan 17 2012
next sibling parent "Nick Sabalausky" <a a.a> writes:
"Nick Sabalausky" <a a.a> wrote in message 
news:jf53c2$u86$1 digitalmars.com...
 "Peter Alexander" <peter.alexander.au gmail.com> wrote in message 
 news:jf4ull$n6b$1 digitalmars.com...
 2. The -property flag *creates* a new kind of error, but doesn't actually 
 help find real problems with your code. Without properties, member 
 function access would always be a.b(), and this artificial error could be 
 avoided.

Bullshit. Without properties, member function access *ANY* many value accesses are "a.b()". Is this member value a plain-old-var or a function? Who knows! It's a leeked out implementation detail, hooray!

Obviously, I need to re-proofread *after* I edit... ;) The: "...member function access *ANY* many..." Should be: "...member function accesses *AND* many..." (Little less grammatically non-sensical that way ;) )
Jan 17 2012
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Nick Sabalausky:

 Without properties, member function access *ANY* many value 
 accesses are "a.b()". Is this member value a plain-old-var or a function? 
 Who knows! It's a leeked out implementation detail, hooray!

I have a partially related question. Currently this code compiles even with -property: void main() { int[int] aa = [1:2]; auto byval = aa.byValue(); } But I think byValue is a property, so isn't it right to give a compilation error if you add () after the name of a property? ----------------- By the way, I have just seen this code gives a Access Violation, I think it's a bug for Bugzilla: void main() { int[int] aa; auto byval = aa.byValue(); } Bye, bearophile
Jan 17 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/18/2012 01:40 AM, Jonathan M Davis wrote:
 On Tuesday, January 17, 2012 19:31:25 bearophile wrote:
 Nick Sabalausky:
 Without properties, member function access *ANY* many value
 accesses are "a.b()". Is this member value a plain-old-var or a
 function?
 Who knows! It's a leeked out implementation detail, hooray!

I have a partially related question. Currently this code compiles even with -property: void main() { int[int] aa = [1:2]; auto byval = aa.byValue(); } But I think byValue is a property, so isn't it right to give a compilation error if you add () after the name of a property?

Definitely a bug. Strict enforcement requires that parens be used on all function calls and that no properties use parens. If you use parens on them, that would mean that you're using them on the return value of the property (e.g. opCall) - and in fact, that's one of the main reasons that property was added in the first place, since without enforcement, property functions which return a delegate result in an ambiguity. - Jonathan M Davis

A related and way more embarrassing problem is that lazy function parameters have the same issue. This program prints nothing: import std.stdio; void foo(lazy void delegate() dg){ dg(); } void main(){ foo({writeln("hello");}); }
Jan 17 2012
parent reply Peter Alexander <peter.alexander.au gmail.com> writes:
On 18/01/12 12:52 AM, Timon Gehr wrote:
 On 01/18/2012 01:40 AM, Jonathan M Davis wrote:
 On Tuesday, January 17, 2012 19:31:25 bearophile wrote:
 Nick Sabalausky:
 Without properties, member function access *ANY* many value
 accesses are "a.b()". Is this member value a plain-old-var or a
 function?
 Who knows! It's a leeked out implementation detail, hooray!

I have a partially related question. Currently this code compiles even with -property: void main() { int[int] aa = [1:2]; auto byval = aa.byValue(); } But I think byValue is a property, so isn't it right to give a compilation error if you add () after the name of a property?

Definitely a bug. Strict enforcement requires that parens be used on all function calls and that no properties use parens. If you use parens on them, that would mean that you're using them on the return value of the property (e.g. opCall) - and in fact, that's one of the main reasons that property was added in the first place, since without enforcement, property functions which return a delegate result in an ambiguity. - Jonathan M Davis

A related and way more embarrassing problem is that lazy function parameters have the same issue. This program prints nothing: import std.stdio; void foo(lazy void delegate() dg){ dg(); } void main(){ foo({writeln("hello");}); }

Perhaps I'm wrong, but this issue is different. The code you have written is something that would be written by someone that doesn't understand how lazy works. You have to use () to un-lazy it, and then () again to invoke the delegate. There is no ambiguity like there is with property delegates.
Jan 18 2012
next sibling parent reply =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= <xtzgzorex gmail.com> writes:
On 19-01-2012 01:41, Peter Alexander wrote:
 On 18/01/12 12:52 AM, Timon Gehr wrote:
 On 01/18/2012 01:40 AM, Jonathan M Davis wrote:
 On Tuesday, January 17, 2012 19:31:25 bearophile wrote:
 Nick Sabalausky:
 Without properties, member function access *ANY* many value
 accesses are "a.b()". Is this member value a plain-old-var or a
 function?
 Who knows! It's a leeked out implementation detail, hooray!

I have a partially related question. Currently this code compiles even with -property: void main() { int[int] aa = [1:2]; auto byval = aa.byValue(); } But I think byValue is a property, so isn't it right to give a compilation error if you add () after the name of a property?

Definitely a bug. Strict enforcement requires that parens be used on all function calls and that no properties use parens. If you use parens on them, that would mean that you're using them on the return value of the property (e.g. opCall) - and in fact, that's one of the main reasons that property was added in the first place, since without enforcement, property functions which return a delegate result in an ambiguity. - Jonathan M Davis

A related and way more embarrassing problem is that lazy function parameters have the same issue. This program prints nothing: import std.stdio; void foo(lazy void delegate() dg){ dg(); } void main(){ foo({writeln("hello");}); }

Perhaps I'm wrong, but this issue is different. The code you have written is something that would be written by someone that doesn't understand how lazy works. You have to use () to un-lazy it, and then () again to invoke the delegate. There is no ambiguity like there is with property delegates.

But couldn't that be considered leaking an implementation detail of lazy values? Or is this intentional design? -- - Alex
Jan 18 2012
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/19/2012 01:38 AM, Alex Rønne Petersen wrote:
 On 19-01-2012 01:41, Peter Alexander wrote:
 On 18/01/12 12:52 AM, Timon Gehr wrote:
 On 01/18/2012 01:40 AM, Jonathan M Davis wrote:
 On Tuesday, January 17, 2012 19:31:25 bearophile wrote:
 Nick Sabalausky:
 Without properties, member function access *ANY* many value
 accesses are "a.b()". Is this member value a plain-old-var or a
 function?
 Who knows! It's a leeked out implementation detail, hooray!

I have a partially related question. Currently this code compiles even with -property: void main() { int[int] aa = [1:2]; auto byval = aa.byValue(); } But I think byValue is a property, so isn't it right to give a compilation error if you add () after the name of a property?

Definitely a bug. Strict enforcement requires that parens be used on all function calls and that no properties use parens. If you use parens on them, that would mean that you're using them on the return value of the property (e.g. opCall) - and in fact, that's one of the main reasons that property was added in the first place, since without enforcement, property functions which return a delegate result in an ambiguity. - Jonathan M Davis

A related and way more embarrassing problem is that lazy function parameters have the same issue. This program prints nothing: import std.stdio; void foo(lazy void delegate() dg){ dg(); } void main(){ foo({writeln("hello");}); }

Perhaps I'm wrong, but this issue is different. The code you have written is something that would be written by someone that doesn't understand how lazy works. You have to use () to un-lazy it, and then () again to invoke the delegate. There is no ambiguity like there is with property delegates.

But couldn't that be considered leaking an implementation detail of lazy values? Or is this intentional design?

I suppose it is an implementation relic.
Jan 18 2012
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/19/2012 01:52 AM, Jonathan M Davis wrote:
 On Thursday, January 19, 2012 01:38:23 Alex Rønne Petersen wrote:
 But couldn't that be considered leaking an implementation detail of lazy
 values? Or is this intentional design?

The language requires that lazy parameters be accessed with (). That leaks the fact that the variable is lazy into the function body, but whether it leaks how lazy parameters are implemented is debatable. The same syntax could be used with a different implementation underneath the hood. But the fact that you have to use double parens on a lazy delegate isn't leaking any kind of implemenatation detail. It's the natural extension of the syntax for lazy. var() gives you the value of the lazy parameter var, and so if you want to call var (or use opCall or it), then you need another set of parens - var()(). Whether requiring parens on lazy parameters is a good design decision is debatable,

They are only required if you want to call a lazy delegate/function pointer. They are optional in all other cases.
 but I don't see any leaking of implementation details in it. The
 syntax chosen was probably chosen because it's implemented with a delegate,
 but the fact that it's implemented with a delegate is still an implementation
 detail which could theoretically be changed.

Jan 18 2012
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/19/2012 01:41 AM, Peter Alexander wrote:
 On 18/01/12 12:52 AM, Timon Gehr wrote:
 On 01/18/2012 01:40 AM, Jonathan M Davis wrote:
 On Tuesday, January 17, 2012 19:31:25 bearophile wrote:
 Nick Sabalausky:
 Without properties, member function access *ANY* many value
 accesses are "a.b()". Is this member value a plain-old-var or a
 function?
 Who knows! It's a leeked out implementation detail, hooray!

I have a partially related question. Currently this code compiles even with -property: void main() { int[int] aa = [1:2]; auto byval = aa.byValue(); } But I think byValue is a property, so isn't it right to give a compilation error if you add () after the name of a property?

Definitely a bug. Strict enforcement requires that parens be used on all function calls and that no properties use parens. If you use parens on them, that would mean that you're using them on the return value of the property (e.g. opCall) - and in fact, that's one of the main reasons that property was added in the first place, since without enforcement, property functions which return a delegate result in an ambiguity. - Jonathan M Davis

A related and way more embarrassing problem is that lazy function parameters have the same issue. This program prints nothing: import std.stdio; void foo(lazy void delegate() dg){ dg(); } void main(){ foo({writeln("hello");}); }

Perhaps I'm wrong, but this issue is different. The code you have written is something that would be written by someone that doesn't understand how lazy works.

It is written by someone who understands how it should work.
 You have to use () to un-lazy

What would 'un-lazying' be and what is supposed to be its effect?
 it, and then () again to invoke the delegate. There is no ambiguity like
 there is with property delegates.

The code has exactly the same semantics whether or not you write the parens after a lazy variable except for the case when it is a delegate or function pointer.
Jan 18 2012
parent reply Peter Alexander <peter.alexander.au gmail.com> writes:
On 19/01/12 12:51 AM, Timon Gehr wrote:
 On 01/19/2012 01:41 AM, Peter Alexander wrote:
 On 18/01/12 12:52 AM, Timon Gehr wrote:
 On 01/18/2012 01:40 AM, Jonathan M Davis wrote:
 On Tuesday, January 17, 2012 19:31:25 bearophile wrote:
 Nick Sabalausky:
 Without properties, member function access *ANY* many value
 accesses are "a.b()". Is this member value a plain-old-var or a
 function?
 Who knows! It's a leeked out implementation detail, hooray!

I have a partially related question. Currently this code compiles even with -property: void main() { int[int] aa = [1:2]; auto byval = aa.byValue(); } But I think byValue is a property, so isn't it right to give a compilation error if you add () after the name of a property?

Definitely a bug. Strict enforcement requires that parens be used on all function calls and that no properties use parens. If you use parens on them, that would mean that you're using them on the return value of the property (e.g. opCall) - and in fact, that's one of the main reasons that property was added in the first place, since without enforcement, property functions which return a delegate result in an ambiguity. - Jonathan M Davis

A related and way more embarrassing problem is that lazy function parameters have the same issue. This program prints nothing: import std.stdio; void foo(lazy void delegate() dg){ dg(); } void main(){ foo({writeln("hello");}); }

Perhaps I'm wrong, but this issue is different. The code you have written is something that would be written by someone that doesn't understand how lazy works.

It is written by someone who understands how it should work.
 You have to use () to un-lazy

What would 'un-lazying' be and what is supposed to be its effect?

Under the hood, lazy is just a delegate with different syntax. void foo(lazy int x) {} int a; foo(a++); Essentially translates to: void foo(int delegate() x) {} int a; foo( { return a++; } ); Inside foo, you have to do x() to evaluate the delegate, just like normals delegates. x on its own without parens would just be the delegate variable. If you had a lazy delegate parameter then that is like a delegate that returns a delegate, so you have to do x()() to evaluate the returned delegate.
 it, and then () again to invoke the delegate. There is no ambiguity like
 there is with property delegates.

The code has exactly the same semantics whether or not you write the parens after a lazy variable except for the case when it is a delegate or function pointer.

I was not aware of this. I believe this is a bug (or at least a design flaw).
Jan 19 2012
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 01/19/2012 03:47 PM, Peter Alexander wrote:
 On 19/01/12 12:51 AM, Timon Gehr wrote:
 On 01/19/2012 01:41 AM, Peter Alexander wrote:
 On 18/01/12 12:52 AM, Timon Gehr wrote:
 On 01/18/2012 01:40 AM, Jonathan M Davis wrote:
 On Tuesday, January 17, 2012 19:31:25 bearophile wrote:
 Nick Sabalausky:
 Without properties, member function access *ANY* many value
 accesses are "a.b()". Is this member value a plain-old-var or a
 function?
 Who knows! It's a leeked out implementation detail, hooray!

I have a partially related question. Currently this code compiles even with -property: void main() { int[int] aa = [1:2]; auto byval = aa.byValue(); } But I think byValue is a property, so isn't it right to give a compilation error if you add () after the name of a property?

Definitely a bug. Strict enforcement requires that parens be used on all function calls and that no properties use parens. If you use parens on them, that would mean that you're using them on the return value of the property (e.g. opCall) - and in fact, that's one of the main reasons that property was added in the first place, since without enforcement, property functions which return a delegate result in an ambiguity. - Jonathan M Davis

A related and way more embarrassing problem is that lazy function parameters have the same issue. This program prints nothing: import std.stdio; void foo(lazy void delegate() dg){ dg(); } void main(){ foo({writeln("hello");}); }

Perhaps I'm wrong, but this issue is different. The code you have written is something that would be written by someone that doesn't understand how lazy works.

It is written by someone who understands how it should work.
 You have to use () to un-lazy

What would 'un-lazying' be and what is supposed to be its effect?

Under the hood, lazy is just a delegate with different syntax.

It is more than that, type checking works differently for lazy values compared to scoped delegates.
 void foo(lazy int x) {}
 int a;
 foo(a++);

 Essentially translates to:

 void foo(int delegate() x) {}
 int a;
 foo( { return a++; } );

 Inside foo, you have to do x() to evaluate the delegate, just like
 normals delegates. x on its own without parens would just be the
 delegate variable. If you had a lazy delegate parameter then that is
 like a delegate that returns a delegate, so you have to do x()() to
 evaluate the returned delegate.

I know what is under the hood, but I don't really care. Lazy is just another storage class, and as such it has no business changing the syntax using which the value is accessed.
 it, and then () again to invoke the delegate. There is no ambiguity like
 there is with property delegates.

The code has exactly the same semantics whether or not you write the parens after a lazy variable except for the case when it is a delegate or function pointer.

I was not aware of this. I believe this is a bug (or at least a design flaw).

Parens should be removed completely from lazy values. They don't add a lot while being inconsistent with how other STCs work.
Jan 19 2012
prev sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, January 19, 2012 18:33:15 Timon Gehr wrote:
 Parens should be removed completely from lazy values. They don't add a
 lot while being inconsistent with how other STCs work.

Ignoring the fact that this will break code, I completely agree. However, given the fact that it's going to break code, I question that you we could get Walter to agree. It would definitely lead to the language being more consistent though. - Jonathan M Davis
Jan 19 2012
prev sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, January 19, 2012 01:38:23 Alex Rønne Petersen wrote:
 But couldn't that be considered leaking an implementation detail of lazy
 values? Or is this intentional design?

The language requires that lazy parameters be accessed with (). That leaks the fact that the variable is lazy into the function body, but whether it leaks how lazy parameters are implemented is debatable. The same syntax could be used with a different implementation underneath the hood. But the fact that you have to use double parens on a lazy delegate isn't leaking any kind of implemenatation detail. It's the natural extension of the syntax for lazy. var() gives you the value of the lazy parameter var, and so if you want to call var (or use opCall or it), then you need another set of parens - var()(). Whether requiring parens on lazy parameters is a good design decision is debatable, but I don't see any leaking of implementation details in it. The syntax chosen was probably chosen because it's implemented with a delegate, but the fact that it's implemented with a delegate is still an implementation detail which could theoretically be changed. - Jonathan M Davis
Jan 18 2012
prev sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, January 17, 2012 19:31:25 bearophile wrote:
 Nick Sabalausky:
 Without properties, member function access *ANY* many value
 accesses are "a.b()". Is this member value a plain-old-var or a
 function?
 Who knows! It's a leeked out implementation detail, hooray!

I have a partially related question. Currently this code compiles even with -property: void main() { int[int] aa = [1:2]; auto byval = aa.byValue(); } But I think byValue is a property, so isn't it right to give a compilation error if you add () after the name of a property?

Definitely a bug. Strict enforcement requires that parens be used on all function calls and that no properties use parens. If you use parens on them, that would mean that you're using them on the return value of the property (e.g. opCall) - and in fact, that's one of the main reasons that property was added in the first place, since without enforcement, property functions which return a delegate result in an ambiguity. - Jonathan M Davis
Jan 17 2012
parent bearophile <bearophileHUGS lycos.com> writes:
Jonathan M Davis:

 Definitely a bug. Strict enforcement requires that parens be used on all 
 function calls and that no properties use parens.

I agree! I'll take a look in Bugzilla if this bug report is already present. Thank you for your answers :-) Bye, bearophile
Jan 17 2012
prev sibling parent reply sclytrack <sclytrack fake.com> writes:
 Is it practical or realistic to throw it out at this stage? I don't
 know. But there are reasons to.

I hope we are not dropping properties regardless of the syntax of how to call them. Keep property Keep methods-as-properties --------------------------------- (a) No () obj.property = "test"; string str = obj.property; obj.method = "string"; obj.method("first"); string str = obj.method; obj.method("first", "second"); --------------------------------- (b) Optional () for methods obj.property = "test"; string str = obj.property; obj.method = "string"; obj.method("first"); string str = obj.method; string str = obj.method(); obj.method("first", "second"); --------------------------------- (c) Mandatory () for methods obj.property = "test"; string str = obj.property; obj.method = "string"; obj.method("first"); string str = obj.method(); obj.method("first", "second"); --------------------------------- (d) Property and Method separated. (Is this the goal for -property?) obj.property = "test"; string str = obj.property; string str = obj.method(); obj.method("first"); obj.method("first", "second"); --------------------------------- Who likes (a) ? Also I think that the property opDispatch() looks weird.
Jan 18 2012
parent reply Jacob Carlborg <doob me.com> writes:
On 2012-01-18 09:30, sclytrack wrote:
 Is it practical or realistic to throw it out at this stage? I don't
 know. But there are reasons to.

I hope we are not dropping properties regardless of the syntax of how to call them. Keep property Keep methods-as-properties --------------------------------- (a) No () obj.property = "test"; string str = obj.property; obj.method = "string"; obj.method("first"); string str = obj.method; obj.method("first", "second"); --------------------------------- (b) Optional () for methods obj.property = "test"; string str = obj.property; obj.method = "string"; obj.method("first"); string str = obj.method; string str = obj.method(); obj.method("first", "second"); --------------------------------- (c) Mandatory () for methods obj.property = "test"; string str = obj.property; obj.method = "string"; obj.method("first"); string str = obj.method(); obj.method("first", "second"); --------------------------------- (d) Property and Method separated. (Is this the goal for -property?) obj.property = "test"; string str = obj.property; string str = obj.method(); obj.method("first"); obj.method("first", "second"); --------------------------------- Who likes (a) ? Also I think that the property opDispatch() looks weird.

I would like this: property: getter - parentheses are not allowed setter: * equal sign is required * parentheses are not allowed method: no parameters - parentheses are optional parameters: * parentheses are required * equal sign is not allowed Examples: obj.property; // legal obj.property = 1; // legal obj.property(); // error obj.property(1); // error obj.method; // legal obj.method(); // legal obj.method(1); // legal obj.method = 1; // error -- /Jacob Carlborg
Jan 18 2012
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2012-01-18 14:47, Steven Schveighoffer wrote:
 On Wed, 18 Jan 2012 07:33:45 -0500, Jacob Carlborg <doob me.com> wrote:

 On 2012-01-18 09:30, sclytrack wrote:
 Is it practical or realistic to throw it out at this stage? I don't
 know. But there are reasons to.

I hope we are not dropping properties regardless of the syntax of how to call them. Keep property Keep methods-as-properties --------------------------------- (a) No () obj.property = "test"; string str = obj.property; obj.method = "string"; obj.method("first"); string str = obj.method; obj.method("first", "second"); --------------------------------- (b) Optional () for methods obj.property = "test"; string str = obj.property; obj.method = "string"; obj.method("first"); string str = obj.method; string str = obj.method(); obj.method("first", "second"); --------------------------------- (c) Mandatory () for methods obj.property = "test"; string str = obj.property; obj.method = "string"; obj.method("first"); string str = obj.method(); obj.method("first", "second"); --------------------------------- (d) Property and Method separated. (Is this the goal for -property?) obj.property = "test"; string str = obj.property; string str = obj.method(); obj.method("first"); obj.method("first", "second"); --------------------------------- Who likes (a) ? Also I think that the property opDispatch() looks weird.

I would like this: property: getter - parentheses are not allowed setter: * equal sign is required * parentheses are not allowed method: no parameters - parentheses are optional parameters: * parentheses are required * equal sign is not allowed Examples: obj.property; // legal obj.property = 1; // legal obj.property(); // error obj.property(1); // error obj.method; // legal obj.method(); // legal obj.method(1); // legal obj.method = 1; // error

what about: int x = obj.method; // passes by your rules, but I think should be illegal

I could go either way with that one. But I think I prefer optional parentheses.
 I think the parentheses should only be optional on void-returning methods.

 Otherwise, I agree with your list.

 -Steve

-- /Jacob Carlborg
Jan 18 2012
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Jacob Carlborg" <doob me.com> wrote in message 
news:jf6e7a$1929$1 digitalmars.com...
 method:
 no parameters - parentheses are optional

FWIW, I always do a double-take when I see code like: functionName; //or object.functionName; It sets off all mannar of "no-effect expression!" bells and buzzers in my head every time I look at it, which I then have to silence.
Jan 18 2012
next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Nick Sabalausky" <a a.a> wrote in message 
news:jf79sh$2l7b$1 digitalmars.com...
 "Jacob Carlborg" <doob me.com> wrote in message 
 news:jf6e7a$1929$1 digitalmars.com...
 method:
 no parameters - parentheses are optional

FWIW, I always do a double-take when I see code like: functionName; //or object.functionName; It sets off all mannar of "no-effect expression!" bells and buzzers in my head every time I look at it, which I then have to silence.

Also it doesn't help that using the function name by itself (with no parens or &) can be used to pass a function as a template alias parameter (or just alias a function), instead of passing the result of the function call as the argument. Plus I've spent time in other langauges where using a function name without parens is the way to refer to a function itself, rather than invoke the function. That's something I very much like: "foo" refers to the function, "foo()" calls the function. Period. End of story. But in D, while "foo()" calls a function, refering to a function is a mess: usually it's "&foo", but if you're aliasing it or passing it as a template alias parameter than it's "foo". But then if you use "foo" in other places, it calls the function instead of referring to it! Bleh!!! Messy, messy.
Jan 18 2012
parent Alvaro <alvaroDotSegura gmail.com> writes:
El 18/01/2012 21:37, Nick Sabalausky escribió:
 "Nick Sabalausky"<a a.a>  wrote in message
 Plus I've spent time in other langauges where using a function name without
 parens is the way to refer to a function itself, rather than invoke the
 function. That's something I very much like: "foo" refers to the function,
 "foo()" calls the function. Period. End of story. But in D, while "foo()"
 calls a function, refering to a function is a mess: usually it's "&foo", but
 if you're aliasing it or passing it as a template alias parameter than it's
 "foo". But then if you use "foo" in other places, it calls the function
 instead of referring to it! Bleh!!! Messy, messy.

Exactly, to my eyes the () is what says "execute!", what triggers the action, so: f = func; // even if not in D, looks like getting the function itself (a pointer to it) x = func(); // looks like "execute func" and assign its ret value to x even with void returning functions: doThat(); // the () is like "Action!" In fact, why not get rid of the & to get a reference to a function? So my vote is: properties: always without (), methods: always ()
Feb 05 2012
prev sibling next sibling parent reply =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= <xtzgzorex gmail.com> writes:
On 18-01-2012 21:26, Nick Sabalausky wrote:
 "Jacob Carlborg"<doob me.com>  wrote in message
 news:jf6e7a$1929$1 digitalmars.com...
 method:
 no parameters - parentheses are optional

FWIW, I always do a double-take when I see code like: functionName; //or object.functionName; It sets off all mannar of "no-effect expression!" bells and buzzers in my head every time I look at it, which I then have to silence.

Indeed! It's so unnatural in a C-based language. See, if the semicolon wasn't there, it would be a different story (see most ML-style functional languages). -- - Alex
Jan 18 2012
parent Manfred Nowak <svv1999 hotmail.com> writes:
Alex Rønne Petersen wrote:
 if the semicolon wasn't there

pwd, ls, du, df, date, uptime, ... -manfred
Jan 18 2012
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2012-01-18 21:26, Nick Sabalausky wrote:
 "Jacob Carlborg"<doob me.com>  wrote in message
 news:jf6e7a$1929$1 digitalmars.com...
 method:
 no parameters - parentheses are optional

FWIW, I always do a double-take when I see code like: functionName; //or object.functionName; It sets off all mannar of "no-effect expression!" bells and buzzers in my head every time I look at it, which I then have to silence.

It's even more fun in Ruby which doesn't require semicolons :) Just: functionName -- /Jacob Carlborg
Jan 18 2012
prev sibling parent sclytrack <sclytrack fake.com> writes:
On 01/17/2012 07:38 PM, Timon Gehr wrote:
 On 01/17/2012 07:48 AM, Andrei Alexandrescu wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }



 Thanks,

 Andrei "I told you" Alexandrescu

IMO it does not matter. I think we should just deprecate the -property switch instead of engaging into that kind of fruitless discussion every now and then. ;)

Can't we drop the empty (). It's too much typing. You don't need them in Delphi and Delphi has properties.
Jan 17 2012
prev sibling next sibling parent Somedude <lovelydear mailmetrash.com> writes:
Le 17/01/2012 07:48, Andrei Alexandrescu a écrit :
 I hate I must ask this:
 
 int[string] aa;
 foreach (k; aa.byKey) { ... }
 
 or
 
 int[string] aa;
 foreach (k; aa.byKey()) { ... }
 
 
 
 Thanks,
 
 Andrei "I told you" Alexandrescu

Microsoft guidelines: http://msdn.microsoft.com/en-us/library/ms229054.aspx http://msdn.microsoft.com/en-us/library/bzwdh01d%28v=vs.71%29.aspx Googling "method vs property" gives different answers to this recurring question.
Jan 17 2012
prev sibling next sibling parent reply Peter Alexander <peter.alexander.au gmail.com> writes:
On 17/01/12 6:48 AM, Andrei Alexandrescu wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }



 Thanks,

 Andrei "I told you" Alexandrescu

byKey(aa) Roll a dice, choose one at random. The only thing properties are good for is distracting us from tabs vs. spaces debates, and other really, really important matters.
Jan 17 2012
next sibling parent "Martin Nowak" <dawg dawgfoto.de> writes:
On Tue, 17 Jan 2012 22:13:49 +0100, Peter Alexander  
<peter.alexander.au gmail.com> wrote:

 On 17/01/12 6:48 AM, Andrei Alexandrescu wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }



 Thanks,

 Andrei "I told you" Alexandrescu

byKey(aa) Roll a dice, choose one at random. The only thing properties are good for is distracting us from tabs vs. spaces debates, and other really, really important matters.

But the current compiler behavior is really annoying. Either nobody should use enforced properties or it should be part of the standard warning level.
Jan 18 2012
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday, January 18, 2012 09:38:41 Martin Nowak wrote:
 But the current compiler behavior is really annoying.
 Either nobody should use enforced properties or it should
 be part of the standard warning level.

Once the implementation of -property has been fully sorted out, I believe that it will be moved to the standard warning level, and then finally to an error, since per TDPL it's a requirement of the language that properties not be called with parens and that non-property functions _must_ be called with parens. The problem is that we're still in the transition period. - Jonathan M Davis
Jan 18 2012
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, January 17, 2012 20:27:41 Timon Gehr wrote:
 On 01/17/2012 07:55 PM, Jonathan M Davis wrote:
 On Tuesday, January 17, 2012 19:38:47 Timon Gehr wrote:
 IMO it does not matter. I think we should just deprecate the -property
 switch instead of engaging into that kind of fruitless discussion
 every
 now and then. ;)

Then we might as well throw out property and change TDPL. There's no point to property without enforcement. I think that that ship has pretty much sailed already. - Jonathan M Davis

Since -property is optional I think the relevant ships are still in the haven.

property is in TDPL. It's definitely the plan to implement it as described in TDPL, integrating -property into the compiler so that property is _always_ enforced. It's just not that way, because it's on the list of things that's not fully implemented, and we needed a migration path from no property enforcement to enforcement. You would need to come up with some really solid arguments why it should be thrown out (and what we should do instead) and get both Walter and Andrei (if not the community at large) to agree that they not only prefer your proposal but that it's worth the issues that the changes are going to cause at this stage. - Jonathan M Davis
Jan 17 2012
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:

 I hate I must ask this:

I am sorry to see you do something you hate :-( Regarding your question, I'd like keys/values to require () because they do lot of work to create the dynamic array, while I like byKey/byValue to be properties because (I think) their creation is O(1). But now we can't change keys/values. So I'd like to keep all five of them as properties. I'd like a byPair property too: http://d.puremagic.com/issues/show_bug.cgi?id=5466 --------------------- There is also the question about code like this: http://d.puremagic.com/issues/show_bug.cgi?id=5075 import std.algorithm; void main() { auto aa = ["red":2, "yellow":3]; auto r = map(n => n * n)(aa); } Bye, bearophile
Jan 17 2012
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/17/12 4:49 PM, bearophile wrote:
 Andrei Alexandrescu:

 I hate I must ask this:

I am sorry to see you do something you hate :-( Regarding your question, I'd like keys/values to require () because they do lot of work to create the dynamic array, while I like byKey/byValue to be properties because (I think) their creation is O(1). But now we can't change keys/values. So I'd like to keep all five of them as properties. I'd like a byPair property too: http://d.puremagic.com/issues/show_bug.cgi?id=5466

byPair is tricky because std.tuple is not visible from object. Andrei
Jan 17 2012
parent bearophile <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:

 I'd like a byPair property too:
 http://d.puremagic.com/issues/show_bug.cgi?id=5466

byPair is tricky because std.tuple is not visible from object.

I will add this answer to the issue 5466. But I hope we'll have the unpacking syntax sugar for tuples. I think this too requires object to see tuples. There are functions in std.math that are better to return a tuple. While having complex numbers as built-in in D is not that useful for most people, I believe tuples are a basic language data type, even more than associative arrays :-) By the way, I have already started using byKey/byValue ranges in my code, and I've already seen a speedup in some programs :-) Bye, bearophile
Jan 17 2012
prev sibling next sibling parent reply Kapps <Kapps NotValidEmail.com> writes:
Is there even a point to having byKey/byValue?
Once UFCS comes in (and there's already a seemingly working pull request 
for it), having .keys return a range like byKey/byValue should will be a 
silent (though more efficient) change for most programs. And in the 
situations where it's not (namely when you want to store it as an 
array), just adding a .array at the end would work.

On 17/01/2012 12:48 AM, Andrei Alexandrescu wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }



 Thanks,

 Andrei "I told you" Alexandrescu

Jan 17 2012
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 17 Jan 2012 19:00:38 -0500, Kapps <Kapps notvalidemail.com> wrote:

 Is there even a point to having byKey/byValue?
 Once UFCS comes in (and there's already a seemingly working pull request  
 for it), having .keys return a range like byKey/byValue should will be a  
 silent (though more efficient) change for most programs. And in the  
 situations where it's not (namely when you want to store it as an  
 array), just adding a .array at the end would work.

It changes semantics. For example: foreach(k; a.keys) { if(shouldRemove(k)) a.remove(k); // this is currently valid } -Steve
Jan 18 2012
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, January 17, 2012 23:13:21 Peter Alexander wrote:
 On 17/01/12 10:11 PM, Jonathan M Davis wrote:
 You would need to come up with some really solid arguments why it should
 be thrown out (and what we should do instead) and get both Walter and
 Andrei (if not the community at large) to agree that they not only
 prefer your proposal but that it's worth the issues that the changes
 are going to cause at this stage.

There's a few good reasons to throw it out: 1. Avoids pointless discussions like this one. These discussions add nothing, it's just mindless bike shedding. 2. The -property flag *creates* a new kind of error, but doesn't actually help find real problems with your code. Without properties, member function access would always be a.b(), and this artificial error could be avoided. 3. Properties introduce another thing to remember, with no value ("was it byKeys, or byKeys()?"). Without properties, it would be byKeys(). No need to remember. 4. Properties obfuscate code. Is (a.b = c) a variable assignment or arbitrary function call? Who knows! Is a.b an actual variable? Can I write &a.b to get its address, or is it a function masquerading as a variable? 5. One less language feature to implement, learn, document, debug, and discuss. Is it practical or realistic to throw it out at this stage? I don't know. But there are reasons to.

I'm fully aware that there are those who want to throw it out (e.g. Andrei) and that there are reasons for doing so. My point is that those reasons must be strong enough to justify the cost of getting rid of property at this stage in the game, or it's not going to happen. As it stands, we're going to have property with it being enforced. And there _are_ those of us who like it. I _do_ think that it's an improvement over what we had before. One of the primary reasons for properties IMHO is to be able to swap out functions and public member variables without breaking code, and that's not possible without something like property with strict enforcement. - Jonathan M Davis
Jan 17 2012
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 17 Jan 2012 18:29:11 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 1/17/12 5:13 PM, Peter Alexander wrote:
 On 17/01/12 10:11 PM, Jonathan M Davis wrote:
 You would need to come up with some really solid arguments why it
 should be
 thrown out (and what we should do instead) and get both Walter and
 Andrei (if
 not the community at large) to agree that they not only prefer your
 proposal
 but that it's worth the issues that the changes are going to cause at
 this
 stage.

There's a few good reasons to throw it out: 1. Avoids pointless discussions like this one. These discussions add nothing, it's just mindless bike shedding.

Yes.

The solution is easy, just don't start the discussion. Make a decision (property or no), and that's the end of it. My intuition says that you will purposely make the *wrong* choice just to try and get others to complain so you can "be right". The point of required property semantics is that the name of the function includes whether you need parentheses or not. a.empty does not have the same tone as a.empty(). The former looks like a field, the latter looks like an action. It's a subtle bikeshed issue, but so is naming functions anyways! If you think the names of things aren't important, name them whatever you want, but at least you as the author get to choose instead of the user. And if I may add my opinion, byValue and byKey are properties.
 2. The -property flag *creates* a new kind of error, but doesn't
 actually help find real problems with your code. Without properties,
 member function access would always be a.b(), and this artificial error
 could be avoided.

Yes! I can't believe we have a check that has _zero_ contribution to improving code.

I think you misunderstand Peter, he is saying we should not have properties *at all* a-la Java.
 Is it practical or realistic to throw it out at this stage? I don't
 know. But there are reasons to.

Me neither. If I had my way I'd carefully redo the feature to only require property on rare cases that would otherwise be ambiguous, and make parens optional everywhere else.

Don't forget my suggestion that void-returning no-arg functions should be able to be called without parens. There should be no ambiguity (since you can't use it as an accessor). But I think enforced properties is the right path, which gives all the naming power to the code author, not the code user. -Steve
Jan 18 2012
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 18 Jan 2012 07:33:45 -0500, Jacob Carlborg <doob me.com> wrote:

 On 2012-01-18 09:30, sclytrack wrote:
 Is it practical or realistic to throw it out at this stage? I don't
 know. But there are reasons to.

I hope we are not dropping properties regardless of the syntax of how to call them. Keep property Keep methods-as-properties --------------------------------- (a) No () obj.property = "test"; string str = obj.property; obj.method = "string"; obj.method("first"); string str = obj.method; obj.method("first", "second"); --------------------------------- (b) Optional () for methods obj.property = "test"; string str = obj.property; obj.method = "string"; obj.method("first"); string str = obj.method; string str = obj.method(); obj.method("first", "second"); --------------------------------- (c) Mandatory () for methods obj.property = "test"; string str = obj.property; obj.method = "string"; obj.method("first"); string str = obj.method(); obj.method("first", "second"); --------------------------------- (d) Property and Method separated. (Is this the goal for -property?) obj.property = "test"; string str = obj.property; string str = obj.method(); obj.method("first"); obj.method("first", "second"); --------------------------------- Who likes (a) ? Also I think that the property opDispatch() looks weird.

I would like this: property: getter - parentheses are not allowed setter: * equal sign is required * parentheses are not allowed method: no parameters - parentheses are optional parameters: * parentheses are required * equal sign is not allowed Examples: obj.property; // legal obj.property = 1; // legal obj.property(); // error obj.property(1); // error obj.method; // legal obj.method(); // legal obj.method(1); // legal obj.method = 1; // error

what about: int x = obj.method; // passes by your rules, but I think should be illegal I think the parentheses should only be optional on void-returning methods. Otherwise, I agree with your list. -Steve
Jan 18 2012
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 18 Jan 2012 09:13:37 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 1/18/12 7:44 AM, Steven Schveighoffer wrote:
 The solution is easy, just don't start the discussion. Make a decision
 (property or no), and that's the end of it. My intuition says that you
 will purposely make the *wrong* choice just to try and get others to
 complain so you can "be right".

Well in this case I am right :o). We did a poor job at designing properties. Anyhow, I honestly asked simply because I found no clear cut decision. My intuition was that byXxx should be a property but I asked Walter whose intuition said it should be a method. So we agreed to ask the newsgroup.

Then I withdraw the "being spiteful" suggestion, it was probably unfair. But the "I told you" didn't set the tone very well for this discussion :)
 The point of required property semantics is that the name of the
 function includes whether you need parentheses or not. a.empty does not
 have the same tone as a.empty(). The former looks like a field, the
 latter looks like an action. It's a subtle bikeshed issue, but so is
 naming functions anyways!

Yes, but the problem is this adds additional bikeshedding for no benefit.
 If you think the names of things aren't
 important, name them whatever you want, but at least you as the author
 get to choose instead of the user.

I understand this point. It doesn't reduce the frustration that we have a feature that does not palpably improve the language.

Disagree on both points :) property with enforcement is the right answer, it improves the language significantly, bringing it in line with most other property-enabled C-like languages.
 And if I may add my opinion, byValue and byKey are properties.

I agree. The current code has them as properties. My thoughts are, a property should reasonably replace a member variable (of which syntax it mimics). So x.length should be property, x.dup shouldn't. Now byXxx can be considered member variables but only as long as it's not considered an lvalue: r.byKey.popFront() does nothing interesting, but would do if r.byKey were actually a member variable. I think that distinction still does not impair byXxx's right to be a property.

I think the difference between what should be a property and what shouldn't is not black and white. There is no easy way to define it. The best I can come up with is, if it gets something that is logically a piece of the object, then it should be a property (even if it makes a copy of that something). If it creates something separate from the object, or modifies the object, it should be a method. -Steve
Jan 18 2012
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 18 Jan 2012 09:40:00 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 1/18/12 8:34 AM, Steven Schveighoffer wrote:
 On Wed, 18 Jan 2012 09:13:37 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 1/18/12 7:44 AM, Steven Schveighoffer wrote:
 The solution is easy, just don't start the discussion. Make a decision
 (property or no), and that's the end of it. My intuition says that you
 will purposely make the *wrong* choice just to try and get others to
 complain so you can "be right".

Well in this case I am right :o). We did a poor job at designing properties. Anyhow, I honestly asked simply because I found no clear cut decision. My intuition was that byXxx should be a property but I asked Walter whose intuition said it should be a method. So we agreed to ask the newsgroup.

Then I withdraw the "being spiteful" suggestion, it was probably unfair. But the "I told you" didn't set the tone very well for this discussion :)

Indeed I told you all! Every time we add anything, there's going to be sh... stuff like this.
 I understand this point. It doesn't reduce the frustration that we
 have a feature that does not palpably improve the language.

Disagree on both points :) property with enforcement is the right answer, it improves the language significantly, bringing it in line with most other property-enabled C-like languages.

This is not an argument. It's good because it's like in other languages where it's supposed to be good. And it's not "the right answer" when there's nothing to be answered.

All of your arguments were subjective "doesn't palpably change the language" "all it does it generate these [in your opinion] useless discussions", why can't mine be? And you did say you were right, when clearly you are wrong :)
 And if I may add my opinion, byValue and byKey are properties.

I agree. The current code has them as properties. My thoughts are, a property should reasonably replace a member variable (of which syntax it mimics). So x.length should be property, x.dup shouldn't. Now byXxx can be considered member variables but only as long as it's not considered an lvalue: r.byKey.popFront() does nothing interesting, but would do if r.byKey were actually a member variable. I think that distinction still does not impair byXxx's right to be a property.

I think the difference between what should be a property and what shouldn't is not black and white. There is no easy way to define it.

If that's the case, then there shouldn't be a black-and-white distinction in the language about it.

The language defines the mechanisms of enforcement, not when to use them. Any time it's a human interpretation of something, the language has to step back and say "you're the boss, you tell me what to do and I'll enforce it." The problem with the current situation is that there is no enforcement. You can suggest a certain usage, and be completely ignored. I liken it to case sensitivity. We could say symbol names aren't case sensitive, and that anyone can use any casing to call a function. But then the author of the function has lost control of what his function names look like. Since D enforced case sensitivity from the beginning, there is never a post saying "should this function be called isUseless or IsUseless. Grr... why on earth do we have case sensitivity anyways, it just generates useless discussions!" But go try to suggest to some language community that has case insensitive symbols that they should add case sensitivity enforcement, and you'll get shit like that.
 The best I can come up with is, if it gets something that is logically a
 piece of the object, then it should be a property (even if it makes a
 copy of that something). If it creates something separate from the
 object, or modifies the object, it should be a method.

The fact that reasonable people disagree, and that choosing one way or another has zero impact on the quality of the code, makes this feature a costly mistake.

The error in that sentence is "has zero impact." It has an impact, about as significant as choosing a good symbol name. -Steve
Jan 18 2012
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Wednesday, January 18, 2012 08:13:37 Andrei Alexandrescu wrote:
 On 1/18/12 7:44 AM, Steven Schveighoffer wrote:
 If you think the names of things aren't
 important, name them whatever you want, but at least you as the author
 get to choose instead of the user.

I understand this point. It doesn't reduce the frustration that we have a feature that does not palpably improve the language.

There are those of us who _do_ think that it palpably improves the language. I think that the issue is more that we have a feature that is rather divisive as to whether it's an improvement or not. Some think that it definitely is, and some think it definitely isn't. It's not one of those features where pretty much everyone agrees that it's an improvement. - Jonathan M Davis
Jan 18 2012
prev sibling next sibling parent Olivier Pisano <olivier.pisano laposte.net> writes:
Le 17/01/2012 07:48, Andrei Alexandrescu a écrit :
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }



 Thanks,

 Andrei "I told you" Alexandrescu

I vote for the methods. Cheers, Olivier
Jan 18 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, January 19, 2012 03:18:22 Timon Gehr wrote:
 They are only required if you want to call a lazy delegate/function
 pointer. They are optional in all other cases.

I could have sworn that they were required. If not, then yeah, that seems pretty bad. It's certainly not the end of the world, but it's inconsistent in away that has caused problem for some people (Andrej was posting about it just the other day). So, it's poor design in that respect. - Jonathan M Davis
Jan 18 2012
prev sibling next sibling parent reply torhu <no spam.invalid> writes:
On 17.01.2012 07:48, Andrei Alexandrescu wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }

For it to be a property, I think you should be able to simplify this example: --- auto k = aa.byKey; writeln(k.front); k.popFront(); writeln(k.front); --- to this: --- writeln(k.byKey.front); k.byKey.popFront(); writeln(k.byKey.front); --- and get the same result. But my understanding is that you wouldn't, in which case byKey doesn't sense to me as a property. It creates and returns a new range object each time you call it, right?
Jan 19 2012
next sibling parent reply torhu <no spam.invalid> writes:
On 19.01.2012 18:19, torhu wrote:
 On 17.01.2012 07:48, Andrei Alexandrescu wrote:
  I hate I must ask this:

  int[string] aa;
  foreach (k; aa.byKey) { ... }

  or

  int[string] aa;
  foreach (k; aa.byKey()) { ... }

For it to be a property, I think you should be able to simplify this example: --- auto k = aa.byKey; writeln(k.front); k.popFront(); writeln(k.front); --- to this: --- writeln(k.byKey.front); k.byKey.popFront(); writeln(k.byKey.front); --- and get the same result. But my understanding is that you wouldn't, in which case byKey doesn't sense to me as a property. It creates and returns a new range object each time you call it, right?

Sorry, I meant this for the second example: --- writeln(aa.byKey.front); aa.byKey.popFront(); writeln(aa.byKey.front); ---
Jan 19 2012
parent reply torhu <no spam.invalid> writes:
On 19.01.2012 18:21, torhu wrote:
 On 19.01.2012 18:19, torhu wrote:
  On 17.01.2012 07:48, Andrei Alexandrescu wrote:
   I hate I must ask this:

   int[string] aa;
   foreach (k; aa.byKey) { ... }

   or

   int[string] aa;
   foreach (k; aa.byKey()) { ... }

For it to be a property, I think you should be able to simplify this example: --- auto k = aa.byKey; writeln(k.front); k.popFront(); writeln(k.front); --- to this: --- writeln(k.byKey.front); k.byKey.popFront(); writeln(k.byKey.front); --- and get the same result. But my understanding is that you wouldn't, in which case byKey doesn't sense to me as a property. It creates and returns a new range object each time you call it, right?

Sorry, I meant this for the second example: --- writeln(aa.byKey.front); aa.byKey.popFront(); writeln(aa.byKey.front); ---

The reason would be that if it looks like field access, it should behave like that. People will quickly learn how this works, like they have gotten used to .dup and similar, but what happens when third-party libraries start doing it too? It think this is not a good precedence to set. We already have fields and functions, this would be a third kind, one that looks like a field but behaves more like a function.
Jan 19 2012
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/19/12 11:29 AM, torhu wrote:
 The reason would be that if it looks like field access, it should behave
 like that.

The difficulty is in knowing where to stop. The only things that behaves exactly like a field access is a field access. This is a known issue in C++, e.g. smart pointers "are smart but aren't pointers". Andrei
Jan 19 2012
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, January 19, 2012 11:33:24 Andrei Alexandrescu wrote:
 On 1/19/12 11:29 AM, torhu wrote:
 The reason would be that if it looks like field access, it should behave
 like that.

The difficulty is in knowing where to stop. The only things that behaves exactly like a field access is a field access. This is a known issue in C++, e.g. smart pointers "are smart but aren't pointers".

Yeah. It's generally expected that properties may return stuff which is generated on each call. They're _simulating_ a member variable rather than being one. I don't think that the fact that a new value is returned each time is particularly relevant, especially since as long as the AA hasn't been altered, the returned values are equivalent. - Jonathan M Davis
Jan 19 2012
prev sibling parent "Marco Leise" <Marco.Leise gmx.de> writes:
Am 19.01.2012, 19:19 Uhr, schrieb Jonathan M Davis <jmdavisProg gmx.com>:

 On Thursday, January 19, 2012 11:33:24 Andrei Alexandrescu wrote:
 On 1/19/12 11:29 AM, torhu wrote:
 The reason would be that if it looks like field access, it should  

 like that.

The difficulty is in knowing where to stop. The only things that behaves exactly like a field access is a field access. This is a known issue in C++, e.g. smart pointers "are smart but aren't pointers".

Yeah. It's generally expected that properties may return stuff which is generated on each call. They're _simulating_ a member variable rather than being one. I don't think that the fact that a new value is returned each time is particularly relevant, especially since as long as the AA hasn't been altered, the returned values are equivalent. - Jonathan M Davis

I just came across some C++ code and came to the conclusion, that properties and indexed access should not modify the structure. In other words all my property and opIndex will probably also by const. An exception to that being caching and access counting.
Jan 19 2012
prev sibling next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/19/12 11:19 AM, torhu wrote:
 On 17.01.2012 07:48, Andrei Alexandrescu wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }

For it to be a property, I think you should be able to simplify this example: --- auto k = aa.byKey; writeln(k.front); k.popFront(); writeln(k.front); --- to this: --- writeln(k.byKey.front); k.byKey.popFront(); writeln(k.byKey.front); --- and get the same result. But my understanding is that you wouldn't, in which case byKey doesn't sense to me as a property. It creates and returns a new range object each time you call it, right?

Yah, this is the lvalue vs. rvalue part. I think you are making a good argument. Andrei
Jan 19 2012
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 19 Jan 2012 12:19:09 -0500, torhu <no spam.invalid> wrote:

 On 17.01.2012 07:48, Andrei Alexandrescu wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }

For it to be a property, I think you should be able to simplify this example: --- auto k = aa.byKey; writeln(k.front); k.popFront(); writeln(k.front); --- to this: --- writeln(k.byKey.front); k.byKey.popFront(); writeln(k.byKey.front); --- and get the same result. But my understanding is that you wouldn't, in which case byKey doesn't sense to me as a property. It creates and returns a new range object each time you call it, right?

That's like saying this: int[] arr; int l = arr.length; l++; should be the same as this: arr.length++; because it's a property. This is an orthogonal problem. byKey doesn't try to affect the original AA, so the semantics should be the same whether you save a copy or access it in one line. There are no hard-fast rules on what should be properties and what shouldn't. But the rvalue vs lvalue is an orthogonal problem. -Steve
Jan 19 2012
parent reply torhu <no spam.invalid> writes:
On 19.01.2012 19:17, Steven Schveighoffer wrote:
 That's like saying this:

 int[] arr;

 int l = arr.length;
 l++;

 should be the same as this:

 arr.length++;

 because it's a property.

 This is an orthogonal problem.  byKey doesn't try to affect the original
 AA, so the semantics should be the same whether you save a copy or access
 it in one line.

 There are no hard-fast rules on what should be properties and what
 shouldn't.  But the rvalue vs lvalue is an orthogonal problem.

If the type of byKeys is Range, I would expect to be able to treat it like one. Not like one, then another, then another, then another... ad infinitum.
Jan 19 2012
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/19/12 4:43 PM, Steven Schveighoffer wrote:
 On Thu, 19 Jan 2012 14:06:00 -0500, torhu <no spam.invalid> wrote:
 If the type of byKeys is Range, I would expect to be able to treat it
 like one. Not like one, then another, then another, then another... ad
 infinitum.

I don't know what you mean. You can treat it like one. -Steve

It's the rvalue aspect. byKey does not hold a range inside the hashtable (as a member variable would do). Each use of byKey gives you a range that you get to iterate from the beginning. Andrie
Jan 19 2012
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/19/12 5:57 PM, Jonathan M Davis wrote:
 On Thursday, January 19, 2012 17:41:44 Andrei Alexandrescu wrote:
 On 1/19/12 4:43 PM, Steven Schveighoffer wrote:
 On Thu, 19 Jan 2012 14:06:00 -0500, torhu<no spam.invalid>  wrote:
 If the type of byKeys is Range, I would expect to be able to treat it
 like one. Not like one, then another, then another, then another... ad
 infinitum.

I don't know what you mean. You can treat it like one. -Steve

It's the rvalue aspect. byKey does not hold a range inside the hashtable (as a member variable would do). Each use of byKey gives you a range that you get to iterate from the beginning.

Well, that's part of the point of properties. They don't have to actually be associated with any particular member variable. They just _act_ like the type has that public member variable.

Yah, but .length acts to a better extent like an lvalue. Andrei
Jan 19 2012
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, January 19, 2012 22:30:46 Jose Armando Garcia wrote:
 I think MSDN has some decent advice on when to use properties vs
 methods:
 http://msdn.microsoft.com/en-us/library/bzwdh01d(v=vs.71).aspx#cpconpropert
 yusageguidelinesanchor1

Those do seem like pretty good guidelines. - Jonathan M Davis
Jan 19 2012
prev sibling next sibling parent Peter Alexander <peter.alexander.au gmail.com> writes:
On 20/01/12 12:57 AM, Steven Schveighoffer wrote:
 On Thu, 19 Jan 2012 18:41:44 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 1/19/12 4:43 PM, Steven Schveighoffer wrote:
 On Thu, 19 Jan 2012 14:06:00 -0500, torhu <no spam.invalid> wrote:
 If the type of byKeys is Range, I would expect to be able to treat it
 like one. Not like one, then another, then another, then another... ad
 infinitum.

I don't know what you mean. You can treat it like one. -Steve

It's the rvalue aspect. byKey does not hold a range inside the hashtable (as a member variable would do). Each use of byKey gives you a range that you get to iterate from the beginning.

The point of a property is to allow for read-only access on something that is logically a property but can only be implemented via a function. byKeys is such a property. There is no way to specify a field that behaves the same. This doesn't make properties invalid or useless.

Can you define what "is logically a property means"? (I assume you meant "field" there) That means different things to different people. For example, in my mind, something that is logically a field would have an address. From what I can see, byKeys is logically a function (not a field) in every way (because it *is* a function).
Jan 20 2012
prev sibling next sibling parent reply Johannes Pfau <spam example.com> writes:
Jose Armando Garcia wrote:

 On Thu, Jan 19, 2012 at 9:41 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 On 1/19/12 4:43 PM, Steven Schveighoffer wrote:
 On Thu, 19 Jan 2012 14:06:00 -0500, torhu <no spam.invalid> wrote:
 If the type of byKeys is Range, I would expect to be able to treat it
 like one. Not like one, then another, then another, then another... ad
 infinitum.

I don't know what you mean. You can treat it like one. -Steve

It's the rvalue aspect. byKey does not hold a range inside the hashtable (as a member variable would do). Each use of byKey gives you a range that you get to iterate from the beginning. Andrie

I think MSDN has some decent advice on when to use properties vs methods: http://msdn.microsoft.com/en-

Hi Jose, great that you're still around in the newsgroups. Any news on std.log? Is it ready for review?
Jan 20 2012
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 2/5/12 11:25 AM, Jose Armando Garcia wrote:
 std.log still works! hehe. std.log is ready for review but
 unfortunately it depends on some changes I have made to druntime. I
 have tried to get those changes into druntime but they are just
 sitting in there as pull requests. I have recently decided to remove
 all my druntime changes and just put them in std/log.d instead. I'll
 have a revised std.log soon and maybe we can have a review soon.

If the changes make more sense to put in druntime let's do so. Please let me know which they are and I'll take a look today. Andrei
Feb 05 2012
prev sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Jonathan M Davis wrote:
 On Thursday, January 19, 2012 22:30:46 Jose Armando Garcia wrote:
 I think MSDN has some decent advice on when to use properties vs
 methods:
 http://msdn.microsoft.com/en-us/library/bzwdh01d(v=vs.71).aspx#cpconpropert
 yusageguidelinesanchor1

Those do seem like pretty good guidelines.

Then why not add these in a condensed form to http://www.dlang.org/dstyle.html? Convention may be a way to end these discussions. Jens
Jan 20 2012
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 19 Jan 2012 14:06:00 -0500, torhu <no spam.invalid> wrote:

 On 19.01.2012 19:17, Steven Schveighoffer wrote:
 That's like saying this:

 int[] arr;

 int l = arr.length;
 l++;

 should be the same as this:

 arr.length++;

 because it's a property.

 This is an orthogonal problem.  byKey doesn't try to affect the original
 AA, so the semantics should be the same whether you save a copy or  
 access
 it in one line.

 There are no hard-fast rules on what should be properties and what
 shouldn't.  But the rvalue vs lvalue is an orthogonal problem.

If the type of byKeys is Range, I would expect to be able to treat it like one. Not like one, then another, then another, then another... ad infinitum.

I don't know what you mean. You can treat it like one. -Steve
Jan 19 2012
prev sibling next sibling parent Jose Armando Garcia <jsancio gmail.com> writes:
On Thu, Jan 19, 2012 at 9:41 PM, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:
 On 1/19/12 4:43 PM, Steven Schveighoffer wrote:
 On Thu, 19 Jan 2012 14:06:00 -0500, torhu <no spam.invalid> wrote:
 If the type of byKeys is Range, I would expect to be able to treat it
 like one. Not like one, then another, then another, then another... ad
 infinitum.

I don't know what you mean. You can treat it like one. -Steve

It's the rvalue aspect. byKey does not hold a range inside the hashtable (as a member variable would do). Each use of byKey gives you a range that you get to iterate from the beginning. Andrie

I think MSDN has some decent advice on when to use properties vs methods: http://msdn.microsoft.com/en-us/library/bzwdh01d(v=vs.71).aspx#cpconpropertyusageguidelinesanchor1
Jan 19 2012
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 19 Jan 2012 18:41:44 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 1/19/12 4:43 PM, Steven Schveighoffer wrote:
 On Thu, 19 Jan 2012 14:06:00 -0500, torhu <no spam.invalid> wrote:
 If the type of byKeys is Range, I would expect to be able to treat it
 like one. Not like one, then another, then another, then another... ad
 infinitum.

I don't know what you mean. You can treat it like one. -Steve

It's the rvalue aspect. byKey does not hold a range inside the hashtable (as a member variable would do). Each use of byKey gives you a range that you get to iterate from the beginning.

The point of a property is to allow for read-only access on something that is logically a property but can only be implemented via a function. byKeys is such a property. There is no way to specify a field that behaves the same. This doesn't make properties invalid or useless. But Torhu, your use of terminology doesn't make sense. The type of byKeys is a Range, and you can use it as a Range. A range on a container is a shallow view, it fundamentally does not affect the container topology. -Steve
Jan 19 2012
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 20 Jan 2012 04:29:12 -0500, Peter Alexander  
<peter.alexander.au gmail.com> wrote:

 On 20/01/12 12:57 AM, Steven Schveighoffer wrote:
 On Thu, 19 Jan 2012 18:41:44 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 1/19/12 4:43 PM, Steven Schveighoffer wrote:
 On Thu, 19 Jan 2012 14:06:00 -0500, torhu <no spam.invalid> wrote:
 If the type of byKeys is Range, I would expect to be able to treat it
 like one. Not like one, then another, then another, then another...  
 ad
 infinitum.

I don't know what you mean. You can treat it like one. -Steve

It's the rvalue aspect. byKey does not hold a range inside the hashtable (as a member variable would do). Each use of byKey gives you a range that you get to iterate from the beginning.

The point of a property is to allow for read-only access on something that is logically a property but can only be implemented via a function. byKeys is such a property. There is no way to specify a field that behaves the same. This doesn't make properties invalid or useless.

Can you define what "is logically a property means"? (I assume you meant "field" there)

No, I meant property. A property is a more general term. It's a piece of data that is associated with an entity. For example, if you have a ball, you might say that the ball is red, or it's bouncy. Those are properties. In this context (of programming language properties), a property can also be a piece of the entity. For example, the valve stem in the ball. properties do several things: 1. they allow you to avoid storing logically derived data. For example, if I have x and y, and I want to get z = sqrt(x*x + y*y), then I could either store z as a field, and update it every time x and y are changed, or I can just make a property, which logically acts like a read-only field. 2. they allow encapsulation. This means, I can give you information or mutable pieces of data from an object without actually exposing the data to you directly. 3. They allow you to control read/write access to a piece of data, including using contracts to check for errors. byKey is an example of the first -- it's not directly stored, but is generated on request. Since it's not actually stored in the object, the other 2 features don't apply. Which is why I was confused as to the nature of the argument above, it's a derived piece of data. The very nature of calculated properties are that you don't get direct access to the internal data because it doesn't exist! -Steve
Jan 20 2012
prev sibling next sibling parent Jose Armando Garcia <jsancio gmail.com> writes:
On Fri, Jan 20, 2012 at 7:47 AM, Johannes Pfau <spam example.com> wrote:
 Jose Armando Garcia wrote:

 On Thu, Jan 19, 2012 at 9:41 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 On 1/19/12 4:43 PM, Steven Schveighoffer wrote:
 On Thu, 19 Jan 2012 14:06:00 -0500, torhu <no spam.invalid> wrote:
 If the type of byKeys is Range, I would expect to be able to treat it
 like one. Not like one, then another, then another, then another... ad
 infinitum.

I don't know what you mean. You can treat it like one. -Steve

It's the rvalue aspect. byKey does not hold a range inside the hashtable (as a member variable would do). Each use of byKey gives you a range that you get to iterate from the beginning. Andrie

I think MSDN has some decent advice on when to use properties vs methods: http://msdn.microsoft.com/en-

Hi Jose, great that you're still around in the newsgroups. Any news on std.log? Is it ready for review?

std.log still works! hehe. std.log is ready for review but unfortunately it depends on some changes I have made to druntime. I have tried to get those changes into druntime but they are just sitting in there as pull requests. I have recently decided to remove all my druntime changes and just put them in std/log.d instead. I'll have a revised std.log soon and maybe we can have a review soon. Thanks, -Jose
Feb 05 2012
prev sibling parent Jose Armando Garcia <jsancio gmail.com> writes:
On Sun, Feb 5, 2012 at 3:26 PM, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:
 On 2/5/12 11:25 AM, Jose Armando Garcia wrote:
 std.log still works! hehe. std.log is ready for review but
 unfortunately it depends on some changes I have made to druntime. I
 have tried to get those changes into druntime but they are just
 sitting in there as pull requests. I have recently decided to remove
 all my druntime changes and just put them in std/log.d instead. I'll
 have a revised std.log soon and maybe we can have a review soon.

If the changes make more sense to put in druntime let's do so. Please let me know which they are and I'll take a look today.

https://github.com/D-Programming-Language/druntime/pull/141/files Let me know if there is anything I need to fix and I'll make the changes in a short time. Thanks!
 Andrei

Feb 05 2012
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, January 19, 2012 20:56:39 Marco Leise wrote:
 I just came across some C++ code and came to the conclusion, that
 properties and indexed access should not modify the structure. In other
 words all my  property and opIndex will probably also by const. An
 exception to that being caching and access counting.

I don't know why you came to that concluson. I don't agree at all. Obviously, you're free to do what you want with your code, but that seems overly restrictive to little or no benefit. Properties can be both getters and setters for a reason. It would be horrible if all you had were getters. - Jonathan M Davis
Jan 19 2012
parent Alvaro <alvaroDotSegura gmail.com> writes:
El 20/01/2012 10:15, Jonathan M Davis escribió:
 On Friday, January 20, 2012 09:58:42 Marco Leise wrote:
 Ah, I meant to say that getters should not modify their object. When I see
 "a = abc.x[i]" I would be a little surprised to find that it changes the
 observable state of abc. The same goes for "a = b.length()". Now it is
 clearer, isn't is? :p

the original through its return value in C++ that I'm aware of is the subscript operator, and it has to in order to function like the built-in substript operator, so that's a special case. - Jonathan M Davis

Well, there is the case of std::map and its [] operator which adds an element if it does not exist. Even if in the right hand side: a = map[x]; // modifies map if x was not found in it Maybe Marco is talking about something like that.
Jan 20 2012
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, January 19, 2012 17:41:44 Andrei Alexandrescu wrote:
 On 1/19/12 4:43 PM, Steven Schveighoffer wrote:
 On Thu, 19 Jan 2012 14:06:00 -0500, torhu <no spam.invalid> wrote:
 If the type of byKeys is Range, I would expect to be able to treat it
 like one. Not like one, then another, then another, then another... ad
 infinitum.

I don't know what you mean. You can treat it like one. -Steve

It's the rvalue aspect. byKey does not hold a range inside the hashtable (as a member variable would do). Each use of byKey gives you a range that you get to iterate from the beginning.

Well, that's part of the point of properties. They don't have to actually be associated with any particular member variable. They just _act_ like the type has that public member variable. - Jonathan M Davis
Jan 19 2012
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, January 19, 2012 18:07:50 Andrei Alexandrescu wrote:
 Yah, but .length acts to a better extent like an lvalue.

True, but that's because it's both a getter and a setter. What's weirder IMHO is properties which are just setters, but they do make sense once in a while. - Jonathan M Davis
Jan 19 2012
prev sibling next sibling parent "Marco Leise" <Marco.Leise gmx.de> writes:
Am 19.01.2012, 21:53 Uhr, schrieb Jonathan M Davis <jmdavisProg gmx.com>:

 On Thursday, January 19, 2012 20:56:39 Marco Leise wrote:
 I just came across some C++ code and came to the conclusion, that
 properties and indexed access should not modify the structure. In other
 words all my  property and opIndex will probably also by const. An
 exception to that being caching and access counting.

I don't know why you came to that concluson. I don't agree at all. Obviously, you're free to do what you want with your code, but that seems overly restrictive to little or no benefit. Properties can be both getters and setters for a reason. It would be horrible if all you had were getters. - Jonathan M Davis

Ah, I meant to say that getters should not modify their object. When I see "a = abc.x[i]" I would be a little surprised to find that it changes the observable state of abc. The same goes for "a = b.length()". Now it is clearer, isn't is? :p
Jan 20 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, January 20, 2012 09:58:42 Marco Leise wrote:
 Ah, I meant to say that getters should not modify their object. When I see
 "a = abc.x[i]" I would be a little surprised to find that it changes the
 observable state of abc. The same goes for "a = b.length()". Now it is
 clearer, isn't is? :p

Yes. Generally, setters should be used to set rather than getters doing it one way or another, though I have no idea how either of your examples there would result in the getter changing anything. However, if a getter property returns a ref, then it's both a getter and a setter. But whether exposing the underlying variable like that makes sense depends on the property - generally not, I think. The one major place where you essentially have a getter being able to modifer the original through its return value in C++ that I'm aware of is the subscript operator, and it has to in order to function like the built-in substript operator, so that's a special case. - Jonathan M Davis
Jan 20 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, January 20, 2012 09:29:12 Peter Alexander wrote:
 Can you define what "is logically a property means"? (I assume you meant
 "field" there)
 
 That means different things to different people. For example, in my
 mind, something that is logically a field would have an address. From
 what I can see, byKeys is logically a function (not a field) in every
 way (because it *is* a function).

Usually when discussing properties, taking the address doesn't come into the equation at all. Part of the reason for this is that many of the languages which have properties don't allow you to take the address of anything in the first place. Also, it completely invalidates property anyway, since by definition, using a property function instead of a member variable makes it so that you can't take its address (or that if you do, it means something completely different). So, taking the address of something really can't come into consideration when talking about properties unless the design requires that you be able to take its address, in which case it must be an actual member variable instead of a property function. So, when talking about something logically acting like a property or a field, it really can't have anything to do with addressing but rather the other aspects about how a field is used. - Jonathan M Davis
Jan 20 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, January 20, 2012 11:01:10 Jens Mueller wrote:
 Jonathan M Davis wrote:
 On Thursday, January 19, 2012 22:30:46 Jose Armando Garcia wrote:
 I think MSDN has some decent advice on when to use properties vs
 methods:
 http://msdn.microsoft.com/en-us/library/bzwdh01d(v=vs.71).aspx#cpcon
 propert yusageguidelinesanchor1

Those do seem like pretty good guidelines.

Then why not add these in a condensed form to http://www.dlang.org/dstyle.html? Convention may be a way to end these discussions.

Oh, it may be a good idea to add them (or something like them) to the style guide or elsewhere on the site, but it won't really end any discussions. Just like function names are subjective, whether something is a property or not is subjective. You can objectively narrow it down pretty thoroughly based on good naming rules (or good rules on what's a property), but in many cases, it still comes down to a subjective decision. So, there will always be debate. You can't get around that. At best, you can reduce it. - Jonathan M Davis
Jan 20 2012
prev sibling next sibling parent Jens Mueller <jens.k.mueller gmx.de> writes:
Jonathan M Davis wrote:
 On Friday, January 20, 2012 11:01:10 Jens Mueller wrote:
 Jonathan M Davis wrote:
 On Thursday, January 19, 2012 22:30:46 Jose Armando Garcia wrote:
 I think MSDN has some decent advice on when to use properties vs
 methods:
 http://msdn.microsoft.com/en-us/library/bzwdh01d(v=vs.71).aspx#cpcon
 propert yusageguidelinesanchor1

Those do seem like pretty good guidelines.

Then why not add these in a condensed form to http://www.dlang.org/dstyle.html? Convention may be a way to end these discussions.

Oh, it may be a good idea to add them (or something like them) to the style guide or elsewhere on the site, but it won't really end any discussions. Just like function names are subjective, whether something is a property or not is subjective. You can objectively narrow it down pretty thoroughly based on good naming rules (or good rules on what's a property), but in many cases, it still comes down to a subjective decision. So, there will always be debate. You can't get around that. At best, you can reduce it.

I was only hoping for a reduction. If a convention works most of the time it's fine, I think. Jens
Jan 20 2012
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, January 20, 2012 15:13:51 Alvaro wrote:
 Well, there is the case of std::map and its [] operator which adds an
 element if it does not exist. Even if in the right hand side:
 
 a = map[x]; // modifies map if x was not found in it
 
 Maybe Marco is talking about something like that.

Maybe. It's certainly a pretty horrible design decision IMHO, and it's not something that should be emulated. - Jonathan M Davis
Jan 20 2012
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/17/12 12:48 AM, Andrei Alexandrescu wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }



 Thanks,

 Andrei "I told you" Alexandrescu

I tallied the votes. Function: Mail Mantis, bearophile, Jacob Carlborg, Olivier Pisano, Ary Manzana, torhu. Property: Nick Sabalausky, Simen Kjaeraas. I wasn't able to discern a clear vote from the others. Please correct the list. Thanks, Andrei
Jan 20 2012
next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 20 Jan 2012 12:58:28 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 1/17/12 12:48 AM, Andrei Alexandrescu wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }



 Thanks,

 Andrei "I told you" Alexandrescu

I tallied the votes. Function: Mail Mantis, bearophile, Jacob Carlborg, Olivier Pisano, Ary Manzana, torhu. Property: Nick Sabalausky, Simen Kjaeraas. I wasn't able to discern a clear vote from the others. Please correct the list.

I voted property, though not as a direct reply before. -Steve
Jan 20 2012
prev sibling next sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, January 20, 2012 11:58:28 Andrei Alexandrescu wrote:
 On 1/17/12 12:48 AM, Andrei Alexandrescu wrote:
 I hate I must ask this:
 
 int[string] aa;
 foreach (k; aa.byKey) { ... }
 
 or
 
 int[string] aa;
 foreach (k; aa.byKey()) { ... }
 
 
 
 Thanks,
 
 Andrei "I told you" Alexandrescu

I tallied the votes. Function: Mail Mantis, bearophile, Jacob Carlborg, Olivier Pisano, Ary Manzana, torhu. Property: Nick Sabalausky, Simen Kjaeraas. I wasn't able to discern a clear vote from the others. Please correct the list.

I'm divided. If it were keys and values, I'd be all for property, but byValue and byKey are weird property names. Of course, they're weird function names too. I assume that they essentially stand for iterateByValue and iterateByKey, which would be more of a function name, but they don't really iterate. Rather, they return something which you can iterate over. So, from a usage perspective, it definitely makes more sense as a property, but from a naming perspective, it's a bit off. I don't really have a better suggestion though, since values and keys are already taken. So, I'm fine with it either way. There's going to be something weird about it regardless. - Jonathan M Davis
Jan 20 2012
parent Matt Soucy <msoucy csh.rit.edu> writes:
On 01/20/2012 01:43 PM, Jonathan M Davis wrote:
 On Friday, January 20, 2012 11:58:28 Andrei Alexandrescu wrote:
 On 1/17/12 12:48 AM, Andrei Alexandrescu wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }



 Thanks,

 Andrei "I told you" Alexandrescu

I tallied the votes. Function: Mail Mantis, bearophile, Jacob Carlborg, Olivier Pisano, Ary Manzana, torhu. Property: Nick Sabalausky, Simen Kjaeraas. I wasn't able to discern a clear vote from the others. Please correct the list.

I'm divided. If it were keys and values, I'd be all for property, but byValue and byKey are weird property names. Of course, they're weird function names too. I assume that they essentially stand for iterateByValue and iterateByKey, which would be more of a function name, but they don't really iterate. Rather, they return something which you can iterate over. So, from a usage perspective, it definitely makes more sense as a property, but from a naming perspective, it's a bit off. I don't really have a better suggestion though, since values and keys are already taken. So, I'm fine with it either way. There's going to be something weird about it regardless. - Jonathan M Davis

names themselves are a bit weird, though. +1 Property
Jan 20 2012
prev sibling next sibling parent sclytrack <sclytrack fake.com> writes:
On 01/20/2012 06:58 PM, Andrei Alexandrescu wrote:
 On 1/17/12 12:48 AM, Andrei Alexandrescu wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }



 Thanks,

 Andrei "I told you" Alexandrescu

I tallied the votes. Function: Mail Mantis, bearophile, Jacob Carlborg, Olivier Pisano, Ary Manzana, torhu,

 Property: Nick Sabalausky, Simen Kjaeraas.

 I wasn't able to discern a clear vote from the others. Please correct
 the list.


 Thanks,

 Andrei

Collection properties should satisfy the "torhu" criteria. Collection property. Usually indexed. Conditions: 1) The focus is on collection 2) torhu criteria I know strings can be seen as a collection of chars. Is string a collection or not, that's another vote. Memory aid: torhu criteria --- auto k = aa.byKey; writeln(k.front); k.popFront(); writeln(k.front); --- to this: --- writeln(aa.byKey.front); aa.byKey.popFront(); writeln(aa.byKey.front);
Jan 20 2012
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:

 I tallied the votes.
 
 Function: Mail Mantis, bearophile, Jacob Carlborg, Olivier Pisano, Ary 
 Manzana, torhu.
 
 Property: Nick Sabalausky, Simen Kjaeraas.
 
 I wasn't able to discern a clear vote from the others. Please correct 
 the list.

I vote for byKey and byValue to be properties. Bye, bearophile
Jan 20 2012
prev sibling next sibling parent Peter Alexander <peter.alexander.au gmail.com> writes:
On 20/01/12 5:58 PM, Andrei Alexandrescu wrote:
 I tallied the votes.

 Function: Mail Mantis, bearophile, Jacob Carlborg, Olivier Pisano, Ary
 Manzana, torhu.

 Property: Nick Sabalausky, Simen Kjaeraas.

 I wasn't able to discern a clear vote from the others. Please correct
 the list.

I vote function.
Jan 20 2012
prev sibling next sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2012-01-20 17:58:28 +0000, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 I tallied the votes.
 
 Function: Mail Mantis, bearophile, Jacob Carlborg, Olivier Pisano, Ary 
 Manzana, torhu.
 
 Property: Nick Sabalausky, Simen Kjaeraas.
 
 I wasn't able to discern a clear vote from the others. Please correct the list.

Votes ?!? I think byKey and byValue are oddly named, property or not. Since you asked, I think they should be properties. But I don't care really. What I care about is consistency. Voting on a case by case basis is just nonsensical. What's needed are guidelines and rationales covering how to name things and by extension what should and shouldn't be a property. If something needs to be put to vote, it should be those guidelines. I attempted a while ago to write some guidelines on the wiki, feel free to use them if they make sense to you. <http://prowiki.org/wiki4d/wiki.cgi?DProgrammingGuidelines> -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 20 2012
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/20/12 7:31 PM, Michel Fortin wrote:
 On 2012-01-20 17:58:28 +0000, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> said:

 I tallied the votes.

 Function: Mail Mantis, bearophile, Jacob Carlborg, Olivier Pisano, Ary
 Manzana, torhu.

 Property: Nick Sabalausky, Simen Kjaeraas.

 I wasn't able to discern a clear vote from the others. Please correct
 the list.

Votes ?!? I think byKey and byValue are oddly named, property or not.

Give them better names and convince others. Please don't choose "keys" and "values".
 Since you
 asked, I think they should be properties. But I don't care really. What
 I care about is consistency.

Mindless consistency would probably be unnerving too.
 Voting on a case by case basis is just nonsensical. What's needed are
 guidelines and rationales covering how to name things and by extension
 what should and shouldn't be a property. If something needs to be put to
 vote, it should be those guidelines.

 I attempted a while ago to write some guidelines on the wiki, feel free
 to use them if they make sense to you.
 <http://prowiki.org/wiki4d/wiki.cgi?DProgrammingGuidelines>

A good outcome of this vote might have been the distillation of some simple guidelines, as opposed to enforcing some arbitrary consistency. Apparently the participants in this thread are divided regarding general rules as well as their applicability to this particular case. Andrei
Jan 20 2012
next sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2012-01-21 01:43:17 +0000, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 On 1/20/12 7:31 PM, Michel Fortin wrote:
 On 2012-01-20 17:58:28 +0000, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> said:
 
 I tallied the votes.
 
 Function: Mail Mantis, bearophile, Jacob Carlborg, Olivier Pisano, Ary
 Manzana, torhu.
 
 Property: Nick Sabalausky, Simen Kjaeraas.
 
 I wasn't able to discern a clear vote from the others. Please correct
 the list.

Votes ?!? I think byKey and byValue are oddly named, property or not.

Give them better names and convince others. Please don't choose "keys" and "values".

Well, if the best ones are already taken, I'd say "allKeys" and "allValues" would be the next best ones. And they are obviously properties.
 Since you
 asked, I think they should be properties. But I don't care really. What
 I care about is consistency.

Mindless consistency would probably be unnerving too.

Guidelines are guides, not absolutes. If you have a good reason it is perfectly fine to not follow the guideline, and you can amend the document if it happens too often. But you need guidelines as a baseline, and a good reason when you derogate.
 Voting on a case by case basis is just nonsensical. What's needed are
 guidelines and rationales covering how to name things and by extension
 what should and shouldn't be a property. If something needs to be put to
 vote, it should be those guidelines.
 
 I attempted a while ago to write some guidelines on the wiki, feel free
 to use them if they make sense to you.
 <http://prowiki.org/wiki4d/wiki.cgi?DProgrammingGuidelines>

A good outcome of this vote might have been the distillation of some simple guidelines, as opposed to enforcing some arbitrary consistency. Apparently the participants in this thread are divided regarding general rules as well as their applicability to this particular case.

It'd be more useful if the discussion involved several examples of various types. You can't make a guideline from only one case, especially a litigious case. You must start by establishing a consensus by listing more clear-cut cases and then you can extend from that consensual position. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 20 2012
next sibling parent reply Alvaro <alvaroDotSegura gmail.com> writes:
El 21/01/2012 3:05, Michel Fortin escribió:
 I think byKey and byValue are oddly named, property or not.

Give them better names and convince others. Don't choose "keys" and "values".

Well, if the best ones are already taken, I'd say "allKeys" and "allValues" would be the next best ones. And they are obviously properties.

Agree with "allKeys" and "allValues" as the next best. IMO, the name of a property should be a a *noun phrase* (a noun possibly with modifiers, complements, adjectives...) because it represents a thing. And if the property represens a collection of things (an array, a list, a range,...) that noun should be *plural* (giving the idea that it can be enumerable). "allKeys" follows this guideline (plural noun with a complement). byKey is what, an adverb phrase, an adjective phrase? It can't name a range which is a thing.
Jan 22 2012
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/22/12 5:57 AM, Alvaro wrote:
 El 21/01/2012 3:05, Michel Fortin escribió:
  >>> I think byKey and byValue are oddly named, property or not.
  >>
  >> Give them better names and convince others. Don't choose "keys"
  >> and "values".
  >
  > Well, if the best ones are already taken, I'd say "allKeys" and
  > "allValues" would be the next best ones. And they are obviously
  > properties.
  >

 Agree with "allKeys" and "allValues" as the next best.

byXyz is in TDPL.
 IMO, the name of a property should be a a *noun phrase* (a noun possibly
 with modifiers, complements, adjectives...) because it represents a
 thing. And if the property represens a collection of things (an array, a
 list, a range,...) that noun should be *plural* (giving the idea that it
 can be enumerable). "allKeys" follows this guideline (plural noun with a
 complement).

torhu convinced me byXyz can't be properties. I'll operate the change soon.
 byKey is what, an adverb phrase, an adjective phrase? It can't name a
 range which is a thing.

It has the implied verb "enumerate", "span". "Span hashtable by key". Andrei
Jan 22 2012
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/12 2:53 PM, Steven Schveighoffer wrote:
 On Sun, 22 Jan 2012 10:27:42 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 byKey is what, an adverb phrase, an adjective phrase? It can't name a
 range which is a thing.

It has the implied verb "enumerate", "span". "Span hashtable by key".

Actually, it's for each (x) in (y) by key:

I'm thinking independently of foreach, e.g. auto iter = aa.byKey/*()*/; This should clarify that iter spans aa by key. Andrei
Jan 24 2012
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/24/12 2:59 PM, Steven Schveighoffer wrote:
 On Fri, 20 Jan 2012 20:43:17 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 On 1/20/12 7:31 PM, Michel Fortin wrote:
 I think byKey and byValue are oddly named, property or not.

Give them better names and convince others. Please don't choose "keys" and "values".

On Sun, 22 Jan 2012 10:27:42 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:
 On 1/22/12 5:57 AM, Alvaro wrote:

 Agree with "allKeys" and "allValues" as the next best.

byXyz is in TDPL.

So in other words, please come up with better names, you can't chose "keys" or "values" but you must choose byKeys or byValues, because it's already in TDPL. Got it! Looking in TDPL, it seems byKey and byValue are already functions. Why did we have this discussion again? Looks like you already chose the answer... -Steve

Changing parens would be (have been) a smaller change. Andrei
Jan 24 2012
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, January 22, 2012 12:57:14 Alvaro wrote:
 byKey is what, an adverb phrase, an adjective phrase?

Prepositional phrase actually. - Jonathan M Davis
Jan 22 2012
prev sibling next sibling parent Johannes Pfau <spam example.com> writes:
Andrei Alexandrescu wrote:

 On 1/20/12 7:31 PM, Michel Fortin wrote:
 On 2012-01-20 17:58:28 +0000, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> said:

 I tallied the votes.

 Function: Mail Mantis, bearophile, Jacob Carlborg, Olivier Pisano, Ary
 Manzana, torhu.

 Property: Nick Sabalausky, Simen Kjaeraas.

 I wasn't able to discern a clear vote from the others. Please correct
 the list.

Votes ?!? I think byKey and byValue are oddly named, property or not.

Give them better names and convince others. Please don't choose "keys" and "values".

keyRange and valueRange?
 
 Since you
 asked, I think they should be properties. But I don't care really. What
 I care about is consistency.

Mindless consistency would probably be unnerving too.
 Voting on a case by case basis is just nonsensical. What's needed are
 guidelines and rationales covering how to name things and by extension
 what should and shouldn't be a property. If something needs to be put to
 vote, it should be those guidelines.

 I attempted a while ago to write some guidelines on the wiki, feel free
 to use them if they make sense to you.
 <http://prowiki.org/wiki4d/wiki.cgi?DProgrammingGuidelines>

A good outcome of this vote might have been the distillation of some simple guidelines, as opposed to enforcing some arbitrary consistency. Apparently the participants in this thread are divided regarding general rules as well as their applicability to this particular case. Andrei

Jan 21 2012
prev sibling next sibling parent Peter Alexander <peter.alexander.au gmail.com> writes:
On 21/01/12 1:43 AM, Andrei Alexandrescu wrote:
 Apparently the participants in this thread are divided regarding general
 rules as well as their applicability to this particular case.

And this is exactly the problem. There are no general rules because everyone disagrees with what exactly a property is.
Jan 21 2012
prev sibling parent torhu <no spam.invalid> writes:
On 21.01.2012 02:43, Andrei Alexandrescu wrote:
 A good outcome of this vote might have been the distillation of some
 simple guidelines, as opposed to enforcing some arbitrary consistency.
 Apparently the participants in this thread are divided regarding general
 rules as well as their applicability to this particular case.

I think that the people here have two different views of what a property is: 1) Just way to hook up some code to what looks and (mostly) behaves like field access. 2) A property of some object, in a wider sense. Examples of 1) are: Creating a read-only field, or delaying calculating a value until first use and then caching it for future use. An example of 2) would be saying that the set of keys of an AA is a property of that AA. As I see it, the main difference between 1) and 2) is that with the latter you are giving field access (dot) syntax a new logical meaning that it didn't use to have. Which why I'm weary of things like aa.byKey. What is the gain, not having to type parentheses? That's not a lot.
Jan 21 2012
prev sibling next sibling parent Alix Pexton <alix.DOT.pexton gmail.DOT.com> writes:
On 20/01/2012 17:58, Andrei Alexandrescu wrote:
 On 1/17/12 12:48 AM, Andrei Alexandrescu wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }



 Thanks,

 Andrei "I told you" Alexandrescu

I tallied the votes. Function: Mail Mantis, bearophile, Jacob Carlborg, Olivier Pisano, Ary Manzana, torhu. Property: Nick Sabalausky, Simen Kjaeraas. I wasn't able to discern a clear vote from the others. Please correct the list. Thanks, Andrei

I vote property. While the names do not fall in line with the properties-are-nouns pattern, I do see the compound aa.byKey as a noun (especially when aa is something more meaningful, and preferably plural). So I think the names should stay as they are. A...
Jan 21 2012
prev sibling next sibling parent Alvaro <alvaroDotSegura gmail.com> writes:
El 20/01/2012 18:58, Andrei Alexandrescu escribió:
 On 1/17/12 12:48 AM, Andrei Alexandrescu wrote:
 I hate I must ask this:

 int[string] aa;
 foreach (k; aa.byKey) { ... }

 or

 int[string] aa;
 foreach (k; aa.byKey()) { ... }


I vote properties. The general rule to me the is a function represents an *action* and usually has a verb in its name while a property is logically something of an object and its name is basically a noun, but nothing is said about whether that thing is stored (a field). A function *does* something, a property *is* something. I'm using "is" in a special way maybe because property values might not actually exist and be created/computed on the fly. "circle.area" is the area of a circle. Whether its value is stored or computed on the fly does not change that. aa.byKey is a range of keys, so, property. Even "a.dup" *is* "a duplicate of a" so it's OK as a property even if it is not a "part" of a. Emphasis on the action of creating that duplicate is removed. BTW, someone said that properties bring something more to remember (is it a.b or a.b()?) but I think they actually reduce doubts: How would I change the radius of a circle in another language? circle.setRadius(2), circle.SetRadius(2), circle.set_radius(2), circle.radius_set(2)? With properties "circle.radius=2;" easier to remember. My two cents.
Jan 21 2012
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sun, 22 Jan 2012 10:27:42 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:
 byKey is what, an adverb phrase, an adjective phrase? It can't name a
 range which is a thing.

It has the implied verb "enumerate", "span". "Span hashtable by key".

Actually, it's for each (x) in (y) by key: foreach(i; aa.byKey); The verb is not implied, nor should it be: for each (x) in (y) enumerate by key. This doesn't read well... But... for each (x) in (y) enumerated by key. Hm... still not an action. It's not a noun, but looks more like an adjective (not an english major). Even if you don't use it via foreach: auto x = aa enumerate by key. The call itself didn't *actually* enumerate the values, it just got you an enumerator. Still vote property, but I see it's unlikely to change your opinion. Oh well, back to the winnable battles :) -Steve
Jan 24 2012
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 20 Jan 2012 20:43:17 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 1/20/12 7:31 PM, Michel Fortin wrote:
 I think byKey and byValue are oddly named, property or not.

Give them better names and convince others. Please don't choose "keys" and "values".

On Sun, 22 Jan 2012 10:27:42 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:
 On 1/22/12 5:57 AM, Alvaro wrote:

 Agree with "allKeys" and "allValues" as the next best.

byXyz is in TDPL.

So in other words, please come up with better names, you can't chose "keys" or "values" but you must choose byKeys or byValues, because it's already in TDPL. Got it! Looking in TDPL, it seems byKey and byValue are already functions. Why did we have this discussion again? Looks like you already chose the answer... -Steve
Jan 24 2012
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 24 Jan 2012 15:02:33 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 1/24/12 2:53 PM, Steven Schveighoffer wrote:
 On Sun, 22 Jan 2012 10:27:42 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 byKey is what, an adverb phrase, an adjective phrase? It can't name a
 range which is a thing.

It has the implied verb "enumerate", "span". "Span hashtable by key".

Actually, it's for each (x) in (y) by key:

I'm thinking independently of foreach, e.g. auto iter = aa.byKey/*()*/; This should clarify that iter spans aa by key.

I wrote about that. auto iter = aa enumerate (or span) by key. But it doesn't actually enumerate by calling that function. The enumeration is done by iter, which is an enumerator/spanner/iterator. FWIW, I think byKey or byValue is fine for a name. We're not writing COBOL here, it can be shorthand. I just think they are properties, and read in English as nouns/adjectives (not actions). -Steve
Jan 24 2012