www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - UFCS syntax I never saw before.

reply SrMordred <patric.dexheimer gmail.com> writes:
After all this time I saw this:

writeln = iota = 5;

what??

I never saw that before!

This is interesting, there is something useful that i can do with 
this kind of call?
May 21 2018
next sibling parent reply Rubn <where is.this> writes:
On Monday, 21 May 2018 at 11:38:12 UTC, SrMordred wrote:
 After all this time I saw this:

 writeln = iota = 5;

 what??

 I never saw that before!

 This is interesting, there is something useful that i can do 
 with this kind of call?
I probably wouldn't use that. That wasn't what it was intended for and it's not really UFCS. It's was meant for properties that are defined as functions. struct SomeStruct { void foo(int); } SomeStruct s; s.foo = 10; It's kind of horrible syntax for what it is doing, where it isn't obvious what is happening. Writeln and iota aren't setting anything, they are just function calls that happen to be able to take one parameter.
May 21 2018
parent reply SrMordred <patric.dexheimer gmail.com> writes:
Right, so this should´n be working I think.

 struct SomeStruct
 {
     void foo(int);
 }

 SomeStruct s;
 s.foo = 10;
I thought that only with property this will work.
May 21 2018
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 5/21/18 8:15 AM, SrMordred wrote:
 Right, so this should´n be working I think.
 
 struct SomeStruct
 {
     void foo(int);
 }

 SomeStruct s;
 s.foo = 10;
I thought that only with property this will work.
That was the plan, but it got derailed. Whoever wrote that original line of code, they need a stern talking-to. -Steve
May 21 2018
parent aliak <something something.com> writes:
On Monday, 21 May 2018 at 14:19:35 UTC, Steven Schveighoffer 
wrote:
 On 5/21/18 8:15 AM, SrMordred wrote:
 Right, so this should´n be working I think.
 
 struct SomeStruct
 {
     void foo(int);
 }

 SomeStruct s;
 s.foo = 10;
I thought that only with property this will work.
That was the plan, but it got derailed. Whoever wrote that original line of code, they need a stern talking-to. -Steve
While wearing the naughty pointy hat and sitting in a corner :p
May 22 2018
prev sibling next sibling parent reply ANtlord <antlord92 gmail.com> writes:
On Monday, 21 May 2018 at 11:38:12 UTC, SrMordred wrote:
 After all this time I saw this:

 writeln = iota = 5;

 what??

 I never saw that before!

 This is interesting, there is something useful that i can do 
 with this kind of call?
What the hell is this? I don't figure out why are there so many syntax features? It doesn't make the language more easier. Is it any reason to support 2 additional cases of function calling? We have no literal for a tuple but we call a function via 3 cases. I'm frustrated. D has a lot cool features, I like D, but that is one of those which make me doubt the language future. I don't play a big role in the project but I talk to all my python co-workers: "You know... so there so cool language, it's called D. It can do this and that... It supports convenient static typing so you definitely know what happens in a piece of code.". But something like this make doubt about what happens in a piece of code. There is static typing so I know that type a variable has, but I look at a method calling and I ask: "Is it data field? No. Is it property? No. Is it method? No. It's UFCS! Okay." And now I see that UFCS can works the same way as a property!
May 21 2018
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Monday, May 21, 2018 14:00:55 ANtlord via Digitalmars-d-learn wrote:
 On Monday, 21 May 2018 at 11:38:12 UTC, SrMordred wrote:
 After all this time I saw this:

 writeln = iota = 5;

 what??

 I never saw that before!

 This is interesting, there is something useful that i can do
 with this kind of call?
What the hell is this? I don't figure out why are there so many syntax features? It doesn't make the language more easier. Is it any reason to support 2 additional cases of function calling? We have no literal for a tuple but we call a function via 3 cases. I'm frustrated.
This particular example is a result of how property functions were originally introduced into the language, and UCFS just compounded the problem. It's also why () is optional on function calls. foo = bar; is treating foo like a setter property, and auto result = foo; is treating foo like a getter property. Heck, in foo = bar; both foo and bar could be function calls. As long as it's used intelligently, this is great, because then you can treat functions as properties. But it gets really bad when someone does something dumb like writeln = "hello"; Because this can get really dumb, property was introduced into the language with the idea that it would be used to mark functions which were supposed to be used as properties. Then dumb stuff like writeln = "hello"; could become illegal, whereas stuff functions that were actually intended to be used as properties could continue to be used as properties. So, the clean uses would be left, and the bad uses would be illegal. Unfortunately, because moving to property meant breaking code (even code that was using properties legitimately, since it was introduced before property was a thing), that meant that we had to introduce property as doing nothing and then switch to enforcing it later. Somewhere along the line, the -property flag was introduced to start enforcing it, but it only partially enforced it, and of course code continued to be written without using it. So, actually moving to enforcing everything with property was slow. And then UFCS happened, and that pretty much killed the whole thing. The problem was twofold: 1. A number of folks just got in the habit of calling functions without parens and liked it. They would generally agree that writeln = "foo"; was dumb, but they liked being able to just not use parens when doing stuff like myObj = foo; or myFunc(foo); So, telling them that they couldn't do that anymore didn't go over well. 2. Once, UFCS came into the game, instead of having code like auto result = map!(a => a / 2)(range); you got auto result = range.map!(a => / 2)(); and you all of a sudden had a bunch of templated functions with empty parens when called, and since you already had a one set of parens for the template argument, folks thought that that was ugly. So, they started writing auto result = range.map!(a => / 2); So, requiring that they then use parens for that as they would have to if parens were required when calling all non- property functions as had been the plan was _not_ going to go over well. It basically became completely unacceptable to require property for property functions, and so plans to properly implement property were dropped. The result is that property does almost nothing (it affects what typeof does, and it affects __traits - and thus std.traits.functionAttributes - and you can't overload an property function and a normal function, but that's pretty much it). Lots of us use it all the time to indicate what we intend to be used as a property function, but it's just documentation. Now, even if you think that calling functions with no parens is great, that still leaves us with two problems: 1. writeln = "foo"; is still legal. Maybe we could make it so that property is required with free functions used as setters that aren't used with UFCS, but figuring out a set of rules that doesn't require putting property on all setter functions while still disallowing the really dumb stuff isn't easy, and it's questionable that requiring property on setters at this point is going to go over well. It's very annoying that stuff like writeln = "foo"; is legal, and it's dumb, but it hasn't mattered much in practice. So, causing a bunch of code breakage in order to disallow it is unlikely to go over well. It would also then make getters and setters inconsistent in that setters would require property and getters wouldn't. How much that matters is debatable, but it does make such a change less palatable. 2. The other issue that property was supposed to fix was property functions that return callables - e.g. foo could return a delegate, but the compiler has to assume that the parens on foo() are calling foo, not the delegate that it returns. So, even though you want to treat foo as a property that is a delegate, you're forced to treat it as a function and use double parens - e.g. foo()(). If property were required, then if foo were marked with property, the compiler would know that foo() called the delegate and that foo()() was trying to call the return value of the delegate. However, since property is clearly never going to be implemented as intended, that problem is remains unsolved. It's been suggested that we just make it so that property actually do what it was originally intended to do if the return type is callable, but that has never been officially decided, let alone implemented. So, the end result is - as you're complaining about - a bit of a mess. But it's not at all clear how to fix it at this point, and with how Walter and Andrei have become decreasingly willing to make breaking changes that don't have large benefits, it seems unlikely that this situation is going to be fixed. The reality of the matter is that as ugly as the situation is, it really doesn't matter much in practice. You're almost certainly never going to find something like writeln = "foo"; in real code. It's dumb that it can be done, but because it's so dumb, no one does it - just like 5[arr] is legal in C (whereas the languages that have come after have wisely required that you do arr[5]), but it's dumb, so no one does it. And returning callables from property functions happens rarely enough in practice that it pretty much only comes up as a theoretical problem to the current situation rather than a practical one. No one actually complains about it. So, when faced with the choice of fixing dumb corner cases that aren't actually problems in real code and breaking existing code in the process (since there isn't an easy way to just prevent the dumb code while allowing reasonable code) or leaving things as-is, Walter and Andrei have chosen to leave things as-is. It wouldn't surprise me if Walter and Andrei make some official decision about property at some point in the nearish future, since one of their priorities at this point is to clean up and complete existing features (e.g. shared), but the most likely decision would be that property would just be made to do nothing and get phased out of existence, because they aren't going to want to break valid code, and the only places that it really causes problems are places where programmers are being dumb. But we'll have to wait and see what they decide. I think that of all of the things they want to finish about the language, property is pretty low on the list, because it's pretty low impact. If someone wrote an good DIP on the subject, I expect that things could be accelerated, but it's not much a real paint point in practice, and the chances of property actually ever meaning anything like it was originally intended to mean are pretty much zero. UFCS killed that. - Jonathan M Davis
May 21 2018
next sibling parent ANtlord <antlord92 gmail.com> writes:
On Monday, 21 May 2018 at 18:53:19 UTC, Jonathan M Davis wrote:
 On Monday, May 21, 2018 14:00:55 ANtlord via 
 Digitalmars-d-learn wrote:

 If someone wrote an good DIP on the subject, I expect that 
 things could be accelerated, but it's not much a real paint 
 point in practice, and the chances of  property actually ever 
 meaning anything like it was originally intended to mean are 
 pretty much zero. UFCS killed that.

 - Jonathan M Davis
First of all thanks a lot for the response. It cleans something for me. I need a few time to think.
May 22 2018
prev sibling parent reply aliak <something something.com> writes:
On Monday, 21 May 2018 at 18:53:19 UTC, Jonathan M Davis wrote:
 writeln = "foo";

 is legal, and it's dumb, but it hasn't mattered much in 
 practice. So, causing a bunch of code breakage in order to 
 disallow it is unlikely to go over well. It would also then 
 make getters and setters inconsistent in that setters would 
 require  property and getters wouldn't. How much that matters 
 is debatable, but it does make such a change less palatable.

 [...]
Can't assignment to a function be fixed though? Are there any cases where fixing that will cause problems for property free functions because they all must take more that one parameter i assume. It's quite a big wart so we don't have to fix all of property at least, but that should be fixed if fixing it does not crap on UFCS and property free functions.
May 22 2018
next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 5/22/18 9:48 AM, aliak wrote:
 On Monday, 21 May 2018 at 18:53:19 UTC, Jonathan M Davis wrote:
 writeln = "foo";

 is legal, and it's dumb, but it hasn't mattered much in practice. So, 
 causing a bunch of code breakage in order to disallow it is unlikely 
 to go over well. It would also then make getters and setters 
 inconsistent in that setters would require  property and getters 
 wouldn't. How much that matters is debatable, but it does make such a 
 change less palatable.

 [...]
Can't assignment to a function be fixed though? Are there any cases where fixing that will cause problems for property free functions because they all must take more that one parameter i assume. It's quite a big wart so we don't have to fix all of property at least, but that should be fixed if fixing it does not crap on UFCS and property free functions.
The derailed plan was to leave alone the ability to call no-arg functions without parentheses, but to REQUIRE property to call an argument-taking function with the assignment style. See the DIP here: https://wiki.dlang.org/DIP23 Written by Walter and Andrei. I can't remember why it didn't happen. -Steve
May 22 2018
parent reply aliak <something something.com> writes:
On Tuesday, 22 May 2018 at 13:59:16 UTC, Steven Schveighoffer 
wrote:
 The derailed plan was to leave alone the ability to call no-arg 
 functions without parentheses, but to REQUIRE  property to call 
 an argument-taking function with the assignment style.

 See the DIP here: https://wiki.dlang.org/DIP23

 Written by Walter and Andrei. I can't remember why it didn't 
 happen.

 -Steve
Aha. Thanks for the link! It feels like the only difference between a no-arg function that is property and one that is not is that the former could be invoked with optional parentheses and the latter should be illegal with parentheses. Whereas an argument taking function marked as property should probably allow read or write operations depending on whether or not it's invoked with an implicit first argument or not: property int f(int) { ... } 1.f; // read op f = 1; // write op And to make parentheses illegal as well of course.
May 24 2018
parent aliak <something something.com> writes:
On Thursday, 24 May 2018 at 22:03:38 UTC, aliak wrote:
 It feels like the only difference between a no-arg function 
 that is  property and one that is not is that the former could 
 be invoked with optional parentheses and the latter should be 
 illegal with parentheses.
Edit: err... other way around!
May 24 2018
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Tuesday, May 22, 2018 13:48:16 aliak via Digitalmars-d-learn wrote:
 On Monday, 21 May 2018 at 18:53:19 UTC, Jonathan M Davis wrote:
 writeln = "foo";

 is legal, and it's dumb, but it hasn't mattered much in
 practice. So, causing a bunch of code breakage in order to
 disallow it is unlikely to go over well. It would also then
 make getters and setters inconsistent in that setters would
 require  property and getters wouldn't. How much that matters
 is debatable, but it does make such a change less palatable.

 [...]
Can't assignment to a function be fixed though? Are there any cases where fixing that will cause problems for property free functions because they all must take more that one parameter i assume. It's quite a big wart so we don't have to fix all of property at least, but that should be fixed if fixing it does not crap on UFCS and property free functions.
A free function with a single argument works just fine as a setter property. e.g. you could do something like void env(Tuple!(string, string)[] str) { // set environment variables } env = [tuple("foo", "bar")]; is perfectly legal. I question that there are many cases where such a function would be considered good design, but basically any case where it would make sense to have a function act like a global variable is currently allowed but would be disallowed if you couldn't have a setter property with only one argument. - Jonathan M Davis
May 22 2018
parent aliak <something something.com> writes:
On Tuesday, 22 May 2018 at 14:33:20 UTC, Jonathan M Davis wrote:
 A free function with a single argument works just fine as a 
 setter property. e.g. you could do something like

 void env(Tuple!(string, string)[] str)
 {
     // set environment variables
 }

 env = [tuple("foo", "bar")];

 is perfectly legal. I question that there are many cases where 
 such a function would be considered good design, but basically 
 any case where it would make sense to have a function act like 
 a global variable is currently allowed but would be disallowed 
 if you couldn't have a setter property with only one argument.

 - Jonathan M Davis
That can be attributed with property if the developer intends for it to be used in that way, else should be illegal.
May 24 2018
prev sibling next sibling parent Chris M. <chrismohrfeld comcast.net> writes:
On Monday, 21 May 2018 at 11:38:12 UTC, SrMordred wrote:
 After all this time I saw this:

 writeln = iota = 5;

 what??

 I never saw that before!

 This is interesting, there is something useful that i can do 
 with this kind of call?
That's pretty cool, but at the same time this should be wiped off the face of the Earth.
May 21 2018
prev sibling parent reply Dennis <dkorpel gmail.com> writes:
On Monday, 21 May 2018 at 11:38:12 UTC, SrMordred wrote:
 what??
Here's another weird example: ``` void funWithUfcsAndPropertySyntax() { import std.typecons : tuple; "%s %s".writefln = ("foo".tuple = "bar").expand; } ``` source: https://github.com/Hackerpilot/Idiotmatic-D/blob/master/idiotmatic.d#L78
May 21 2018
parent SrMordred <patric.dexheimer gmail.com> writes:
"%s %s".writefln = ("foo".tuple = "bar").expand;
lol
May 21 2018