digitalmars.D.bugs - [Issue 7802] New: UFCS functions get lost when type is transmitted to template
- d-bugmail puremagic.com (38/38) Mar 30 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7802
- d-bugmail puremagic.com (7/7) Mar 30 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7802
- d-bugmail puremagic.com (11/11) Mar 31 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7802
- d-bugmail puremagic.com (14/14) Mar 31 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7802
- d-bugmail puremagic.com (14/14) Apr 01 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7802
- d-bugmail puremagic.com (22/22) Apr 04 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7802
- d-bugmail puremagic.com (11/12) Apr 04 2012 I thought this too, although the need to extend unknown types
- d-bugmail puremagic.com (26/34) Apr 04 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7802
- d-bugmail puremagic.com (34/34) Apr 05 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7802
- d-bugmail puremagic.com (10/13) Apr 05 2012 http://d.puremagic.com/issues/show_bug.cgi?id=7802
http://d.puremagic.com/issues/show_bug.cgi?id=7802 Summary: UFCS functions get lost when type is transmitted to template Product: D Version: D2 Platform: All OS/Version: All Status: NEW Severity: normal Priority: P2 Component: DMD AssignedTo: nobody puremagic.com ReportedBy: bugzilla digitalmars.com --- Comment #0 from Walter Bright <bugzilla digitalmars.com> 2012-03-30 23:10:11 PDT --- a.d ------------- void foo(T)(T t) { t.func(); } ------------- test.d ------------- class C { } void func(C c) { } void test(C c) { foo(c); ------------- This fails to compile because a.d doesn't know about test.func(C c), and so does not find it when attempting to resolve t.func() using UFCS. The solution is to: If func() is not found as a member function of t, then look in the template instantiation scope for a func(t). If found, use that as the UFCS function, and then mark the template instantiation as LOCAL to the instantiation context. This will ensure that the mangled name of the instantiation will not conflict with other instantiations of foo(T) with other func(T) functions. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 30 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7802 --- Comment #1 from Walter Bright <bugzilla digitalmars.com> 2012-03-30 23:12:06 PDT --- More details: http://forum.dlang.org/post/op.wbyg2ywyeav7ka localhost.localdomain -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 30 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7802 timon.gehr gmx.ch changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |timon.gehr gmx.ch --- Comment #2 from timon.gehr gmx.ch 2012-03-31 04:22:31 PDT --- What happens if there is an UFCS match both in the instantiation scope and the template declaration scope? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 31 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7802 dawg dawgfoto.de changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |dawg dawgfoto.de --- Comment #3 from dawg dawgfoto.de 2012-03-31 10:28:47 PDT --- That smells like a very hacky special case. Picking up symbols from the instantiation scope is very ambivalent. I'd argue that importing test in class C should fix the UFCS behavior, but it currently doesn't because func is found as a member of C. class C { import test; } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 31 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7802 deadalnix <deadalnix gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |deadalnix gmail.com --- Comment #4 from deadalnix <deadalnix gmail.com> 2012-04-01 23:23:20 PDT --- As mentioned in the newsgroup, templates instantiation and UFCS are 2 orthogonal problems and must be treated as such. The function can be passed as template parameter, the module name to import as a string (and imported via mixin("import " ~ moduleName); ) or whatever. Before trying to solve that problem, we'd better be sure this is a problem. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 01 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7802 Steven Schveighoffer <schveiguy yahoo.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |schveiguy yahoo.com --- Comment #5 from Steven Schveighoffer <schveiguy yahoo.com> 2012-04-04 07:30:43 PDT --- I would suggest instead of using the instantiation scope, use the scope of the defined type. Then the notion of "LOCAL" templates is not needed. For example, if struct S is defined in foo.d, and you instantiate template function func in bar.d: void func(T)(T t) { t.baz(); } and baz is not a member function, look it up from two scopes -- the template definition scope (i.e. bar.d) and the scope where S is defined (i.e. foo.d). This means S's API, including UFCS, is identical no matter where you use it from. Prefer type definition scope over template definition scope, to keep the type's API intact. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 04 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7802 --- Comment #6 from dawg dawgfoto.de 2012-04-04 11:11:46 PDT ---look it up from two scopes -- the template definition scope (i.e. bar.d) and the scope where S is defined (i.e. foo.d).I thought this too, although the need to extend unknown types at the template scope will be limited. There is one important use-case where this fails though. Extending library types so that they fit a library template, e.g. to use std.stream.Stream with std.algorithm.find I need to modify phobos. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 04 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7802 --- Comment #7 from Steven Schveighoffer <schveiguy yahoo.com> 2012-04-04 11:33:27 PDT --- (In reply to comment #6)Templates already introduce a large level of binary incompatibility. This proposal of LOCAL templates will make it even worse, to the point where possibly no binary compatibility will be feasible as long as UFCS is involved. consider that I could import some module that declares a UFCS method foo. Then I call a template function that uses this method. In another module, I also import the same module for foo, call the same template, which generates the exact same code for the exact same function, but now has TWO identical instantiations based on the instantiating module's name.look it up from two scopes -- the template definition scope (i.e. bar.d) and the scope where S is defined (i.e. foo.d).I thought this too, although the need to extend unknown types at the template scope will be limited.There is one important use-case where this fails though. Extending library types so that they fit a library template, e.g. to use std.stream.Stream with std.algorithm.find I need to modify phobos.You can do this probably with alias this. But one thing I am concerned about is how a type can arbitrarily take on different API depending on the modules you import. It makes things confusing and unexpected. I'd rather have the type define what API it takes, along with the template, who is obviously free to extend any types it wants. My main concern with UFCS is about the use case where we have an existing method m, which I want to move outside the class or struct (for whatever reason). Both Walter's and my proposals should cover this case, but mine I think does it without adding unnecessary bloat or complexity to the name mangling system. My proposal is also a subset of Walter's. That is, we could *still* go the LOCAL template route later without breaking existing code. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 04 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7802 --- Comment #8 from Kenji Hara <k.hara.pg gmail.com> 2012-04-05 01:01:35 PDT --- There is two different situations around template instantiations and UFCS. See following example. --- kernel.d --- struct S { int val; } property int foo(ref S s) { return s.val; } --- extra.d --- import kernel; property int bar(ref S s) { return s.val * 2; } --- util.d --- auto testfoo(T)(T t) { return t.foo; } auto testbar(T)(T t) { return t.bar; } --- test.d --- import kernel, extra, util; void main() { auto s = S(1); assert(s.foo == 1); // mod.foo(s), OK assert(s.bar == 2); // extra.bar(s), OK assert(testfoo(s) == 1); // cannot instantiate assert(testbar(s) == 2); // cannot instantiate } Walter's suggestion supports both testfoo and testbar, but I'm afraid that it causes code bloating. Steven's suggestion supports testfoo, but cannot support testbar. I think Steven's way and the case of testfoo is similar to C++ ADL. But in D, a namespace associated with a module is not opened, so unintended name lookup isn't in there. But, the case of testbar requires making relations between kernel and extra modules in test.d module. For now I have no idea about it. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 05 2012
http://d.puremagic.com/issues/show_bug.cgi?id=7802 --- Comment #9 from Steven Schveighoffer <schveiguy yahoo.com> 2012-04-05 04:53:22 PDT --- (In reply to comment #8)Walter's suggestion supports both testfoo and testbar, but I'm afraid that it causes code bloating. Steven's suggestion supports testfoo, but cannot support testbar.What about a compromise? testfoo will be compiled without the LOCAL moniker, but testbar will compile with it. In other words, implement both ideas. In any case, you will be probably doing the same underlying work for both solutions to determine what scope is necessary to do a symbol lookup. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 05 2012