digitalmars.D.learn - UFCS syntax I never saw before.
- SrMordred (6/6) May 21 2018 After all this time I saw this:
- Rubn (14/20) May 21 2018 I probably wouldn't use that. That wasn't what it was intended
- SrMordred (2/8) May 21 2018 I thought that only with @property this will work.
- Steven Schveighoffer (4/16) May 21 2018 That was the plan, but it got derailed.
- aliak (3/20) May 22 2018 While wearing the naughty pointy hat and sitting in a corner :p
- ANtlord (17/23) May 21 2018 What the hell is this? I don't figure out why are there so many
- Jonathan M Davis (119/135) May 21 2018 This particular example is a result of how property functions were
- ANtlord (3/11) May 22 2018 First of all thanks a lot for the response. It cleans something
- aliak (8/16) May 22 2018 Can't assignment to a function be fixed though? Are there any
- Steven Schveighoffer (7/29) May 22 2018 The derailed plan was to leave alone the ability to call no-arg
- aliak (14/21) May 24 2018 Aha. Thanks for the link!
- aliak (2/6) May 24 2018 Edit: err... other way around!
- Jonathan M Davis (14/32) May 22 2018 A free function with a single argument works just fine as a setter prope...
- aliak (3/16) May 24 2018 That can be attributed with @property if the developer intends
- Chris M. (3/9) May 21 2018 That's pretty cool, but at the same time this should be wiped off
- Dennis (10/11) May 21 2018 Here's another weird example:
- SrMordred (1/2) May 21 2018 lol
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
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
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
On 5/21/18 8:15 AM, SrMordred wrote:Right, so this should´n be working I think.That was the plan, but it got derailed. Whoever wrote that original line of code, they need a stern talking-to. -Stevestruct SomeStruct { void foo(int); } SomeStruct s; s.foo = 10;I thought that only with property this will work.
May 21 2018
On Monday, 21 May 2018 at 14:19:35 UTC, Steven Schveighoffer wrote:On 5/21/18 8:15 AM, SrMordred wrote:While wearing the naughty pointy hat and sitting in a corner :pRight, so this should´n be working I think.That was the plan, but it got derailed. Whoever wrote that original line of code, they need a stern talking-to. -Stevestruct SomeStruct { void foo(int); } SomeStruct s; s.foo = 10;I thought that only with property this will work.
May 22 2018
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
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: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 DavisAfter 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.
May 21 2018
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 DavisFirst of all thanks a lot for the response. It cleans something for me. I need a few time to think.
May 22 2018
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
On 5/22/18 9:48 AM, aliak wrote:On Monday, 21 May 2018 at 18:53:19 UTC, Jonathan M Davis 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. -Stevewriteln = "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
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. -SteveAha. 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
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
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: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 Daviswriteln = "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
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 DavisThat can be attributed with property if the developer intends for it to be used in that way, else should be illegal.
May 24 2018
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
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
"%s %s".writefln = ("foo".tuple = "bar").expand;lol
May 21 2018