On Thu, 17 Oct 2024, 12:01 Paul Backus via Digitalmars-d, <digitalmars-d@puremagic.com> wrote:
On Thursday, 17 October 2024 at 00:05:55 UTC, Manu wrote:
> Special-casing the constructor is just admitting that the
> overload selection mechanics are broken for **all other
> function calls**... It's not a matter of 'preference'; if the
> overload mechanics work properly then special casing the
> constructor wouldn't even be thinkable or raised in
> conversation. It's a hack; a really dumb hack which just leaves
> EVERY OTHER FUNCTION broken.
>
> The fact you have "no strong preference" surprises me, maybe
> I've misunderstood some way in which this is not a hack that's
> totally broken? Can you explain to me how every other function
> call isn't broken under the special-case-for-move-constructor
> solution? Overload selection has to work, it is basically the
> meat of this whole thing... there's not really anything else to
> it.

The reason overload selection is broken for constructors but not
for other functions is that "constructors" in D are really
several different kinds of functions lumped together into a
single overload set.

I can't imagine any other way. 
Here is a construction expression: 
  S(arg)

What kind of constructor that is completely depends on arg, and it's selected by overload resolution. That expression could be a copy, or a move, or just a normal initialisation from an unrelated argument...


These include

1. Initialization functions
2. Conversion functions
3. Copying functions

And in the future, we may add

4. Moving functions

There is no fundamental reason why these different kinds of
functions should share the same name and overload set.

Yes there is: 
  S(arg)

That's how you initialise an S... It's not a suite of separate concepts; it's just "initialise an S", and the proper constructor is selected by overload resolution.


Indeed,
there are languages where they do not--in Rust, for example,
conversion is done with `from` and `into`, and copying is done
with `clone`, with the constructor reserved solely for
initialization.

Our syntax is very clear: S(arg)

It is only because D forces the programmer to combine all of
these into a single overload set that the normal overload
resolution mechanism is insufficient, and we need a special case
to separate them again.

I still don't see it. There's no reason to separate them... why do you say they should be 'separated'? What does that even mean?