digitalmars.D.learn - User defined properties signatures
- dvic (22/22) Apr 20 2015 Hi guys,
- Jonathan M Davis via Digitalmars-d-learn (21/27) Apr 20 2015 Not possible. Just like pretty much any C-derived language (C++, Java, C...
- Steven Schveighoffer (4/16) Apr 20 2015 There's an open bugzilla on this:
- dvic (7/48) Apr 20 2015 Thanks for your answer Jonathan. But does the return type part of
- Jonathan M Davis via Digitalmars-d-learn (28/34) Apr 20 2015 The return type is not considered in overloading. And it would complicat...
- dvic (2/47) Apr 20 2015 Thanks Johnathan for the detailed explanation !
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (11/14) Apr 21 2015 Rust does, as far as I know.
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (16/27) Apr 20 2015 I think that would work if multiple 'alias this' were allowed. (There is...
Hi guys, It seems it's possible to define different read properties, only differing by the return type. Ex: property string value() { return m_value; } // m_value is a string property int value() { return to!int(m_value); } But when using it in writefln() or assert for example, compiler (dmd) complains about 2 different property signatures. What I'd like to have is this: MyObject.value = "12345"; // write property always setting a string assert(MyObject.value == "12345"); // depending on the context, call 1st prop assert(MyObject.value == 12345); // depending on the context, call 2nd prop Why is the compiler not complaining about defining 2 read properties and it does otherwise when using both of them? Any clue? Thanks a lot.
Apr 20 2015
On Monday, April 20, 2015 18:35:34 dvic via Digitalmars-d-learn wrote:Hi guys, It seems it's possible to define different read properties, only differing by the return type.etc.) the return type of a function is not considered in function overloading, and it is illegal to overload a function based on its return type.Why is the compiler not complaining about defining 2 read properties and it does otherwise when using both of them?Now, that is weird. I would fully expect something like struct S { property int foo() { return 7; } property string foo() { return "foo"; } } to result in an error, but for some reason, it doesn't (and it doesn't seem to have anything to do with the fact that it's a property function). I have no idea why and would be inclined to argue that it's a compiler bug (though a compiler dev may be able to come up with a good reason for why it's acting the way it is). However, since it _is_ failing to compile as soon as you use the function, the only real problem is that if you declare a function without ever testing it, you risk having a duplicate function without knowing it. But still, I really think that the compiler should be giving an error message even if you don't call it. - Jonathan M Davis
Apr 20 2015
On 4/20/15 2:50 PM, Jonathan M Davis via Digitalmars-d-learn wrote:On Monday, April 20, 2015 18:35:34 dvic via Digitalmars-d-learn wrote:There's an open bugzilla on this: https://issues.dlang.org/show_bug.cgi?id=2789 -SteveWhy is the compiler not complaining about defining 2 read properties and it does otherwise when using both of them?Now, that is weird. I would fully expect something like struct S { property int foo() { return 7; } property string foo() { return "foo"; } } to result in an error, but for some reason, it doesn't (and it doesn't seem to have anything to do with the fact that it's a property function).
Apr 20 2015
On Monday, 20 April 2015 at 18:50:31 UTC, Jonathan M Davis wrote:On Monday, April 20, 2015 18:35:34 dvic via Digitalmars-d-learn wrote:Thanks for your answer Jonathan. But does the return type part of a method signature? I don't know what theory is claiming about that, but for me they are 2 different methods. So contextually, the best fit should prevail.Hi guys, It seems it's possible to define different read properties, only differing by the return type.Not possible. Just like pretty much any C-derived language etc.) the return type of a function is not considered in function overloading, and it is illegal to overload a function based on its return type.Why is the compiler not complaining about defining 2 read properties and it does otherwise when using both of them?Now, that is weird. I would fully expect something like struct S { property int foo() { return 7; } property string foo() { return "foo"; } } to result in an error, but for some reason, it doesn't (and it doesn't seem to have anything to do with the fact that it's a property function). I have no idea why and would be inclined to argue that it's a compiler bug (though a compiler dev may be able to come up with a good reason for why it's acting the way it is). However, since it _is_ failing to compile as soon as you use the function, the only real problem is that if you declare a function without ever testing it, you risk having a duplicate function without knowing it. But still, I really think that the compiler should be giving an error message even if you don't call it. - Jonathan M Davis
Apr 20 2015
On Monday, April 20, 2015 19:42:30 dvic via Digitalmars-d-learn wrote:Thanks for your answer Jonathan. But does the return type part of a method signature? I don't know what theory is claiming about that, but for me they are 2 different methods. So contextually, the best fit should prevail.The return type is not considered in overloading. And it would complicate things considerably if it were. Some basic cases are pretty obvious, like int foo(); string foo(); int a = foo() But what about something like int foo(); float foo(); auto a = foo() + foo(); or int foo(); string foo(); void bar(int); void bar(string); bar(foo()); It's far simpler for the language to not consider return types in overloading and to simply use it for the type of the resulting expression. Then it's generally straightforward for it to determine what the type of complex expressions are. But if the return type is considered in overloading, then it gets _way_ more complicated, especially when the expressions get at all complicated. At best, the compiler would be able to work in the simple cases and error out in the complex ones, but it wouldn't take much before it would have to give up and give an error due to ambiguity. There may be languages out there which take the the return type into account when overloading, but I've never seen one. - Jonathan M Davis
Apr 20 2015
On Monday, 20 April 2015 at 20:22:40 UTC, Jonathan M Davis wrote:On Monday, April 20, 2015 19:42:30 dvic via Digitalmars-d-learn wrote:Thanks Johnathan for the detailed explanation !Thanks for your answer Jonathan. But does the return type part of a method signature? I don't know what theory is claiming about that, but for me they are 2 different methods. So contextually, the best fit should prevail.The return type is not considered in overloading. And it would complicate things considerably if it were. Some basic cases are pretty obvious, like int foo(); string foo(); int a = foo() But what about something like int foo(); float foo(); auto a = foo() + foo(); or int foo(); string foo(); void bar(int); void bar(string); bar(foo()); It's far simpler for the language to not consider return types in overloading and to simply use it for the type of the resulting expression. Then it's generally straightforward for it to determine what the type of complex expressions are. But if the return type is considered in overloading, then it gets _way_ more complicated, especially when the expressions get at all complicated. At best, the compiler would be able to work in the simple cases and error out in the complex ones, but it wouldn't take much before it would have to give up and give an error due to ambiguity. There may be languages out there which take the the return type into account when overloading, but I've never seen one. - Jonathan M Davis
Apr 20 2015
On Monday, 20 April 2015 at 20:22:40 UTC, Jonathan M Davis wrote:There may be languages out there which take the the return type into account when overloading, but I've never seen one.Rust does, as far as I know. I don't think that the ambiguities are an insurmountable obstacle. It's probably sufficient to error out when a call is ambiguous in its context, as can already happen during overloading. Also note that, as Ali pointed out, with multiple alias this we will be able to implement this indirectly. Which means that the compiler needs to deal with exactly the same ambiguities anyway. Might as well just take the return type into consideration directly.
Apr 21 2015
On Tuesday, 21 April 2015 at 13:27:48 UTC, Marc Schütz wrote:On Monday, 20 April 2015 at 20:22:40 UTC, Jonathan M Davis wrote:And this is incredibly frustrating approach that harms both readability and maintainability (you can't cut/paste RHS of an expression anymore without additional changes to the context). I have actually mentioned that when doing "first impressions" post about Rust.There may be languages out there which take the the return type into account when overloading, but I've never seen one.Rust does, as far as I know.
Apr 21 2015
On Tuesday, 21 April 2015 at 13:53:15 UTC, Dicebot wrote:On Tuesday, 21 April 2015 at 13:27:48 UTC, Marc Schütz wrote:Considering ownership and all the compile-time checks Rust does, I'd say you generally can't just cut/paste any part of an expression, or even whole statements, and expect it to just work. Also, in Rust's case this doesn't really count as overloading but as a template instantiation. BTW, the scope of this feature is much wider. Take a look at the channels example from the online book: http://doc.rust-lang.org/1.0.0-beta.2/book/concurrency.html#channels. Rust's type system is super strict, but mpsc::channel() doesn't specify the type of the stuff sent into the channel, and yet it is set correctly for both tx and rx. What's happening here is this: 1) tx.send receives an argument(or doesn't receive an argument), which lets the compiler know what the type of tx is. 2) Now that the compiler knows what the type of tx is, it knows what the type of mpsc::channel is, because it needs to match tx. 3) At this point, type inferring rx's type is straightforward. Now, Rust can do this because it has a super-strict type system. For D to be able to do this, it would have to completely reinvent it's type system, discarding many of it's idioms along the way, resulting at quite a different language.On Monday, 20 April 2015 at 20:22:40 UTC, Jonathan M Davis wrote:And this is incredibly frustrating approach that harms both readability and maintainability (you can't cut/paste RHS of an expression anymore without additional changes to the context). I have actually mentioned that when doing "first impressions" post about Rust.There may be languages out there which take the the return type into account when overloading, but I've never seen one.Rust does, as far as I know.
Apr 21 2015
This isn't about type system per se but about preferred style of syntax. Original example that caused my hatred looked like this: `let i : uint = from_str("42")`. Fortunately this has been deprecated in favor of `parse` but same principle applies - Rust authors encourage you to use declaration for type deduction instead of expression. Same thing can be rewritten as `let i = from_str::<uint>("42")` without compromising any type strictness Rust is proud of. In this form RHS expression has clear unambiguous type and can be copied anywhere. But this is discouraged form. More than that, when I was pointing out ugly template syntax, I got some comments that it is OK exactly because you are always supposed to put type on LHS. This is purely matter of style decisions and it sucks hard.
Apr 21 2015
On 04/20/2015 11:35 AM, dvic wrote:property string value() { return m_value; } // m_value is a string property int value() { return to!int(m_value); }Yes, as Jonathan M Davis said, that's weird.But when using it in writefln() or assert for example, compiler (dmd) complains about 2 different property signatures. What I'd like to have is this: MyObject.value = "12345"; // write property always setting a string assert(MyObject.value == "12345"); // depending on the context, call 1st prop assert(MyObject.value == 12345); // depending on the context, call 2nd propI think that would work if multiple 'alias this' were allowed. (There is a pull request that does not pass some tests; that's why it is not included in 2.067.) struct S { int int_value() { /* ... */ } string string_value() { /* ... */ } alias int_value this; alias string_value this; // ... } The matching function would be called depending on whether S is used in place of an int or a string. Ali
Apr 20 2015