ADL

Manu via Digitalmars-d digitalmars-d at puremagic.com
Sat Sep 3 02:31:59 PDT 2016


On 3 September 2016 at 11:09, Walter Bright via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
>
> First solution:
>
>    module bob;
>    struct S {
>        void f();
>    }

This is my current workaround.
I'm not happy with it at all. UFCS exists for a reason.


> Second solution:
>
>     module user_code;
>     import bob, joe;
>     import myalgorithm;
>
>     mixin myalgorithm.test!S;
>     mixin myalgorithm.test!T;
>
>     void main()
>     {
>       test(S.init);
>       test(T.init);
>     }

You're not serious, right?
I just want to call a function... functions should be functions, not
mixin templates!


> Third solution:
>
>     module myalgorithm;
>     void test(M,T)(T t)
>     {
>         M.f(t);
>     }
>
>     module user_code;
>     import bob, joe;
>     import myalgorithm;
>
>     void main()
>     {
>       test!bob(S.init);
>       test!joe(T.init);
>     }

Another crazy workaround.
Users should not be expected to manually pass scope's around the place
to perform a name lookup.
Try and explain that to a normal programmer.


> Fourth solution:
>
>     module myalgorithm;
>
>     void test(T)(T t)
>     {
>         import std.traits;
>         mixin("import " ~ std.traits.moduleName!T ~ ";");
>         mixin("alias M = " ~ std.traits.moduleName!T ~ ";");
>         // The above could be encapsulated into an eponymous template
>         // that takes T as a parameter and returns the alias
>
>         M.f(t);
>     }
>
> What makes them problematic or highly unsavory? I thought #4 in particular
> was rather cool, I plan to use it as an example.

I also had this idea as workaround, but you can't seriously think this is okay?
Importing an entire module at the point I want to call a function is crazy.
I don't want to import _everything_ from T's module into my local
namespace; that could easily lead to conflicting names in the local
scope which would now require disambiguation.
This surely represents a far higher probability of name collisions
than the theoretical accidental collision that could come from ADL.
The ADL style collision isn't accidental though, that's _the whole point_.


>> or had any problems with ADL
>
>     https://en.wikipedia.org/wiki/Argument-dependent_name_lookup#Criticism
>
> Essentially, ADL has awkward problems when getting beyond the simple cases.
> It isn't right for D.

D requires ADL so much more than C++ does, because the things ADL does
in C++ are absolute concrete advertised core value propositions of D.


> ADL has the problems I provided a link to.

It's never caused me a problem, in like, 15 years or more. This
situation in D causes me problems all the time.


> In any case, these difficulties are the consequence of trying to write C++
> code in D.

You've told me this before, and I find it kind of offensive every time
you do, since I've been programming D for like 7 years now, and I
definitely don't code D like C++.
If anything, I have a strong tendency to code C++ like D, and that has
lead to a lot of interesting changes in my C++ style.

I'm tired of these sorts of dismissals. You insist that I'm not a
'real' D programmer, or something to that effect.

This problem consistently arises when I try to commit to go all in on
ranges+UFCS pipeline style programming. There's nothing C++-ey about
that. C++ can barely do it. It is the advertised mission of modern D
programmers to write code this way, and it's the exact area where the
problem I'm trying to express breaks down.

The interesting part is, when I do try and code this way in C++ (which
is brutal, it's all SFINAE based template constraints and stuff), it
actually _works_, simply because ADL works.

Pipeline programming is a core value proposition for D, as are
uber-powerful templates which leads to making algorithms out of
everything.


> None of the algorithms used in std.algorithm or elsewhere in
> Phobos have this particular issue. Nor have I seen ADL supported in any
> other language, despite many supporting generic algorithms.

std.algorithm is extremely simple, it doesn't do anything except raw
algorithm-ey stuff. It doesn't attempt to invoke functionality on the
data it's working on.

Right now I'm working on image processing. There are lots of image
data types, and they all have things like interpolation and blending
functions. Write an image processing algorithm that calls out to lerp
or blend, and you'll run into these problems instantly.
I was writing some audio software some time back, again, trying to use
stream processing extensively because it's a perfect match for that
workload, but same problem!

Write an algorithm that does _work_, rather than does algorithm logic,
and you can't miss this problem. You need to call associated functions
to do work.


> I do understand trying to write C++ code in D, because my early FORTRAN
> programs looked like BASIC, my early C programs looked like FORTRAN, my C++
> code looked like C, etc.

Again, stop this. It's insulting, and it really pisses me off.
I'm writing textbook modern D, which is code that you can't even express in C++.


> What I have provided is a generic way to make ADL work in D, which shows how
> adaptable it is.

I never said D wasn't adaptable and capable of madhax. I understand
very well that D is powerful enough to find a possible work-around for
basically anything. You wouldn't believe some of the hacks I'm
responsible for! (mostly relating to ref! >_<)
It's useful once in a while, but once some particular hax present
themselves as rule rather than the excepsion, you find yourself
effectively engaged in writing boilerplate. Just like C, but a
different kind of boilerplate, and for my money; extremely more
complex boilerplate than C/C++, which only experts can read and
understand. I am absolutely not okay with that sort of madhax.


More information about the Digitalmars-d mailing list