November 14, 2012
On Wednesday, November 14, 2012 13:05:41 Gor Gyolchanyan wrote:
> Actually the (x) => y style delegates compute their return type exactly by
> looking at the left-hand side. This exact thing is already being done. If
> the ambiguity cannot be resolved, the return type is explicitly set OR the
> result is casted to a type.
> Having normal functions behave this way doesn't add anything new. This
> already exists.

I think that you're wrong about that. (x) => y lambdas are no different from any other delegate literals save for  their syntax. The type of x is dependent on what's being passed to it, and the type of y depends on x and what the function does. It shouldn't have any need whatsoever to look at the expression that the lambda is being used in, just what's passed to it.

- Jonathan M Davis
November 14, 2012
On 11/13/2012 1:34 PM, Rob T wrote:
> I'm wondering why overloading has been implemented to only match on the argument
> list rather than the full signature which includes the return type? I know I
> would use it if it was available.
>
> I'm not requesting this to be a feature of D, I'm only asking why it is not
> being done.

Because types are resolved bottom-up, and if the return type were part of the overloading, there would be no sensible rule to determine the types.

November 14, 2012
On Wednesday, 14 November 2012 at 09:16:13 UTC, Walter Bright wrote:
>> I'm not requesting this to be a feature of D, I'm only asking why it is not
>> being done.
>
> Because types are resolved bottom-up, and if the return type were part of the overloading, there would be no sensible rule to determine the types.

But doesn't the compiler already have to perform overload-like decision making on return types in the "alias this" case, esp once multiple conversions are allowed?

class A{
  int i;
  bool b;
  alias i this;
  alias b this;
}

main()
{
  auto a = new A;
  int i = a;
  bool b = a;
}

--rt
November 14, 2012
On Tuesday, 13 November 2012 at 21:34:28 UTC, Rob T wrote:
> I'm wondering why overloading has been implemented to only match on the argument list rather than the full signature which includes the return type? I know I would use it if it was available.
>
> I'm not requesting this to be a feature of D, I'm only asking why it is not being done.
>
> --rt

This is hardly a new idea. It was implemented in a few languages of the 70's and it proved to be adding complexity and generally not worth the trouble. No language nowadays bothers with this based on those past lessons.
November 14, 2012
On Wednesday, 14 November 2012 at 06:52:57 UTC, Rob T wrote:
> In C++ there are conversion operators, which are not exactly the same as function overloading, but the correct function is selected based on the type on the left hand side.
>
> Example
>
> class A
> {
>    operator bool(){ return _b; }
>    operator int(){ return _i; }
>    int _i; bool _b;
> }
>
> A a;
> bool b = a; // executes bool()
> int i = a; // executes int()
>
> Is there anything like C++ conversion operators in D? I have used conversion ops in C++ and may want to use a similar feature in D if available.
>
>
> --rt

Not really, that has *nothing* to do with "the correct function is selected based on the type on the left hand side", but just C++ trying to match the signature of the constructor it is trying to call. As a matter of fact, as a rule of thumb, there is no "left hand side" for the compiler. Just functions and arguments.

It is absolutely no different from:
//----
void foob(bool);
void fooi(int);
A a;
foob(a); //Executes bool()
fooi(a); //Executes int()
//----
November 14, 2012
On Wednesday, 14 November 2012 at 06:52:57 UTC, Rob T wrote:
> In C++ there are conversion operators, which are not exactly the same as function overloading, but the correct function is selected based on the type on the left hand side.
>
> Example
>
> class A
> {
>    operator bool(){ return _b; }
>    operator int(){ return _i; }
>    int _i; bool _b;
> }
>
> A a;
> bool b = a; // executes bool()
> int i = a; // executes int()
>
> Is there anything like C++ conversion operators in D? I have used conversion ops in C++ and may want to use a similar feature in D if available.
>
>
> --rt

Not really, that has *nothing* to do with "the correct function is selected based on the type on the left hand side", but just C++ trying to match the signature of the constructor it is trying to call. As a matter of fact, as a rule of thumb, there is no "left hand side" for the compiler. Just functions and arguments.

It is absolutely no different from:
//----
void foob(bool);
void fooi(int);
A a;
foob(a); //Executes bool()
fooi(a); //Executes int()
//----
November 14, 2012
On 11/14/2012 06:30 PM, Rob T wrote:
> On Wednesday, 14 November 2012 at 09:16:13 UTC, Walter Bright wrote:
>>> I'm not requesting this to be a feature of D, I'm only asking why it
>>> is not
>>> being done.
>>
>> Because types are resolved bottom-up, and if the return type were part
>> of the overloading, there would be no sensible rule to determine the
>> types.
>
> But doesn't the compiler already have to perform overload-like decision
> making on return types in the "alias this" case, esp once multiple
> conversions are allowed?
>
> class A{
>    int i;
>    bool b;
>    alias i this;
>    alias b this;
> }
>
> main()
> {
>    auto a = new A;
>    int i = a;
>    bool b = a;
> }
>
> --rt

alias this is not the best example, but the necessary logic is basically already in the compiler. Lambda parameter type deduction based on the expected type is a similar task.

It is not being done because it is not being done. Full type inference would be even more fun.
November 14, 2012
On 11/14/2012 06:43 PM, foobar wrote:
> On Tuesday, 13 November 2012 at 21:34:28 UTC, Rob T wrote:
>> I'm wondering why overloading has been implemented to only match on
>> the argument list rather than the full signature which includes the
>> return type? I know I would use it if it was available.
>>
>> I'm not requesting this to be a feature of D, I'm only asking why it
>> is not being done.
>>
>> --rt
>
> This is hardly a new idea. It was implemented in a few languages of the
> 70's and it proved to be adding complexity and generally not worth the
> trouble.

I guess they just were not doing it right then.

> No language nowadays bothers with this based on those past lessons.

Haskell.

> fromInteger 2 :: Float
2.0
November 15, 2012
On Wednesday, 14 November 2012 at 19:12:59 UTC, Timon Gehr wrote:
> On 11/14/2012 06:43 PM, foobar wrote:
>> On Tuesday, 13 November 2012 at 21:34:28 UTC, Rob T wrote:
>>> I'm wondering why overloading has been implemented to only match on
>>> the argument list rather than the full signature which includes the
>>> return type? I know I would use it if it was available.
>>>
>>> I'm not requesting this to be a feature of D, I'm only asking why it
>>> is not being done.
>>>
>>> --rt
>>
>> This is hardly a new idea. It was implemented in a few languages of the
>> 70's and it proved to be adding complexity and generally not worth the
>> trouble.
>
> I guess they just were not doing it right then.
>
>> No language nowadays bothers with this based on those past lessons.
>
> Haskell.
>
> > fromInteger 2 :: Float
> 2.0

I thought that Haskell doesn't have function overloading (which simplifies this greatly)... Anyway, I mostly meant "standard" imperative/OO languages. Sorry for the confusion.
November 15, 2012
I've been wondering for a couple of years about why overloading stops at the argument sig in almost all languages, but so far I have not seen a good reason why this must be so.

From what I've read so far, the reason why full overloading is not being done, is because it is not being done. Other than that, I don't have an answer as to why it is not being done because clearly it can be done, and the compiler certainly has the means to do it already, otherwise it could not err when you assign a function return type to the wrong type on the LHS, ie, it most certainly is able to determine what the full signature is at some point.

So does anyone really know why it is not being done? The "it's too complicated" argument seems weak to me since the compiler already has to check for both matching argument sig as well as the return type, and it already does overloading on the argument sig. I figure "it's too complicated" only because the compiler was initially designed without taking full signature overloading into account from the very start, otherwise it would be not much more complicated than the regular overloading that we have now.

The argument that the compiler will get too confused seems a bit weak as well, since the compiler can already get confused with argument sig overloading, and there are certainly methods of working this out, otherwise function overloading would not work as it is now. At the end of the day, if the compiler cannot figure it out, then it errs, just as it does now when it cannot figure it out. There's already an incalculable number of ways a programmer can mess up a valid compile, so adding one more possible way to the already massive pile cannot be used as a reason why it should not be done.

I could argue that overloading only on function sig is too complicated and not worth it, but we have it, and it is useful to at least some or most people, so why did we stop at the argument sig and not go all the way? Is there a theoretical reason why we should stop, are their use cases that have shown that it fails to help the programmer or makes programming more difficult?

--rt