May 19, 2005
"TechnoZeus" <TechnoZeus@PeoplePC.com> wrote in message news:d6gv0k$qig$1@digitaldaemon.com...
>
*snip*
>
> This way, the function could be called as any type that it is capable of returning.
>
*snip*
>
> TZ
>
>

...or as type "void" when called without requesting a return value.

autotype hack()
{
     writef("testing..." \n);
     return 1;
     writef("not int .." \n);
     return 'a';
     writef("not char .." \n);
     return null;
}

int main()
{
     hack();  // technically returns 1, but hack.typeof is of type void in this context.
     return 0;
}


May 19, 2005
"Ben Hinkle" <ben.hinkle@gmail.com> wrote in message news:d6gmgp$jib$1@digitaldaemon.com...
>
> "James Dunne" <james.jdunne@gmail.com> wrote in message news:d6geed$d6b$1@digitaldaemon.com...
> >I think Walter has made it perfectly clear that he doesn't want return-type
> > function overloading in D, but I'm curious about it.
> >
> > I'm posting because I'd like to modify TinyCC's [http://tinycc.org/]
> > source code
> > to allow for return-type function overloading in the C language and play
> > around
> > with it.
> >
> > What I'd like to know is what types of pitfalls and gotchas are likely to
> > be
> > introduced to the compiler writer by allowing overloading based on
> > function
> > return type, especially in type casting and type promotion rules.  Are
> > there any
> > ambiguities that can be tackled easily?  Any signficantly difficult
> > challenges
> > involved?  Is it completely impossible to achieve with the current
> > language
> > design of C and its type system?
>
> It's probably not impossible to achieve since the expression tree is a ...
> well... tree. The algorithm would start at the root (if the root type is
> known) and leaves of the tree and start deducing types towards the middle
> and if they meet in a unique set of overload choices then the expression is
> allowed. Otherwise it is disallowed. And I bet it wouldn't be all that
> inefficient. It wouldn't be compatible with today's overloading choices
> since implicit casts will swing choices one way or another. For example
> today the code
>   int f(int x) {..}
>   short f(short x) {..}
>   int a;
>   short b;
>   a = f(b);
>   b = f(a);
> works fine. When you start overloading based on return value the choices are
> ambiguous if you start overload resolution based on the inputs or the
> outputs. So in "disallow anything non-unique" the code above wouldn't
> compile. The cast tricks would sort it out, though:
>   a = f(cast(int)b);
> for example.
>
> The problems probably aren't technical but philosophical. Should a C-like language do that? Would large programs written to use it be more or less buggy/confusing/hard-to-maintain? Would it replace buckets of template hackery? I don't know the answers there.
>
>

Implicit casts shouldn't be a problem.
Simply use the overload that requires the least modification of it's return type.
For example, if byte and short return types are available and int is requested,
then choose the overload that returns the shory type, since it is the less drastic integer promotion.
Okay, so an integer promotion is probably a bad example, but I can't think of a good one right now.
Hopefully, it still illustrates my point.

TZ


May 19, 2005
On Wed, 18 May 2005 19:33:13 -0600, Hasan Aljudy <hasan.aljudy@gmail.com> wrote:
> The problem with that is, you need to have the object /before/ you make the cast.

True, assuming you're actually casting, which we're not.

> The way I understand cst is: "take this chunck of memory, reinterpret it (or decode it) as if it was of this type", where "this type" is what you want to cast to.

Sure. That is a description of what cast 'does'.

I was simply saying that people use cast to disambiguate function calls already, extending it to do the same for functions overloaded by return-type is not a big step to make.

As I noted, it wouldn't actually cast anything.

>>  The objections seemed (to me to be) mostly differences of  definition/concept, i.e. the idea that cast's 'purpose' is to convert  data, not disambiguate function calls, so shouldn't be used here where no  'conversion' is actually required.
>>  The fact remains (in my opinion) that it is used to disambiguate function  calls, eg. (using my example above):
>>    foo(cast(int)a);
>>  Does the cast convert data? debatable, in reality it's simply looking at  less of the data in this case, it's not changing the data itself (like it  would/could from long to float).
>
> something like
> foo(5);
> is a call that passes constants. Now, literal constants are part of the language, and the type of a constant is determined by the language.

Yep.

> I think in C, 5 is an int, while 5.0 is a double.

Yep.

> I don't know what D does with that.

The same thing, I believe.

> But when you
> cast(int)5
> you are not removing ambiguity, you are writing an expression that returns an "int".

Technically you are correct. I'm saying there is another way to look at it and that is...

When you decide to use cast in this case it is because you want to call 'that' function with 'that' value, ideally an overload would exist and you'd have no problem, however one doesn't. You know from experience to use cast to cause the correct overload to be selected. In effect you're using cast to select an overload.

Technically cast causes it to cast the value, however primarily you don't care about the fact that it's casting, all you really care about is selecting the overload.

> The data is already vilable, it's 5, and when you cast it to an int, you   are essentially removing an ambiguity, but actually you are just writing an expression that returns a known type (hence no ambiguity).

Technically, correct.

>>  Is conversion the reason the programmer put it there? debatable, the  programmer simply wanted to call 'that' function with 'that' data.  Cast/conversion just happens to be the only way to do that.
>>  So, while return-type casting would not involve *any* conversion in *any*  sense, if the programmers intent is to call 'that' function then it's use  signals the same intent, IMHO.
>>  Other solutions involved inventing a new syntax for 'selecting an  overload'.
>>  Regan
>
> A better way maybe to introduce a new concept, that is, a new keyword, so instead of cast(type), we may say call(type) or something like that.
>
> But it would not be a "cast".

Like I said, oppostion to using cast previously all wanted another keyword. Personally, I have no problem re-using cast for this.

Regan
May 19, 2005
TechnoZeus wrote:
> "Hasan Aljudy" <hasan.aljudy@gmail.com> wrote in message news:d6gg2v$eb7$1@digitaldaemon.com...
> 
>>James Dunne wrote:
>>
>>>I think Walter has made it perfectly clear that he doesn't want return-type
>>>function overloading in D, but I'm curious about it.
>>>
>>>I'm posting because I'd like to modify TinyCC's [http://tinycc.org/] source code
>>>to allow for return-type function overloading in the C language and play around
>>>with it.
>>>
>>>What I'd like to know is what types of pitfalls and gotchas are likely to be
>>>introduced to the compiler writer by allowing overloading based on function
>>>return type, especially in type casting and type promotion rules.  Are there any
>>>ambiguities that can be tackled easily?  Any signficantly difficult challenges
>>>involved?  Is it completely impossible to achieve with the current language
>>>design of C and its type system?
>>>
>>>I'd really like to theoretically explore the area with you guys before I try to
>>>design it in and get frustrated and give up =P.  Note I haven't given the
>>>problem entirely much thought - just want to spark some interesting discussion.
>>>
>>>Regards,
>>>James Dunne
>>
>>I'm not expert on compilers, but here is an example where it won't work:
>>
> 
> *snip*
> 
> 
> Okay, here's a thought.  What it instead of complete overriding based on return type, it were made possible to
> include code in a function that would return more than once type, and any return statement that returns
> an incompatible type would simply be skipped over.  In the case where no return value is made use of,
> there would be no such thing as an incompatible return value, so the first return would encountered would be accepted.
> 
> autotype hack()
> {
>      writef("testing..." \n);
>      return 1;
>      writef("not int .." \n);
>      return 'a';
>      writef("not char .." \n);
>     return null;
> }
> 
> int main()
> {
>      char b;
>      b = hack(); // returns 'a' which is assigned to b.
>      hack(); // returns 1, which is discarded anyway.
>      return 0;
> }
> 
> This way, the function could be called as any type that it is capable of returning.
> 
> Obviously, not as versitile.. but quite possibly also not as troublesome.  A good compromise, perhaps?
> 
> Another interesting possibility would be to expose the requested return type of a function from within that function...
> 
> autotype hack()
> {
>      if (this.typeof == ...
> 
> TZ
> 
> 

The problem is not only what to return, it's what the function does.

and, what about:

real foo() {...}
int foo(){ .. }

void bar
{
    float x = cast(float)foo(){...} //which function to call? even we humans can't determine that, how would a compiler do it?
}

May 19, 2005
Regan Heath wrote:
> On Wed, 18 May 2005 19:33:13 -0600, Hasan Aljudy <hasan.aljudy@gmail.com>  wrote:
> 
>> The problem with that is, you need to have the object /before/ you make  the cast.
> 
> 
> True, assuming you're actually casting, which we're not.
> 

you said it, it's not a cast, so why would we use cast when we actually aren't casting anything?

>>
>> A better way maybe to introduce a new concept, that is, a new keyword,  so instead of cast(type), we may say call(type) or something like that.
>>
>> But it would not be a "cast".
> 
> 
> Like I said, oppostion to using cast previously all wanted another  keyword. Personally, I have no problem re-using cast for this.
> 
> Regan

The problem is, we probably don't want to just "hack" the language together.
Using "cast" to do something in special cases that's totally irrelevant to its meaning just because we use it for the same purpose for something else .... isn't exactly a good design IMHO.

Also, this doesn't really remove any ambiguity, look at this example:
###
int foo(){...}
real foo(){...}

void bar
{
    cast(int) foo(); //still ambigious
}
###
what are we doing here?
- calling the "real foo()" and casting it to "int"
or
- calling "int foo()"
?!

This is why "cast" is a hackish solution (it doesn't even work).
May 19, 2005
On Wed, 18 May 2005 21:34:36 -0600, Hasan Aljudy <hasan.aljudy@gmail.com> wrote:
> Regan Heath wrote:
>> On Wed, 18 May 2005 19:33:13 -0600, Hasan Aljudy <hasan.aljudy@gmail.com>  wrote:
>>
>>> The problem with that is, you need to have the object /before/ you make  the cast.
>>   True, assuming you're actually casting, which we're not.
>>
>
> you said it, it's not a cast, so why would we use cast when we actually aren't casting anything?

I said it "people use cast to disambiguate function calls already".

>>> A better way maybe to introduce a new concept, that is, a new keyword,  so instead of cast(type), we may say call(type) or something like that.
>>>
>>> But it would not be a "cast".
>>   Like I said, oppostion to using cast previously all wanted another  keyword. Personally, I have no problem re-using cast for this.
>>  Regan
>
> The problem is, we probably don't want to just "hack" the language together.

IMO using "cast" isn't a "hack". It's already used for the same 'purpose' with normal function overload resolution, the only difference being that in this case it doesn't actually have to 'cast' anything.

> Using "cast" to do something in special cases that's totally irrelevant to its meaning just because we use it for the same purpose for something else .... isn't exactly a good design IMHO.

That sentence was terribly confused but I think I follow. You're saying "using cast to select an overload is bad design" right?

So when we write this:
  foo(cast(int)a);

and do so in order to select an overload (rather than actually cast a value) we should use a new keyword?

> Also, this doesn't really remove any ambiguity, look at this example:
> ###
> int foo(){...}
> real foo(){...}
>
> void bar
> {
>      cast(int) foo(); //still ambigious
> }
> ###
> what are we doing here?

You're calling "int foo()"

Please read my other post for the rationale behind this:
http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/23847

> - calling the "real foo()" and casting it to "int"

If this is your intent you write:
  cast(int) cast(real) foo();

> This is why "cast" is a hackish solution (it doesn't even work).

In your opinion :)

Regan
May 19, 2005
TechnoZeus wrote:
> "Hasan Aljudy" <hasan.aljudy@gmail.com> wrote in message news:d6gg2v$eb7$1@digitaldaemon.com...
> 
>>James Dunne wrote:
>>
>>>I think Walter has made it perfectly clear that he doesn't want return-type
>>>function overloading in D, but I'm curious about it.
>>>
>>>I'm posting because I'd like to modify TinyCC's [http://tinycc.org/] source code
>>>to allow for return-type function overloading in the C language and play around
>>>with it.
>>>
>>>What I'd like to know is what types of pitfalls and gotchas are likely to be
>>>introduced to the compiler writer by allowing overloading based on function
>>>return type, especially in type casting and type promotion rules.  Are there any
>>>ambiguities that can be tackled easily?  Any signficantly difficult challenges
>>>involved?  Is it completely impossible to achieve with the current language
>>>design of C and its type system?
>>>
>>>I'd really like to theoretically explore the area with you guys before I try to
>>>design it in and get frustrated and give up =P.  Note I haven't given the
>>>problem entirely much thought - just want to spark some interesting discussion.
>>>
>>>Regards,
>>>James Dunne
>>
>>I'm not expert on compilers, but here is an example where it won't work:
>>
> 
> *snip*
> 
> 
> Okay, here's a thought.  What it instead of complete overriding based on return type, it were made possible to
> include code in a function that would return more than once type, and any return statement that returns
> an incompatible type would simply be skipped over.  In the case where no return value is made use of,
> there would be no such thing as an incompatible return value, so the first return would encountered would be accepted.
> 
> autotype hack()
> {
>      writef("testing..." \n);
>      return 1;
>      writef("not int .." \n);
>      return 'a';
>      writef("not char .." \n);
>     return null;
> }
> 
> int main()
> {
>      char b;
>      b = hack(); // returns 'a' which is assigned to b.
>      hack(); // returns 1, which is discarded anyway.
>      return 0;
> }
> 
> This way, the function could be called as any type that it is capable of returning.
> 
> Obviously, not as versitile.. but quite possibly also not as troublesome.  A good compromise, perhaps?
> 
> Another interesting possibility would be to expose the requested return type of a function from within that function...
> 
> autotype hack()
> {
>      if (this.typeof == ...
> 
> TZ
> 
> 

Multiple return values would make me dance and sing. Como lua...

Although, I dont know if this would work with a strongly typed language.
May 19, 2005
Regan Heath wrote:
> On Wed, 18 May 2005 21:34:36 -0600, Hasan Aljudy <hasan.aljudy@gmail.com>  wrote:
> 
>> Regan Heath wrote:
>>
>>> On Wed, 18 May 2005 19:33:13 -0600, Hasan Aljudy  <hasan.aljudy@gmail.com>  wrote:
>>>
>>>> The problem with that is, you need to have the object /before/ you  make  the cast.
>>>
>>>   True, assuming you're actually casting, which we're not.
>>>
>>
>> you said it, it's not a cast, so why would we use cast when we actually  aren't casting anything?
> 
> 
> I said it "people use cast to disambiguate function calls already".
> 
>>>> A better way maybe to introduce a new concept, that is, a new  keyword,  so instead of cast(type), we may say call(type) or something  like that.
>>>>
>>>> But it would not be a "cast".
>>>
>>>   Like I said, oppostion to using cast previously all wanted another   keyword. Personally, I have no problem re-using cast for this.
>>>  Regan
>>
>>
>> The problem is, we probably don't want to just "hack" the language  together.
> 
> 
> IMO using "cast" isn't a "hack". It's already used for the same 'purpose'  with normal function overload resolution, the only difference being that  in this case it doesn't actually have to 'cast' anything.
> 
>> Using "cast" to do something in special cases that's totally irrelevant  to its meaning just because we use it for the same purpose for something  else .... isn't exactly a good design IMHO.
> 
> 
> That sentence was terribly confused but I think I follow. You're saying  "using cast to select an overload is bad design" right?
> 
> So when we write this:
>   foo(cast(int)a);
> 
> and do so in order to select an overload (rather than actually cast a  value) we should use a new keyword?
> 
>> Also, this doesn't really remove any ambiguity, look at this example:
>> ###
>> int foo(){...}
>> real foo(){...}
>>
>> void bar
>> {
>>      cast(int) foo(); //still ambigious
>> }
>> ###
>> what are we doing here?
> 
> 
> You're calling "int foo()"
> 
> Please read my other post for the rationale behind this:
> http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/23847
> 
>> - calling the "real foo()" and casting it to "int"
> 
> 
> If this is your intent you write:
>   cast(int) cast(real) foo();
> 
>> This is why "cast" is a hackish solution (it doesn't even work).
> 
> 
> In your opinion :)
> 
> Regan

In my opinion also. Keywords should be unambiguous to the newbie, or at least make sense when explained. Using cast for all these purposes will add to the learning curve and also, IMHO, is hackish, as has already been stated.

Also, doesnt the complier "know" which overload to call for the example:

foo(cast(int)a);

?
May 19, 2005
"Hasan Aljudy" <hasan.aljudy@gmail.com> wrote in message news:d6h0jj$s1r$1@digitaldaemon.com...
> TechnoZeus wrote:
> > "Hasan Aljudy" <hasan.aljudy@gmail.com> wrote in message news:d6gg2v$eb7$1@digitaldaemon.com...
> >
> >>James Dunne wrote:
> >>
> >>>I think Walter has made it perfectly clear that he doesn't want return-type function overloading in D, but I'm curious about it.
> >>>
> >>>I'm posting because I'd like to modify TinyCC's [http://tinycc.org/] source code to allow for return-type function overloading in the C language and play around with it.
> >>>
> >>>What I'd like to know is what types of pitfalls and gotchas are likely to be introduced to the compiler writer by allowing overloading based on function return type, especially in type casting and type promotion rules.  Are there any ambiguities that can be tackled easily?  Any signficantly difficult challenges involved?  Is it completely impossible to achieve with the current language design of C and its type system?
> >>>
> >>>I'd really like to theoretically explore the area with you guys before I try to design it in and get frustrated and give up =P.  Note I haven't given the problem entirely much thought - just want to spark some interesting discussion.
> >>>
> >>>Regards,
> >>>James Dunne
> >>
> >>I'm not expert on compilers, but here is an example where it won't work:
> >>
> >
> > *snip*
> >
> >
> > Okay, here's a thought.  What it instead of complete overriding based on return type, it were made possible to
> > include code in a function that would return more than once type, and any return statement that returns
> > an incompatible type would simply be skipped over.  In the case where no return value is made use of,
> > there would be no such thing as an incompatible return value, so the first return would encountered would be accepted.
> >
> > autotype hack()
> > {
> >      writef("testing..." \n);
> >      return 1;
> >      writef("not int .." \n);
> >      return 'a';
> >      writef("not char .." \n);
> >     return null;
> > }
> >
> > int main()
> > {
> >      char b;
> >      b = hack(); // returns 'a' which is assigned to b.
> >      hack(); // returns 1, which is discarded anyway.
> >      return 0;
> > }
> >
> > This way, the function could be called as any type that it is capable of returning.
> >
> > Obviously, not as versitile.. but quite possibly also not as troublesome.  A good compromise, perhaps?
> >
> > Another interesting possibility would be to expose the requested return type of a function from within that function...
> >
> > autotype hack()
> > {
> >      if (this.typeof == ...
> >
> > TZ
> >
> >
>
> The problem is not only what to return, it's what the function does.
>
> and, what about:
>
> real foo() {...}
> int foo(){ .. }
>
> void bar
> {
>      float x = cast(float)foo(){...} //which function to call? even we
> humans can't determine that, how would a compiler do it?
> }
>

I don't see that one has hard to determine, but if the compiler doesn't know... it should be a compile-time error.

As for "what the function does" that depends on the path taken through the function's code,
which could be directed according to information on what return type has been requested (if any) and could also be
extended by skipping over any return statement that attempts to return an incompatible value.

TZ


May 19, 2005
"Kyle Furlong" <ky220@umail.ucsb.edu> wrote in message news:d6h26k$svr$1@digitaldaemon.com...
>
> Multiple return values would make me dance and sing. Como lua...
>
> Although, I dont know if this would work with a strongly typed language.

I don't see any reason why it shouldn't, if done correctly.

TZ