digitalmars.D - Properties: problems
- John C (27/27) Jul 29 2009 Here's a couple of annoying problems I encounter quite often with D's
- Chad J (27/71) Jul 29 2009 This one is weird. After defining getPerson() I was able to rewrite the
- John C (7/47) Jul 30 2009 Yes, that's D's special array syntax, where free functions can be called...
- Benji Smith (6/36) Jul 30 2009 Yeah, this is one of those nasty cases where several different features
- Chad J (8/64) Jul 31 2009 It's the pointed answer to your question:
- John C (4/50) Jul 30 2009 It actually works if the "ref" is attached not to the WebClient.headers
Here's a couple of annoying problems I encounter quite often with D's properties. Would having some form of property syntax fix them? 1) Array extensions: class Person { string name_; string name() { return name_; } } auto person = getPerson(); auto firstAndLast = person.name.split(' '); The above line currently requires parentheses after 'name' to compile. 2) Indexing: struct Map(K, V) { void opIndexAssign(V value, K key) { ... } V opIndex(K key) { ... } } class WebClient { private Map!(string, string) headers_; Map!(string, string) headers() { return headers_; } } auto client = new WebClient(); client.headers["User-Agent"] = "MyWebClient"; The compiler says client.headers() is not an lvalue (adding 'ref' in D2 changes nothing).
Jul 29 2009
John C wrote:Here's a couple of annoying problems I encounter quite often with D's properties. Would having some form of property syntax fix them? 1) Array extensions: class Person { string name_; string name() { return name_; } } auto person = getPerson(); auto firstAndLast = person.name.split(' '); The above line currently requires parentheses after 'name' to compile.This one is weird. After defining getPerson() I was able to rewrite the last line into this and make it compile: auto firstAndLast = split(person.name," "); Note that you need qoutes, not just ' '. But even auto firstAndLast = person.name.split(" "); does not compile. main2.d(36): Error: function expected before (), not split(person.name()) of type immutable(char)[][] This is probably a compiler bug. I don't think property syntax is truly necessary for this example. You are fortunate enough to be using strings, which are passed by reference.2) Indexing: struct Map(K, V) { void opIndexAssign(V value, K key) { ... } V opIndex(K key) { ... } } class WebClient { private Map!(string, string) headers_; Map!(string, string) headers() { return headers_; } } auto client = new WebClient(); client.headers["User-Agent"] = "MyWebClient"; The compiler says client.headers() is not an lvalue (adding 'ref' in D2 changes nothing).This is nearly the same thing as the "a.b.c = 3;" example given in the "a.b.c = 3;" thread. The .b is your .headers. It's slightly more forgiving though, since you are calling a function on the returned struct and not accessing a field. The setter never needs to be called in your example. I'll use the compiler's rewritting technique to show you what it looks like: client.headers["User-Agent"] = "MyWebClient"; client.headers.opIndexAssign("User-Agent","MyWebClient"); client.headers().opIndexAssign("User-Agent","MyWebClient"); client.headers() creates a /new/ Map!(...) struct, so the opIndexAssign will not be called on the one you want it to be called on. Adding 'ref' should change that. That sounds like a bug. In this specific example, property syntax is not truly necessary. That ref returns were added should make this doable.
Jul 29 2009
Chad J wrote:John C wrote:Yes, that's D's special array syntax, where free functions can be called as if they were "methods" of an array.Here's a couple of annoying problems I encounter quite often with D's properties. Would having some form of property syntax fix them? 1) Array extensions: class Person { string name_; string name() { return name_; } } auto person = getPerson(); auto firstAndLast = person.name.split(' '); The above line currently requires parentheses after 'name' to compile.This one is weird. After defining getPerson() I was able to rewrite the last line into this and make it compile: auto firstAndLast = split(person.name," ");Note that you need qoutes, not just ' '.My mistake.But even auto firstAndLast = person.name.split(" "); does not compile. main2.d(36): Error: function expected before (), not split(person.name()) of type immutable(char)[][] This is probably a compiler bug.This is my point. The compiler can't tell that "name" is a property, so it expects parentheses "name()" to work. That's the problem.I don't think property syntax is truly necessary for this example. You are fortunate enough to be using strings, which are passed by reference.Sorry, I don't see how this statement is relevant at all.
Jul 30 2009
John C wrote:Chad J wrote:Yeah, this is one of those nasty cases where several different features (optional parentheses on functions & automatic extension method syntax on arrays) work ok in isolation, but where they have weird wonky behavior when combined. I've seen this one before. --benjiJohn C wrote:Yes, that's D's special array syntax, where free functions can be called as if they were "methods" of an array.Here's a couple of annoying problems I encounter quite often with D's properties. Would having some form of property syntax fix them? 1) Array extensions: class Person { string name_; string name() { return name_; } } auto person = getPerson(); auto firstAndLast = person.name.split(' '); The above line currently requires parentheses after 'name' to compile.This one is weird. After defining getPerson() I was able to rewrite the last line into this and make it compile: auto firstAndLast = split(person.name," ");
Jul 30 2009
John C wrote:Chad J wrote:I'm saying this actually should work in current D2.John C wrote:Yes, that's D's special array syntax, where free functions can be called as if they were "methods" of an array.Here's a couple of annoying problems I encounter quite often with D's properties. Would having some form of property syntax fix them? 1) Array extensions: class Person { string name_; string name() { return name_; } } auto person = getPerson(); auto firstAndLast = person.name.split(' '); The above line currently requires parentheses after 'name' to compile.This one is weird. After defining getPerson() I was able to rewrite the last line into this and make it compile: auto firstAndLast = split(person.name," ");Note that you need qoutes, not just ' '.My mistake.But even auto firstAndLast = person.name.split(" "); does not compile. main2.d(36): Error: function expected before (), not split(person.name()) of type immutable(char)[][] This is probably a compiler bug.This is my point. The compiler can't tell that "name" is a property, so it expects parentheses "name()" to work. That's the problem.It's the pointed answer to your question:I don't think property syntax is truly necessary for this example. You are fortunate enough to be using strings, which are passed by reference.Sorry, I don't see how this statement is relevant at all.They should work already, so property syntax can't possibly fix them. At least not on a conceptual level. On a practical level, it is quite possible that property syntax would improve the situation, if only because the information is provided to the compiler in a much more direct manner.Here's a couple of annoying problems I encounter quite often with D's properties. Would having some form of property syntax fix them?
Jul 31 2009
Chad J wrote:John C wrote:It actually works if the "ref" is attached not to the WebClient.headers property, but to the Map.opIndex operator (and opIndexAssign is removed, or course).2) Indexing: struct Map(K, V) { void opIndexAssign(V value, K key) { ... } V opIndex(K key) { ... } } class WebClient { private Map!(string, string) headers_; Map!(string, string) headers() { return headers_; } } auto client = new WebClient(); client.headers["User-Agent"] = "MyWebClient"; The compiler says client.headers() is not an lvalue (adding 'ref' in D2 changes nothing).This is nearly the same thing as the "a.b.c = 3;" example given in the "a.b.c = 3;" thread. The .b is your .headers. It's slightly more forgiving though, since you are calling a function on the returned struct and not accessing a field. The setter never needs to be called in your example. I'll use the compiler's rewritting technique to show you what it looks like: client.headers["User-Agent"] = "MyWebClient"; client.headers.opIndexAssign("User-Agent","MyWebClient"); client.headers().opIndexAssign("User-Agent","MyWebClient"); client.headers() creates a /new/ Map!(...) struct, so the opIndexAssign will not be called on the one you want it to be called on. Adding 'ref' should change that. That sounds like a bug. In this specific example, property syntax is not truly necessary. That ref returns were added should make this doable.
Jul 30 2009