www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 9857] New: UFCS for struct opCall

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9857

           Summary: UFCS for struct opCall
           Product: D
           Version: D2
          Platform: x86
        OS/Version: Windows
            Status: NEW
          Keywords: rejects-valid
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: bearophile_hugs eml.cc



Maybe this should be valid:


struct Foo {
    int opCall(bool b) {
        return 0;
    }
}
void main() {
   Foo foo;
   auto b1 = foo(true); // OK
   auto b2 = true.foo;  // Error
}


dmd 2.063alpha gives:

temp.d(9): Error: no property 'foo' for type 'bool'

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 02 2013
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9857


Andrej Mitrovic <andrej.mitrovich gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrej.mitrovich gmail.com



06:47:33 PDT ---
That seems like a stretch.. why would you need this?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 02 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9857





 That seems like a stretch.. why would you need this?
1) I am using UFCS often in D, for functions, higher order functions, etc. A struct with an opCall method is usable like a function with state. So for uniformity with the other functions I'd like to use it with UFCS. When you have a long UFCS chain you don't want to break it, if it's possible. 2) Both struct constructors, struct implicit constructors and struct static opCall support UFCS, so I don't see a good reason for the normal struct opCall to not support it: struct Foo { static int opCall(int x) { return x * 2; } } struct Bar { int x; this(int y) { x = y * 2; } } struct Spam { int x; } void main() { assert(10.Foo == 20); assert(10.Bar.x == 20); assert(10.Spam.x == 10); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 02 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9857




10:41:50 PDT ---

 2) Both struct constructors, struct implicit constructors and struct static
 opCall support UFCS, so I don't see a good reason for the normal struct opCall
 to not support it:
I had no idea these worked. I'm really wondering whether this was introduced on purpose.. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 02 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9857






 I had no idea these worked. I'm really wondering whether this was introduced on
 purpose..
They are useful to not break UFCS chains. I'd even like typeof() to be usable with that trailing syntax, like sizeof, see Issue 4272 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 02 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9857






 I'd even like typeof() to be usable with that trailing syntax, like sizeof, see
 Issue 4272
The U of UFCS means universal. And ctors too are functions. So it's expected. This silly example of random bigint creation shows why they are handy in UFCS chains: import std.stdio, std.bigint, std.algorithm, std.random, std.ascii, std.range, std.array; void main() { auto b1 = 20.iota.map!(_ => digits[uniform(0, $)]).array.BigInt; b1.writeln; } auto b1 = 20 .iota .map!(_ => digits[uniform(0, $)]) .array .BigInt; If struct ctors don't support UFCS you have to wrap everything in a BigInt, and it gets harder to read: auto b1 = BigInt(20.iota.map!(_ => digits[uniform(0, $)]).array); And those columns look bad: auto b1 = BigInt(20 .iota .map!(_ => digits[uniform(0, $)]) .array .BigInt); -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 02 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9857






 And those columns look bad:
 
     auto b1 = BigInt(20
                      .iota
                      .map!(_ => digits[uniform(0, $)])
                      .array
                      .BigInt);
Sorry, I meant: auto b1 = BigInt(20 .iota .map!(_ => digits[uniform(0, $)]) .array); -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 02 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9857


Andrej Mitrovic <andrej.mitrovich gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Platform|x86                         |All
         OS/Version|Windows                     |All



14:06:44 PDT ---


 
 I'd even like typeof() to be usable with that trailing syntax, like sizeof, see
 Issue 4272
The U of UFCS means universal. And ctors too are functions.
Well it probably stands for uniform, but I guess both are true.
 auto b1 = 20
           .iota
           .map!(_ => digits[uniform(0, $)])
           .array
           .BigInt;
That looks great.
 So it's expected.
I don't have a problem with the feature (it actually looks great with the ctor example you gave there), but it's hard to say what's expected when there's ZERO documentation for UFCS in the spec, which is ridiculous since we've had this feature for the last several years and it has just expanded in functionality ever since. Even TDPL barely talks about UFCS, and calls them "pseudo members". I really wish people who implement language features spent 10 minutes of their time writing documentation about it. As it stands, it seems only compiler hackers seem to know what language features actually exist and are expected to work. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 02 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9857


Jonathan M Davis <jmdavisProg gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jmdavisProg gmx.com



PDT ---
Personally, it feels very wrong to me that UFCS would work with constructors.
It's one thing to use it with normal free functions. It's quite another to do
stuff like this.

 I don't have a problem with the feature (it actually looks great with the ctor
 example you gave there), but it's hard to say what's expected when there's
 ZERO documentation for UFCS in the spec, which is ridiculous since we've had 
 this feature for the last several years and it has just expanded in 
 functionality ever since. Even TDPL barely talks about UFCS, and calls them 
 "pseudo members".
UFCS and pseudo members are two very different things as similar as they may appear. Arrays had UFCS. That was it. That was all that was ever planned for, and it may have been an accident that it worked in the first (I don't recall for sure). Some tried to claim that TDPL said that it was in the language, but all TDPL ever talked about was arrays, because that's all that there was and all that was planned for. The only reason that it was ever expanded beyond arrays was because people kept asking for it. It hasn't existed for very long, and it was never really planned out AFAIK. Certainly, stuff like whether it should work with overloaded operators or constructors or anything other than basic free functions was never discussed or designed. It was just implemented with the idea that it would work with free functions like arrays had been doing, and the implications of that and the various corner cases were not necessarily considered or examined in detail. So, if anything, the problem is that the feature was ever implemented without being designed first, and while it _should_ be properly documented by now, it's also a semi-recent feature, so it's not particularly surprising that it's not given how things work around here. But it _has_ been months (probably over a year now, though I'm not sure) since it was introduced, so there's really not much excuse for it not being documented other than the fact that the spec is rarely kept up-to-date (which is just indicative of a larger problem). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 02 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9857





 Personally, it feels very wrong to me that UFCS would work with constructors.
Do you want to explain why? (Constructors are functions, so why introduce an asymmetry.) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 02 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9857




PDT ---
 Do you want to explain why?
 (Constructors are functions, so why introduce an asymmetry.)
In great part because they're _not_ normal functions. They're constructors. They're also not free functions, and the whole idea with UFCS was that it would work with free functions so that you could act like the function was a member of the type of its first argument. It allowed you to essentially add member functions to a type, and therefore be able to not care whether a function was implemented on a type or as a free function, thereby making code more generic. This is trying to take UFCS beyond free functions, and it makes no sense for a constructor to be treated as a member function of another type, because it never could have been implemented as a member function of that type in the first place. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 02 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9857


Maxim Fomin <maxim maxim-fomin.ru> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |maxim maxim-fomin.ru



---

 I really wish people who implement language features spent 10 minutes of their
 time writing documentation about it. As it stands, it seems only compiler
 hackers seem to know what language features actually exist and are expected to
 work.
This is a good description of how D project is organized, I often face some strange behavior of dmd and such idea comes to my mind. Regarding issue - I think that it moves UFCS beyond its purpose and looks like extending UFCS for operator overloaded function which I consider a bad idea. Better option I think is to move discussion to forum or to write a DIP which has recommended itself as a structured process of proposing. Bugzilla and github discussions are not suitable for significant language changes (do you remember threads about alias T = A syntax after semi-silent depreciation in git pull?). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 02 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9857




23:15:54 PDT ---

 Some tried to claim that TDPL said that it was in the language, but
 all TDPL ever talked about was arrays, because that's all that there was and
 all that was planned for. The only reason that it was ever expanded beyond
 arrays was because people kept asking for it.
That's complete BS. Read the fine-print, it clearly says on page 156: "If a.fun(b, c, d) is seen but fun is not a member of a's type, D rewrites that as fun(a, b, c, d) and tries that as well." It doesn't matter that the page talked about arrays beforehand. It says right there "a's type", it doesn't say "array type". But note that it also says: "The opposite path is never taken: if you write fun(a, b, c, d) and it does not work, a.fun(b, c, d) is not tried" So this could be interpreted against this enhancement request, although TDPL has been made wrong before..
 But it _has_ been months (probably over a
 year now, though I'm not sure)
The oldest changelog entry I can find about UFCS is for version 2.055, which was released Sep 4 2011, and this is for a bug that was filed March 03 2011. And the oldest UFCS bug was filed in 2006: Issue 662 We've had UFCS for years. It's been a feature years in the making, it should have documentation by now. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 02 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9857






 Better option I think is to move discussion to forum or to write a DIP
OK: http://forum.dlang.org/thread/mxsipaadpufujicmerjn forum.dlang.org -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 08 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9857




For potential downsides see also:

http://forum.dlang.org/thread/sdffgyosxmfjjjrshajy forum.dlang.org

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 02 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9857


timon.gehr gmx.ch changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |timon.gehr gmx.ch



The discussion is misguided. opCall is compatible with UFCS already. I suggest
to close this down and to open a more detailed enhancement request for using
local symbols with UFCS instead if that is desired.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 03 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9857


bearophile_hugs eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |WORKSFORME




 The discussion is misguided. opCall is compatible with UFCS already.
Right, I didn't realize this works: struct Foo { int opCall(bool b) { return 0; } } Foo foo; void main() { auto b1 = foo(true); // OK auto b2 = true.foo; // Error }
 I suggest to close this down
OK, closed.
 and to open a more detailed enhancement request for using
 local symbols with UFCS instead if that is desired.
That's a quite different need. It needs more thinking. Thank you for the note. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 03 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9857




---

 and to open a more detailed enhancement request for using
 local symbols with UFCS instead if that is desired.
That's a quite different need. It needs more thinking. Thank you for the note.
UFCS is designed not work for local symbols. https://github.com/D-Programming-Language/dlang.org/pull/346 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 06 2013