What is the reasoning behind the lack of conversions when passing parameters

Carl Sturtivant sturtivant at gmail.com
Fri Feb 2 23:49:21 UTC 2024


On Friday, 2 February 2024 at 22:02:30 UTC, Jonathan M Davis 
wrote:
> However, I'm pretty sure what it comes down to is that it 
> simplifies function overloading (which can get fairly complex 
> in C++ thanks to it allowing such conversions).

Those complications could have been embraced *because* parameter 
passing and initialization are best kept to exactly the same 
semantics when there is no overloading. And that would force a 
system of overloading compatible with such that extends naturally 
when an additional function of the same name is added, that works 
without changing the semantics of the others. C++ can do it. So D 
can.

Overloading is complicated anyway, so pushing the complications 
into there rather than crippling parameter passing is making the 
language more effective. Scripting naively with Variant from 
std.variant would just work for example.

> It also reduces the number of bugs that you get from implicit 
> conversions (though we do have alias this). By having alias 
> this without the implicit construction with function arguments, 
> we make it so that the conversion is only in one direction, 
> whereas if we also allowed conversion based on constructors, 
> then it would complicate the choices considerably in some cases.

Why is `alias this` conversion permitted with parameter passing? 
Why isn't the no conversion restriction applied there? Your 'not 
onerous' argument below could be applied, and the name from the 
`alias this` declaration could have to be explicitly used. And 
that would affect only types that have alias this, not 
*everything* which is what the current restriction affects. Seems 
like the wrong decision.

For consistency with initialization, `alias this` conversions 
could be disabled for initialization too. Interaction with 
constructors occurs there and for the same reasons.

Initialization and parameter passing parallel one another 
naturally, and that simplicity has been broken in D's design.

> And if you want to pass something to a function where 
> construction is required, it's as simple as calling the 
> constructor, which isn't particularly onerous, and it makes the 
> code easier to understand.

However, this makes a mess of D's versatility, for example with 
naive scripting using Variant.

Or standalone functions that carry their own imports (including 
for parameter types using `imported!()` from object) that when 
pasted into other code need to have modules containing their 
parameter types imported before they can be used, so constructors 
can be called to pass parameters to them.

Working around this design decision in some more-than-trivial 
situations *is* onerous. Not all coding is in the context of big 
software projects. Versatility matters.

Someone might reasonably expect parameter passing and 
initialization to have the same semantics: after all, parameter 
passing /is/ initialization of parameters to arguments.

D lacking this possibility in some form seems to be a design 
mistake.




More information about the Digitalmars-d mailing list