Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
February 11, 2014 Disappointing inflexibility of argument passing in D | ||||
---|---|---|---|---|
| ||||
D has opAssign, making defining implicit conversions from any type to a new type possible on assignment, so where is the analogue (say opPass) for passing an argument to a function? void f( Data d, Data2 d2) { ..... } void main() { //conversions from string part of the definitions of Data, Data2 f( "hello", "bonjour"); //no way to do this --- disappointing } See http://forum.dlang.org/thread/agstjpezerwlgdhphclk@forum.dlang.org |
February 11, 2014 Re: Disappointing inflexibility of argument passing in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carl Sturtivant | On Tuesday, 11 February 2014 at 15:10:57 UTC, Carl Sturtivant wrote:
> void main() {
> //conversions from string part of the definitions of Data, Data2
> f( "hello", "bonjour"); //no way to do this --- disappointing
> }
>
> See
> http://forum.dlang.org/thread/agstjpezerwlgdhphclk@forum.dlang.org
Function calls are a more complicated case because of overload resolution.
If f(string, string) is defined, this will a) break silently or b) require qualification. Both is disappointing, too.
|
February 11, 2014 Re: Disappointing inflexibility of argument passing in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tobias Pankrath | On Tuesday, 11 February 2014 at 15:57:33 UTC, Tobias Pankrath wrote:
> On Tuesday, 11 February 2014 at 15:10:57 UTC, Carl Sturtivant wrote:
>> void main() {
>> //conversions from string part of the definitions of Data, Data2
>> f( "hello", "bonjour"); //no way to do this --- disappointing
>> }
>>
>> See
>> http://forum.dlang.org/thread/agstjpezerwlgdhphclk@forum.dlang.org
>
> Function calls are a more complicated case because of overload resolution.
>
> If f(string, string) is defined, this will a) break silently or b) require qualification. Both is disappointing, too.
I do not understand why your (a) and (b) provably must be so. Please supply an argument: there seem to be other possibilities and without a proof that there are not, we may as well seek to do the right thing.
In the absence of such comprehension on my part, it seems to me that what's needed are some consistent rules that generalize the overloading rules about the interaction of opPass and overloading, with some priorities so that the best match is found. Perhaps some combinations of opPass and overloading should be illegal. Not that I've thought this through. :)
But is there a good reason why there isn't a reasonable such set of rules in principle? And if not, why do we not have opPass? Overtly converting all over the place is less than a happy situation.
|
February 11, 2014 Re: Disappointing inflexibility of argument passing in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carl Sturtivant | On 2/11/14, 7:10 AM, Carl Sturtivant wrote:
>
> D has opAssign, making defining implicit conversions from any type to a
> new type possible on assignment, so where is the analogue (say opPass)
> for passing an argument to a function?
>
> void f( Data d, Data2 d2) { ..... }
>
> void main() {
> //conversions from string part of the definitions of Data, Data2
> f( "hello", "bonjour"); //no way to do this --- disappointing
> }
>
> See
> http://forum.dlang.org/thread/agstjpezerwlgdhphclk@forum.dlang.org
Hmmm... very interesting. I was thinking of the same these days because we have qualifier(T[]) automatically change to qualifier(T)[] upon passing to a function. However, there is no way for the user to specify such type change for a user-defined type.
Adding some sort of opPass would help solve the current problem we have with passing const ranges into functions. (Currently they won't work unless they're built-in slices).
Andrei
|
February 11, 2014 Re: Disappointing inflexibility of argument passing in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carl Sturtivant | On Tuesday, 11 February 2014 at 15:10:57 UTC, Carl Sturtivant wrote:
>
> D has opAssign, making defining implicit conversions from any type to a new type possible on assignment, so where is the analogue (say opPass) for passing an argument to a function?
>
> void f( Data d, Data2 d2) { ..... }
>
> void main() {
> //conversions from string part of the definitions of Data, Data2
> f( "hello", "bonjour"); //no way to do this --- disappointing
> }
>
> See
> http://forum.dlang.org/thread/agstjpezerwlgdhphclk@forum.dlang.org
In the meanwhile maybe you can try a workaround with templates? Something like:
void f(D1, D2)(D1 d, D2 d2) if (is(D1:Data) && is(D2 : Data2))
{
// Temp vars and assignment
...
...
f(tmpD1, tmpD2);
}
|
February 11, 2014 Re: Disappointing inflexibility of argument passing in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carl Sturtivant | On Tuesday, 11 February 2014 at 16:29:01 UTC, Carl Sturtivant wrote: > On Tuesday, 11 February 2014 at 15:57:33 UTC, Tobias Pankrath wrote: >> On Tuesday, 11 February 2014 at 15:10:57 UTC, Carl Sturtivant wrote: >>> void main() { >>> //conversions from string part of the definitions of Data, Data2 >>> f( "hello", "bonjour"); //no way to do this --- disappointing >>> } >>> >>> See >>> http://forum.dlang.org/thread/agstjpezerwlgdhphclk@forum.dlang.org >> >> Function calls are a more complicated case because of overload resolution. >> >> If f(string, string) is defined, this will a) break silently or b) require qualification. Both is disappointing, too. > > I do not understand why your (a) and (b) provably must be so. Please supply an argument: there seem to be other possibilities and without a proof that there are not, we may as well seek to do the right thing. I have code that executes f(Data, Data), but I'm actually passing (string, string). Now someone of my coworkers defines f(string, string), which is visible to my code. I see two possibilities: My codes executes the new function f, which silently brakes my program or the compiler says that two possible overloads are in place and requires explicit qualification of the correct function (I'm probably back to f(Data(), Data()). What is the third way you have in mind? > In the absence of such comprehension on my part, it seems to me that what's needed are some consistent rules that generalize the overloading rules about the interaction of opPass and overloading, with some priorities so that the best match is found. Perhaps some combinations of opPass and overloading should be illegal. Not that I've thought this through. :) I'm just saying that it is more complicated that simple assignment. |
February 11, 2014 Re: Disappointing inflexibility of argument passing in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tobias Pankrath | > I have code that executes f(Data, Data), but I'm actually passing (string, string). Now someone of my coworkers defines f(string, string), which is visible to my code. I see two possibilities: My codes executes the new function f, which silently brakes my program or the compiler says that two possible overloads are in place and requires explicit qualification of the correct function (I'm probably back to f(Data(), Data()).
>
> What is the third way you have in mind?
Concretely the latter sounds right in that specific case, but I
have not endeavored to design new overloading rules that include
the effects of opPass.
Overloading should be confined to one module (I distantly recall
there is some restriction in this area). And when overloading,
knowledge of how the rules apply to the existing functions of the
same name should be used by the function writer.
Actually there are already conversions, like passing int to long.
How do they interact with overloading? This is a prototype of
sorts. This already causes the kind of overloading interference
in your example.
opPass provides a property of a data type, and anyone using that
type should know about such a property before writing functions
that take arguments of that type.
People writing overloaded functions with types alien to types
with opPass should be aware of the overloading rules, and should
search for functions that may compete with their overload,
including looking for opPass conversions in parameter types of
such functions. Documentation should reveal such conversions to
help out. Overloading is usually not a problem anyway, because
people keep it simple.
opPass is too important to refuse because now it's possible for
it to cause some minor trouble if care isn't taken to notice
which function(s) I am overloading!
Carl.
|
February 12, 2014 Re: Disappointing inflexibility of argument passing in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Tuesday, 11 February 2014 at 16:38:41 UTC, Andrei Alexandrescu wrote: > Hmmm... very interesting. I was thinking of the same these days because we have qualifier(T[]) automatically change to qualifier(T)[] upon passing to a function. However, there is no way for the user to specify such type change for a user-defined type. > This is the #1 problem right now. > Adding some sort of opPass would help solve the current problem we have with passing const ranges into functions. (Currently they won't work unless they're built-in slices). > Is is not simply for functions. It is for any user defined type that embed a parametric types. This is why can't have a nice container library. |
February 12, 2014 Re: Disappointing inflexibility of argument passing in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrea Fontana | >
> In the meanwhile maybe you can try a workaround with templates? Something like:
>
> void f(D1, D2)(D1 d, D2 d2) if (is(D1:Data) && is(D2 : Data2))
> {
> // Temp vars and assignment
> ...
> ...
> f(tmpD1, tmpD2);
> }
Yes, that does the job.
|
Copyright © 1999-2021 by the D Language Foundation