www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - return-type function overloading

reply James Dunne <james.jdunne gmail.com> writes:
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
May 18 2005
next sibling parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
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: int hack() { writef("int .." \n); return 1; } Object hack() { writef("Object .." \n); return null; } int main() { hack(); //which function? return 0; }
May 18 2005
next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 18 May 2005 16:37:26 -0600, Hasan Aljudy <hasan.aljudy gmail.com>  
wrote:
 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: int hack() { writef("int .." \n); return 1; } Object hack() { writef("Object .." \n); return null; } int main() { hack(); //which function? return 0; }

Indeed. Similarly... printf("%x,%d",hack(),hack()); The basic problem being that there is no information supplied/implied to disambiguate the call. This is not unique to return-type overloading however, consider: import std.stdio; void foo(int a) { writefln("int"); } void foo(float a) { writefln("float"); } int main() { long a = 5; foo(a); return 0; } D cannot disambigute the call, it gives an error. (Not sure what C does). A solution proposed in the past (by me and others - to which there was some dislike) is to: 1. Give an error for the above 2. Require the use of cast(type) to disambiguate (much the same way operator overloading is disambiguated). eg. cast(int)hack(); // calls int hack() cast(Object)hack(); // calls Object hack() 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). 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
May 18 2005
parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
Regan Heath wrote:
 
 I'm not expert on compilers, but here is an example where it won't work:

 int hack()
 {
      writef("int .." \n);
      return 1;
 }

 Object hack()
 {
      writef("Object .." \n);
      return null;
 }

 int main()
 {
      hack(); //which function?
      return 0;
 }

Indeed. Similarly... printf("%x,%d",hack(),hack()); The basic problem being that there is no information supplied/implied to disambiguate the call. This is not unique to return-type overloading however, consider: import std.stdio; void foo(int a) { writefln("int"); } void foo(float a) { writefln("float"); } int main() { long a = 5; foo(a); return 0; } D cannot disambigute the call, it gives an error. (Not sure what C does). A solution proposed in the past (by me and others - to which there was some dislike) is to: 1. Give an error for the above 2. Require the use of cast(type) to disambiguate (much the same way operator overloading is disambiguated). eg. cast(int)hack(); // calls int hack() cast(Object)hack(); // calls Object hack()

The problem with that is, you need to have the object /before/ you make the cast. 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. If you can't retrive the data, how are you going to cast it?
 
 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. I think in C, 5 is an int, while 5.0 is a double. I don't know what D does with that. But when you cast(int)5 you are not removing ambiguity, you are writing an expression that returns an "int". 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).
 
 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".
May 18 2005
next sibling parent Derek Parnell <derek psych.ward> writes:
On Wed, 18 May 2005 19:33:13 -0600, Hasan Aljudy wrote:


[snip]
 
 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".

I'm a bit wary of reusing 'cast' for this purpose too. A new keyword would be a better alternative. -- Derek Melbourne, Australia 19/05/2005 11:37:17 AM
May 18 2005
prev sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
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 18 2005
next sibling parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
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 18 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
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.


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".

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: 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 18 2005
next sibling parent reply Kyle Furlong <ky220 umail.ucsb.edu> writes:
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: 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 18 2005
next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 18 May 2005 20:50:35 -0700, Kyle Furlong <ky220 umail.ucsb.edu>  
wrote:
 Regan Heath wrote:
 This is why "cast" is a hackish solution (it doesn't even work).

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.

Each to thier own. I don't think it's too much of a stretch.
 Also, doesnt the complier "know" which overload to call for the example:

 foo(cast(int)a);

 ?

Yes, because the cast tells it which one to call. (I'm afraid I may have missed your point, there wasn't any more context to this example, it was meant for another purpose, perhaps if you propose another example I can answer more effectively) Regan
May 18 2005
parent reply Kyle Furlong <ky220 umail.ucsb.edu> writes:
Regan Heath wrote:
 On Wed, 18 May 2005 20:50:35 -0700, Kyle Furlong <ky220 umail.ucsb.edu>  
 wrote:
 
 Regan Heath wrote:

 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.

Each to thier own. I don't think it's too much of a stretch.
 Also, doesnt the complier "know" which overload to call for the example:

 foo(cast(int)a);

 ?

Yes, because the cast tells it which one to call. (I'm afraid I may have missed your point, there wasn't any more context to this example, it was meant for another purpose, perhaps if you propose another example I can answer more effectively) Regan

What I meant to write was: int x; void foo(int x) { } void foo(real x) { } main() { foo(3); } Doesn't this compile? the compiler knows
May 18 2005
next sibling parent "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"Kyle Furlong" <ky220 umail.ucsb.edu> wrote in message
news:d6hb9u$14dn$1 digitaldaemon.com...
 Regan Heath wrote:
 On Wed, 18 May 2005 20:50:35 -0700, Kyle Furlong <ky220 umail.ucsb.edu>
 wrote:

 Regan Heath wrote:

 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.

Each to thier own. I don't think it's too much of a stretch.
 Also, doesnt the complier "know" which overload to call for the example:

 foo(cast(int)a);

 ?

Yes, because the cast tells it which one to call. (I'm afraid I may have missed your point, there wasn't any more context to this example, it was meant for another purpose, perhaps if you propose another example I can answer more effectively) Regan

What I meant to write was: int x; void foo(int x) { } void foo(real x) { } main() { foo(3); } Doesn't this compile? the compiler knows

You're missing a type for "main" or it would compile... However, both versions of foo are of type void. The return type (although neither of them actually has a return statement) is therefore the same in both cases. This will also compile... import std.stdio; int x; int foo(int x) {return x+1;} real foo(real x) {return x+1;} void main() { writef("int = %d\n",foo(3)); writef("real = %g\n",foo(3.0)); } //........ but there again, it's the parameters that choose which version of foo to run...not the return values. On the other hand... import std.stdio; int x; int foo(real x) {return cast(int)x+1;} real foo(real x) {return x+1;} void main() { writef("int = %d\n",cast(int)foo(3.0)); writef("real = %g\n",cast(real)foo(3.0)); } //........ ...will produce a compile-time error like ... z.d(4): function z.foo conflicts with z.foo at z.d(3) ...because the two versions of foo both have identical parameter lists. However, one call to foo is asking for an int result and the other is asking for a real result, and likewise, one version of foo returns an int result while the other returns a real result, so the compiler could theoretically be modified to match the return types with the requested types and allow the compilation of the second version. TZ
May 19 2005
prev sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 18 May 2005 23:21:49 -0700, Kyle Furlong <ky220 umail.ucsb.edu>  
wrote:
 Regan Heath wrote:
 On Wed, 18 May 2005 20:50:35 -0700, Kyle Furlong  
 <ky220 umail.ucsb.edu>  wrote:

 Regan Heath wrote:

 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);

 ?

(I'm afraid I may have missed your point, there wasn't any more context to this example, it was meant for another purpose, perhaps if you propose another example I can answer more effectively) Regan

What I meant to write was: int x; void foo(int x) { } void foo(real x) { } main() { foo(3); } Doesn't this compile?

Ignoring the malformed main ;) Yes. Due to (as someone mentioned earlier) the 'default' type of a numeric literal is 'int'. So, my example wasn't perfect. :) Try this one: void foo(long a) {} void foo(float a) {} void main() { foo(5); } The error reads: pick.d(6): function pick.foo called with argument types: (int) matches both: pick.foo(long) and: pick.foo(float) This is because 'int' is implicitly castable to both 'long' and 'float'. Regan
May 19 2005
parent reply "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"Regan Heath" <regan netwin.co.nz> wrote in message
news:opsq1tkott23k2f5 nrage.netwin.co.nz...
 On Wed, 18 May 2005 23:21:49 -0700, Kyle Furlong <ky220 umail.ucsb.edu>
 wrote:
 Regan Heath wrote:
 On Wed, 18 May 2005 20:50:35 -0700, Kyle Furlong
 <ky220 umail.ucsb.edu>  wrote:

 Regan Heath wrote:

 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);

 ?

(I'm afraid I may have missed your point, there wasn't any more context to this example, it was meant for another purpose, perhaps if you propose another example I can answer more effectively) Regan

What I meant to write was: int x; void foo(int x) { } void foo(real x) { } main() { foo(3); } Doesn't this compile?

Ignoring the malformed main ;) Yes. Due to (as someone mentioned earlier) the 'default' type of a numeric literal is 'int'. So, my example wasn't perfect. :) Try this one: void foo(long a) {} void foo(float a) {} void main() { foo(5); } The error reads: pick.d(6): function pick.foo called with argument types: (int) matches both: pick.foo(long) and: pick.foo(float) This is because 'int' is implicitly castable to both 'long' and 'float'. Regan

Now, I would have espected it to choose long over float since long anf int are both integer types and float is not... however, I would say that if this ambiguity of passed parameters would cause a compile-time error, then the same ambiguity when applied to a choice of overloaded functions based on return types should also cause a compile-time error... for consistancy. TZ
May 20 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Fri, 20 May 2005 02:15:10 -0500, TechnoZeus <TechnoZeus PeoplePC.com>  
wrote:
 "Regan Heath" <regan netwin.co.nz> wrote in message  
 news:opsq1tkott23k2f5 nrage.netwin.co.nz...
 Try this one:

 void foo(long a) {}
 void foo(float a) {}

 void main()
 {
 foo(5);
 }

 The error reads:

 pick.d(6): function pick.foo called with argument types:
 (int)
 matches both:
 pick.foo(long)
 and:
 pick.foo(float)

 This is because 'int' is implicitly castable to both 'long' and 'float'.

 Regan

Now, I would have espected it to choose long over float since long anf int are both integer types and float is not...

Yeah, that's about the only possible criteria for selecting one over the other. After all you can safely convert to either with no loss of data. I prefer the error to selecting either, it seems to me that there is too large a possibility for a typo (forgetting the .0 on 5.0), or no knowledge of one of the overloads to mean an error.
 however, I would say that if this ambiguity of passed parameters
 would cause a compile-time error, then the same ambiguity when applied to
 a choice of overloaded functions based on return types should also cause
 a compile-time error... for consistancy.

Agreed. Where ppl seem to disagree is what the soln for that would be :) Regan
May 22 2005
parent reply "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"Regan Heath" <regan netwin.co.nz> wrote in message
news:opsq64r6tt23k2f5 nrage.netwin.co.nz...
 On Fri, 20 May 2005 02:15:10 -0500, TechnoZeus <TechnoZeus PeoplePC.com>
 wrote:
 "Regan Heath" <regan netwin.co.nz> wrote in message
 news:opsq1tkott23k2f5 nrage.netwin.co.nz...
 Try this one:

 void foo(long a) {}
 void foo(float a) {}

 void main()
 {
 foo(5);
 }

 The error reads:

 pick.d(6): function pick.foo called with argument types:
 (int)
 matches both:
 pick.foo(long)
 and:
 pick.foo(float)

 This is because 'int' is implicitly castable to both 'long' and 'float'.

 Regan

Now, I would have espected it to choose long over float since long anf int are both integer types and float is not...

Yeah, that's about the only possible criteria for selecting one over the other. After all you can safely convert to either with no loss of data. I prefer the error to selecting either, it seems to me that there is too large a possibility for a typo (forgetting the .0 on 5.0), or no knowledge of one of the overloads to mean an error.
 however, I would say that if this ambiguity of passed parameters
 would cause a compile-time error, then the same ambiguity when applied to
 a choice of overloaded functions based on return types should also cause
 a compile-time error... for consistancy.

Agreed. Where ppl seem to disagree is what the soln for that would be :) Regan

Okay, not sure whether it was a typo, a word I'm unfamilliar with, or an abbreviated word, but one way or the other, I have to ask (because I can't guess with any reasonable degree of certainty)... what was meant by the word "soln" in that context? TZ
May 23 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Mon, 23 May 2005 23:09:22 -0500, TechnoZeus <TechnoZeus PeoplePC.com>  
wrote:
 "Regan Heath" <regan netwin.co.nz> wrote in message  
 news:opsq64r6tt23k2f5 nrage.netwin.co.nz...
 On Fri, 20 May 2005 02:15:10 -0500, TechnoZeus <TechnoZeus PeoplePC.com>
 wrote:
 "Regan Heath" <regan netwin.co.nz> wrote in message
 news:opsq1tkott23k2f5 nrage.netwin.co.nz...
 Try this one:

 void foo(long a) {}
 void foo(float a) {}

 void main()
 {
 foo(5);
 }

 The error reads:

 pick.d(6): function pick.foo called with argument types:
 (int)
 matches both:
 pick.foo(long)
 and:
 pick.foo(float)

 This is because 'int' is implicitly castable to both 'long' and  


 Regan

Now, I would have espected it to choose long over float since long anf int are both integer types and float is not...

Yeah, that's about the only possible criteria for selecting one over the other. After all you can safely convert to either with no loss of data. I prefer the error to selecting either, it seems to me that there is too large a possibility for a typo (forgetting the .0 on 5.0), or no knowledge of one of the overloads to mean an error.
 however, I would say that if this ambiguity of passed parameters
 would cause a compile-time error, then the same ambiguity when  

 a choice of overloaded functions based on return types should also  

 a compile-time error... for consistancy.

Agreed. Where ppl seem to disagree is what the soln for that would be :) Regan

Okay, not sure whether it was a typo, a word I'm unfamilliar with, or an abbreviated word, but one way or the other, I have to ask (because I can't guess with any reasonable degree of certainty)... what was meant by the word "soln" in that context?

"soln" == "solution" Regan
May 24 2005
next sibling parent reply James Dunne <james.jdunne gmail.com> writes:
In article <opsq9rynem23k2f5 nrage.netwin.co.nz>, Regan Heath says...
On Mon, 23 May 2005 23:09:22 -0500, TechnoZeus <TechnoZeus PeoplePC.com>  
wrote:
 "Regan Heath" <regan netwin.co.nz> wrote in message  
 news:opsq64r6tt23k2f5 nrage.netwin.co.nz...
 On Fri, 20 May 2005 02:15:10 -0500, TechnoZeus <TechnoZeus PeoplePC.com>
 wrote:
 "Regan Heath" <regan netwin.co.nz> wrote in message
 news:opsq1tkott23k2f5 nrage.netwin.co.nz...
 Try this one:

 void foo(long a) {}
 void foo(float a) {}

 void main()
 {
 foo(5);
 }

 The error reads:

 pick.d(6): function pick.foo called with argument types:
 (int)
 matches both:
 pick.foo(long)
 and:
 pick.foo(float)

 This is because 'int' is implicitly castable to both 'long' and  


 Regan





My 2nd proposition was to remove all implicit casting from parameters and return types if the function had more than one return type that it was overloaded upon. Only by being completely explicit can we eliminate ambiguity.
 Now, I would have espected it to choose long over float
 since long anf int are both integer types and float is not...

Yeah, that's about the only possible criteria for selecting one over the other. After all you can safely convert to either with no loss of data. I prefer the error to selecting either, it seems to me that there is too large a possibility for a typo (forgetting the .0 on 5.0), or no knowledge of one of the overloads to mean an error.
 however, I would say that if this ambiguity of passed parameters
 would cause a compile-time error, then the same ambiguity when  

 a choice of overloaded functions based on return types should also  

 a compile-time error... for consistancy.

Agreed. Where ppl seem to disagree is what the soln for that would be :) Regan

Okay, not sure whether it was a typo, a word I'm unfamilliar with, or an abbreviated word, but one way or the other, I have to ask (because I can't guess with any reasonable degree of certainty)... what was meant by the word "soln" in that context?

"soln" == "solution" Regan

Regards, James Dunne
May 24 2005
parent "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"James Dunne" <james.jdunne gmail.com> wrote in message
news:d6v9bv$1906$1 digitaldaemon.com...
 In article <opsq9rynem23k2f5 nrage.netwin.co.nz>, Regan Heath says...

 My 2nd proposition was to remove all implicit casting from parameters and
return
 types if the function had more than one return type that it was overloaded
upon.
 Only by being completely explicit can we eliminate ambiguity.

 Regards,
 James Dunne

I wonder if it would be helpful to have a special syntax for declarations that would prohibit any implicit casting to or from parameters of that declaration. // Example: explicit int a(int b); void main(){ int c; byte d; c=a(d); // error } or perhaps it would be better to have to specify each explicit declaration individually. I think that would be easier on the compiler... // Example: explicit int a(explicit int b); void main(){ int c; byte d; c=a(d); // error } TZ
May 30 2005
prev sibling parent "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"Regan Heath" <regan netwin.co.nz> wrote in message
news:opsq64r6tt23k2f5 nrage.netwin.co.nz...
 On Fri, 20 May 2005 02:15:10 -0500, TechnoZeus <TechnoZeus PeoplePC.com>
 wrote:


 "Regan Heath" <regan netwin.co.nz> wrote in message
news:opsq1tkott23k2f5 nrage.netwin.co.nz...

 Now, I would have espected it to choose long over float
 since long anf int are both integer types and float is not...
 however, I would say that if this ambiguity of passed parameters
 would cause a compile-time error, then the same ambiguity when applied to
 a choice of overloaded functions based on return types should also cause
 a compile-time error... for consistancy.

 TZ

Agreed. Where ppl seem to disagree is what the soln for that would be :) Regan

The solution, I would think, would be to be consistant. Lionello Lunesu made a suggestion that return values could be thought of and treated as additional arguments. In that sense, there is no need to determine any special rules for implicit casting specific to return values. just treat them the same as you would any other argument... including the ability to have zero or more of them (rather than always one) and the ability to overload a function based on different combinations of parameters. The problem would be, as I see it, in getting the compiler implementation to know what all of the return parameters are so that it could treat them as a special set of additional parameters. So far, this is done by declaring a function type, and having the return parameter match that type. For multiple or zero return parameters an alternative or extended syntax would be needed. One possibility would be to introduce the "function" keyword to declare a typeless function. This would allow such a function to act as any type that it is capable of returning. The problem with this is that if the end of the function is reached and the correct type is not yet returned, a run-time error would be in order. Another possibility would be to allow type declaration to be a list of type returned, and return them all. Since with a single return type we are allowed the option of not using it, I would think that with this possibility we should have the option of leaving any of the returned types unused. The problem here is what typeof.this would represent. My first thought is that it should be treated as a set of types, and that any assignment of that set could be to a set with matching types or any subset thereof. TZ
May 25 2005
prev sibling parent reply James Dunne <james.jdunne gmail.com> writes:
In article <d6h2eb$t91$1 digitaldaemon.com>, Kyle Furlong says...
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: 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); ?

You guys got a bit off-topic I think. My post was to explore the idea based on extending the C language; never did I say anything about D ;) - but very nice debate going on here. You guys obviously know your stuff! I'm not concerned with D's keyword cast() in the C language; and I agree that it could be a bit ambiguous and shouldn't be used as an all-in-one swiss-army knife. I'll summarize my thoughts on all these issues in a response to my original post to keep the threads easy to follow. Regards, James Dunne
May 18 2005
next sibling parent Derek Parnell <derek psych.ward> writes:
On Thu, 19 May 2005 04:18:45 +0000 (UTC), James Dunne wrote:


[snip]

 You guys got a bit off-topic I think.  My post was to explore the idea based on
 extending the C language; never did I say anything about D ;)

Did you notice the newsgroup's name? Why discuss C issues here and not in one of the DigitalMars C++ groups? Are you really surprised that we assumed you were talking about D? Oh well, I guess you got plenty of theories anyhow. ;-) -- Derek Melbourne, Australia 19/05/2005 2:25:33 PM
May 18 2005
prev sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
Looks like it was my fault too ;)
Sorry.

Regan

On Thu, 19 May 2005 04:18:45 +0000 (UTC), James Dunne  
<james.jdunne gmail.com> wrote:
 In article <d6h2eb$t91$1 digitaldaemon.com>, Kyle Furlong says...
 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: 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); ?

You guys got a bit off-topic I think. My post was to explore the idea based on extending the C language; never did I say anything about D ;) - but very nice debate going on here. You guys obviously know your stuff! I'm not concerned with D's keyword cast() in the C language; and I agree that it could be a bit ambiguous and shouldn't be used as an all-in-one swiss-army knife. I'll summarize my thoughts on all these issues in a response to my original post to keep the threads easy to follow. Regards, James Dunne

May 18 2005
parent reply James Dunne <james.jdunne gmail.com> writes:
In article <opsqz9kl0623k2f5 nrage.netwin.co.nz>, Regan Heath says...
Looks like it was my fault too ;)
Sorry.

Regan

No no, perfectly acceptable to assume one is discussing the D language in a D language newsgroup :). My bad too. My intent was to try the feature out on a simple compiler that I had source-code access to and could easily modify it. Then I could *cough cough* come up with a nice proof-of-concept *cough* to present to Walter =D. And in response to Derek, yes it seems I did get a fair amount of discussion and theories! Please read my reply to my original post. Regards, James Dunne
May 18 2005
parent "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"James Dunne" <james.jdunne gmail.com> wrote in message
news:d6h5h9$10hj$1 digitaldaemon.com...
 In article <opsqz9kl0623k2f5 nrage.netwin.co.nz>, Regan Heath says...
Looks like it was my fault too ;)
Sorry.

Regan

No no, perfectly acceptable to assume one is discussing the D language in a D language newsgroup :). My bad too. My intent was to try the feature out on a simple compiler that I had source-code access to and could easily modify it. Then I could *cough cough* come up with a nice proof-of-concept *cough* to present to Walter =D. And in response to Derek, yes it seems I did get a fair amount of discussion and theories! Please read my reply to my original post. Regards, James Dunne

I noticed that the original post was about modifying C, but I never liked C anyway. :) True, the C language does have it's good points, but... so does D... plus some good points of it's own. With that fact in mind, as well as the fact that you mentioned Walter not wanting return type function overloading in D, I figured best to suggest a connected but not equal possibility, from which we could brain storm and hopefully find something which Walter would find acceptable and would carry the benefits of return type function overloading without it's problems. Sorry if that was out of line. TZ
May 18 2005
prev sibling parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
Regan Heath wrote:
 On Wed, 18 May 2005 21:34:36 -0600, Hasan Aljudy 
 <hasan.aljudy gmail.com>  wrote:
 
 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?

I know the sentence is terrible, (it's a hackish sentence ;) )
 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?

no, we ARE actually casting a value. What I was saying is: we use casting to remove ambiguity from the passed parameter, but this doesn't mean we can use it to remove ambiguity from the return type of the function being called, because this has no meaning with respect to "cast"
 
 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: 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

You make it work by even more hacking. My point still shows that using "cast" is hackish. When we cast function calls, we are casting the returned value to a new type, hence cast(int) foo() takes what ever value "foo" returns, and casts it to int. See, "cast" already has a task that it performs when it preceeds a function call.
May 18 2005
parent "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"Hasan Aljudy" <hasan.aljudy gmail.com> wrote in message
news:d6h46o$vbu$1 digitaldaemon.com...

 no, we ARE actually casting a value.

 What I was saying is: we use casting to remove ambiguity from the passed
 parameter, but this doesn't mean we can use it to remove ambiguity from
 the return type of the function being called, because this has no
 meaning with respect to "cast"

That actually makes sense... when you put it that way. :) TZ
May 18 2005
prev sibling parent "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"Regan Heath" <regan netwin.co.nz> wrote in message
news:opsqz536na23k2f5 nrage.netwin.co.nz...
 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

The concept is sound, but I would definately want to stay away from using the "cast" keyword for that... especially with a syntax that could be mistaken by the compiler (or by a human programmer) for an actual request to cast the return value to a specific type. TZ
May 18 2005
prev sibling next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Wed, 18 May 2005 16:37:26 -0600, Hasan Aljudy wrote:

 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: int hack() { writef("int .." \n); return 1; } Object hack() { writef("Object .." \n); return null; } int main() { hack(); //which function? return 0; }

The 'int' one, as 'int' is the default return type if no other can be determined. And consider the even 'harder' example: int hack() { writef("int .." \n); return 1; } Object hack() { writef("Object .." \n); return null; } void Bar(int a) { } void Bar(Object a) { } int main() { Bar(hack()); //which function? return 0; } --------- I still maintain that because you can't work it out from the context then assume 'int'. And if there is no matching signature using this assumption, then issue a message. If you need to be specific, then code ... Bar(Object hack()); And a really hard one would be ... int hack() { writef("int .." \n); return 1; } real hack() { writef("real .." \n); return 1; } int main() { int y; y = cast(int)hack(); //which function are you casting? return 0; } ------------------ -- Derek Melbourne, Australia 19/05/2005 9:09:13 AM
May 18 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 19 May 2005 09:17:47 +1000, Derek Parnell <derek psych.ward> wrote:
 int hack()
 {
      writef("int .." \n);
      return 1;
 }

 Object hack()
 {
      writef("Object .." \n);
      return null;
 }

 int main()
 {
      hack(); //which function?
      return 0;
 }

The 'int' one, as 'int' is the default return type if no other can be determined.

My initial thought is that this is dangerous. What if the programmer is un-aware of one of the overloads?
 And consider the even 'harder' example:

  int hack()
  {
       writef("int .." \n);
       return 1;
  }
 Object hack()
  {
       writef("Object .." \n);
       return null;
  }

  void Bar(int a)
  {
  }

  void Bar(Object a)
  {
  }
 int main()
  {
       Bar(hack()); //which function?
       return 0;
  }

Solution: Bar(cast(Object)hack()); // Object hack() called, Bar called Bar(cast(int)hack()); // int hack() called, Bar called
 ---------
 I still maintain that because you can't work it out from the context then
 assume 'int'. And if there is no matching signature using this  
 assumption,
 then issue a message.

 If you need to be specific, then code ...

     Bar(Object hack());

Similarly: Bar(cast(Object)hack());
 And a really hard one would be ...


  int hack()
  {
       writef("int .." \n);
       return 1;
  }
 real hack()
  {
       writef("real .." \n);
       return 1;
  }
 int main()
  {
     int y;
     y = cast(int)hack(); //which function are you casting?
     return 0;
  }
 ------------------

This is a good point/question. Assuming, as it's all you've specified here, that you want the result to be an 'int' which function of these two: int hack(); Object hack(); is likely to be the one to give you the desired result? Assuming both versions of 'hack' are written to achieve the same purpose or goal (if not, ideally one should be renamed) then the answer is "int hack();" as it's the more 'specialised' version, it returns the type you want. If you did actually mean to cast the address of an object to an int (or had no control over the name of the functions), you could write: cast(int)cast(Object)hack(); IMO that's not too much of an ask given this desire/goal is rare/unlikely enough that ugly or verbose syntax is not a total pain in butt. It would mean that cast(type) used for overload selection would have to identify 'Object' above and not 'int' as the overload selection, so, it's a complicated feature that's for sure. In the rare situation you were actually doing something odd (casting an object to an int above), a single cast(type) will give the incorrect results. The rest of the time it should give the desired result. Either way the initial error should show the programmer all the various overloads, allowing them to correctly indicate the desired choice. My main point is, I think an error is required initially. No assumption should be made. Regan
May 18 2005
parent Derek Parnell <derek psych.ward> writes:
On Thu, 19 May 2005 11:34:42 +1200, Regan Heath wrote:


[snip]
 The 'int' one, as 'int' is the default return type if no other can be
 determined.

My initial thought is that this is dangerous. What if the programmer is un-aware of one of the overloads?

[snip]
 My main point is, I think an error is required initially. No assumption  
 should be made.

Yes, I suspect you are correct. It follows the D way - if something is ambiguous then complain. ;-) -- Derek Melbourne, Australia 19/05/2005 10:22:17 AM
May 18 2005
prev sibling parent reply "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"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:


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
May 18 2005
next sibling parent "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"TechnoZeus" <TechnoZeus PeoplePC.com> wrote in message
news:d6gv0k$qig$1 digitaldaemon.com...

 This way, the function could be called as any type that it is capable of
returning.

 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 18 2005
prev sibling next sibling parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
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 18 2005
parent "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"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 18 2005
prev sibling parent reply Kyle Furlong <ky220 umail.ucsb.edu> writes:
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 18 2005
parent "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"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
May 18 2005
prev sibling next sibling parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
"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.
May 18 2005
parent "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"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 18 2005
prev sibling next sibling parent reply James Dunne <james.jdunne gmail.com> writes:
I'd like to throw this idea out there:

Make the return types of functions overloaded on multiple return types
non-castable.  Ugh, I hate english... there's no better way to say that :-/.
Yes, I'm a native speaker of the language, and I still hate it.  Boy, talk about
ambiguity... Anyways...

If return types were non-castable (for overloaded functions) this would solve
the implicit v. explicit cast fights (hehe, sounds like cat fights) going on.  I
agree that if the compiler detects any ambiguity, the user should be at least
warned, or error'd =).

Take this for example:

#class DBColumn {
#  public ushort opIndex(int i) { ... }
#  public int opIndex(int i) { ... }
#  public double opIndex(int i) { ... }
#  .
#  .
#}
#
#int main(char[][] args) {
#  DBColumn  col = new DBColumn(......);
#  int    col1;
#  ushort col2;
#  double col3;
#
#  col1 = col[0];  // ok - call int opIndex(0)
#  col2 = col[1];  // ok - call ushort opIndex(1)
#  // error! explicit cast; cannot determine which opIndex to call
#  col3 = cast(ushort)col[2];
#}

Implicit or explicit casting on the return-types should be disallowed.  The
return-type should be treated specially as a non-castable type.  If the return
value were passed to another function as a parameter which required the type to
be casted/promoted to fit, it should be disallowed.  Semantics like this would
be easy to implement into the current compiler - just add a non-castable flag to
the type and if it has that flag set when it is to be casted, bail out.
Generating error messages for these conditions should be fun!

There should be a different operation defined to allow explicit specification of
the return type wanted in ambiguous situations, much like the call() operator
mentioned earlier.

How does 'call(int) col[0]' look?  I suppose the opIndex function is a bad
example ;).

Someone please break my example!!  Proof by contradiction is the best proof
there is. =P

Regards,
James Dunne
May 18 2005
parent James Dunne <james.jdunne gmail.com> writes:
An update on this idea:

I've familiarized myself with the TinyCC source code enough to make a few
initial changes to come up with a proof-of-concept (or failure-of-concept for
that matter =P).

Currently, I have the TinyCC compiler checking for casts on function return
types and simply erroring out on them.  This is just a start.  Since C does not
support function overloading at all, I'll have to implement it myself.
Hopefully it won't be that hard.  The only complexities I foresee are in
matching overloaded function calls.

Maybe I'll simplify things here by disallowing any implicit casting on
overloaded parameters!  I'm all for removing ambiguity wherever possible.

Here's a nice example of what I have TinyCC doing so far:

: // ex3.c
: #include <tcclib.h>

: int fib(int n)
: {
:     if (n <= 2)
:         return 1;
:     else
:         return fib(n-1) + fib(n-2);
: }

: int main(int argc, char **argv) 
: {
:     short n;
: 
:     if (argc < 2) {
:         printf("usage: fib n\n"
:                "Compute nth Fibonacci number\n");
:         return 1;
:     }

:     n = fib(2);
:     n = atoi(argv[1]);

:     printf("fib(%d) = %d\n", n, fib(n, 2));
:     return 0;
: }

$ ./tcc ex3.c -run
ex3.c:21: uncastable function return type 'int' cannot be cast to 'short'

I've tested all different types of casts, including integer promotions and
demotions.

On a random whim I also changed C's '->' and '.' operators to behave alike on
struct pointers.  The '->' operator is still supported for backwards
compatibility.

Seems like I'm sort of making my own language as a minimal superset of C! =D  Of
course, I couldn't come anywhere near what D has!  I'm content with just
extending and fixing the simple things I don't like about C.  I don't need an
entire object-oriented paradigm.

Next thing (after return-type function overloading is done/works) will hopefully
be to completely remove the need for the pre-processor and go with a simple
module/import system.

Compilers are FUN!! =D  *as Walter's eyes glaze over*

In article <d6h5b7$10fd$1 digitaldaemon.com>, James Dunne says...
I'd like to throw this idea out there:

Make the return types of functions overloaded on multiple return types
non-castable.  Ugh, I hate english... there's no better way to say that :-/.
Yes, I'm a native speaker of the language, and I still hate it.  Boy, talk about
ambiguity... Anyways...

If return types were non-castable (for overloaded functions) this would solve
the implicit v. explicit cast fights (hehe, sounds like cat fights) going on.  I
agree that if the compiler detects any ambiguity, the user should be at least
warned, or error'd =).

Take this for example:

#class DBColumn {
#  public ushort opIndex(int i) { ... }
#  public int opIndex(int i) { ... }
#  public double opIndex(int i) { ... }
#  .
#  .
#}
#
#int main(char[][] args) {
#  DBColumn  col = new DBColumn(......);
#  int    col1;
#  ushort col2;
#  double col3;
#
#  col1 = col[0];  // ok - call int opIndex(0)
#  col2 = col[1];  // ok - call ushort opIndex(1)
#  // error! explicit cast; cannot determine which opIndex to call
#  col3 = cast(ushort)col[2];
#}

Implicit or explicit casting on the return-types should be disallowed.  The
return-type should be treated specially as a non-castable type.  If the return
value were passed to another function as a parameter which required the type to
be casted/promoted to fit, it should be disallowed.  Semantics like this would
be easy to implement into the current compiler - just add a non-castable flag to
the type and if it has that flag set when it is to be casted, bail out.
Generating error messages for these conditions should be fun!

There should be a different operation defined to allow explicit specification of
the return type wanted in ambiguous situations, much like the call() operator
mentioned earlier.

How does 'call(int) col[0]' look?  I suppose the opIndex function is a bad
example ;).

Someone please break my example!!  Proof by contradiction is the best proof
there is. =P

Regards,
James Dunne

Regards, James Dunne
May 19 2005
prev sibling parent reply "Lionello Lunesu" <lio lunesu.removethis.com> writes:
I wish return values were thought of as an additional (hidden) "inout" 
argument to the function. Much like "this" is a hidden "in" argument when 
calling methods of an object.

If this could be consistently done, then it would not only allow for 
"return-type function overloading" but maybe also create the possibility of 
returning multiple values (tuples)! (which basically comes down to inventing 
a nice-enough syntax for it)

L. 
May 19 2005
next sibling parent reply "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"Lionello Lunesu" <lio lunesu.removethis.com> wrote in message
news:d6k1qi$bbj$1 digitaldaemon.com...
 I wish return values were thought of as an additional (hidden) "inout"
 argument to the function. Much like "this" is a hidden "in" argument when
 calling methods of an object.

 If this could be consistently done, then it would not only allow for
 "return-type function overloading" but maybe also create the possibility of
 returning multiple values (tuples)! (which basically comes down to inventing
 a nice-enough syntax for it)

 L.

Beautiful idea... I really like this one. :) But yes, coming up with a good syntax could be an issue. My first thought was, perhaps something similar to a built in struct with optional members... void main() { struct{int,real} a() { return {9,1.2}} printf("___%d___%g___",a); real b = a.real; } but then I thought... what else could "int,real x" mean? void main() { int,real x() { return 9,1.2;} printf("___%d___%g___",x); real b = x.real; } of course, the commas look funny there, but I suppose one could get used to them. How about this?... void main() { int : real y() { return 9 : 1.2;} printf("___%d___%g___",y); real b = y.real; } or, here's one other possibility to consider... void main() { function (int,real) q() { return (9,1.2);} printf("___%d___%g___",q); real b = q.real; } just fule for brainstorming. :) Anyone care to add to it? TZ
May 20 2005
next sibling parent reply "Lionello Lunesu" <lio lunesu.removethis.com> writes:
Hi.

 But yes, coming up with a good syntax could be an issue.

<snip>
  struct{int,real} a() { return {9,1.2}}
  int,real x() { return 9,1.2;}

I liked these two best. The other example introduced new stuff :-S that always scares me. Especially since "function" doesn't really have anything to do with the multiple-return value stuff. I guess multiple return values should be treated as a struct, since that's how you would do it now. It's the implicit-ness that makes it nice. At the moment you'll have to manually declare a struct for each function with multiple return values. The second example looks a lot like Python though. I like python's "a,b = x();". L.
May 20 2005
parent "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"Lionello Lunesu" <lio lunesu.removethis.com> wrote in message
news:d6k66u$g2j$1 digitaldaemon.com...
 Hi.

 But yes, coming up with a good syntax could be an issue.

<snip>
  struct{int,real} a() { return {9,1.2}}
  int,real x() { return 9,1.2;}

I liked these two best. The other example introduced new stuff :-S that always scares me. Especially since "function" doesn't really have anything to do with the multiple-return value stuff. I guess multiple return values should be treated as a struct, since that's how you would do it now. It's the implicit-ness that makes it nice. At the moment you'll have to manually declare a struct for each function with multiple return values. The second example looks a lot like Python though. I like python's "a,b = x();". L.

Yep. That's kindof what I was thinking also. ...except for the python stuff, which I wasn't aware of. Figured either treat it as an implied struct, or as an implied set. Not really sure there's much (if any) difference, conceptually. Anyway, of those two, I personally prefer... int,real x() { return 9,1.2;} because of it's simplicity... but the other has more potential for flexibility. TZ
May 20 2005
prev sibling next sibling parent reply Nod <Nod_member pathlink.com> writes:
In article <d6k4uo$f3h$1 digitaldaemon.com>, TechnoZeus says...
"Lionello Lunesu" <lio lunesu.removethis.com> wrote in message
news:d6k1qi$bbj$1 digitaldaemon.com...
 I wish return values were thought of as an additional (hidden) "inout"
 argument to the function. Much like "this" is a hidden "in" argument when
 calling methods of an object.

 If this could be consistently done, then it would not only allow for
 "return-type function overloading" but maybe also create the possibility of
 returning multiple values (tuples)! (which basically comes down to inventing
 a nice-enough syntax for it)

 L.

Beautiful idea... I really like this one. :)

Yup. My thoughts exactly. I have always thought the inout parameter concept was flawed. A function should take in values at one end, and spit them out at the other. Anything else leads to uncertainties about what's really going on. This has been demonstrated enough in the "require inout on function calls" thread. Egads! What is the need to perpetuate this blatantly obvoius inconsistency?! *slams keyboard*
 <snip>
void main()
{
  int,real x() { return 9,1.2;}
  printf("___%d___%g___",x);
  real b = x.real;
}
 <snip>

TZ

This one has my vote. Simple and intuitive. Bliss. May I suggest an addition though? Since function names can be quite long, one may not want to *have* to use it in order to access the return parameters. Thus: :void main() :{ : int a; real b; : int, real longFunctionNameBonanza() { return 9, 1.2;} : [a, b] = longFunctionNameBonanza(); : printf("___%d___%g___", a, b); :} This practise is common in Perl, of all languages, and it's quite pleasant to get used to. -Nod-
May 20 2005
parent "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"Nod" <Nod_member pathlink.com> wrote in message
news:d6loem$1p7r$1 digitaldaemon.com...
 In article <d6k4uo$f3h$1 digitaldaemon.com>, TechnoZeus says...
"Lionello Lunesu" <lio lunesu.removethis.com> wrote in message
news:d6k1qi$bbj$1 digitaldaemon.com...
 I wish return values were thought of as an additional (hidden) "inout"
 argument to the function. Much like "this" is a hidden "in" argument when
 calling methods of an object.

 If this could be consistently done, then it would not only allow for
 "return-type function overloading" but maybe also create the possibility of
 returning multiple values (tuples)! (which basically comes down to inventing
 a nice-enough syntax for it)

 L.

Beautiful idea... I really like this one. :)

Yup. My thoughts exactly. I have always thought the inout parameter concept was flawed. A function should take in values at one end, and spit them out at the other. Anything else leads to uncertainties about what's really going on. This has been demonstrated enough in the "require inout on function calls" thread. Egads! What is the need to perpetuate this blatantly obvoius inconsistency?! *slams keyboard*
 <snip>
void main()
{
  int,real x() { return 9,1.2;}
  printf("___%d___%g___",x);
  real b = x.real;
}
 <snip>

TZ

This one has my vote. Simple and intuitive. Bliss. May I suggest an addition though? Since function names can be quite long, one may not want to *have* to use it in order to access the return parameters. Thus: :void main() :{ : int a; real b; : int, real longFunctionNameBonanza() { return 9, 1.2;} : [a, b] = longFunctionNameBonanza(); : printf("___%d___%g___", a, b); :} This practise is common in Perl, of all languages, and it's quite pleasant to get used to. -Nod-

Yes, I've seen set assignments like that in other languages also. Works nicely. Basically, [a,b] would be an anonomous set in that context, with it's elements being independant of each other outside of the context of that set. For those who are unfamilliar with such notation, the order of the elements is matched in the assignment. In other words... [a,b,c] = [d,e,f]; is the same as... a = d; b = e; c = f; This can be generalized further to include operations such as... [a, b] = [c, d] + [e, f]; meaning roughly the same thing as... a = c + e; b = d + f; except that the order of operations would be to do the additions first and then do the assignments... as if the set of additions were a "group addition" operation. This goes along with the fact that... [a,b]=longFunctionNameBonanza(); first evaluates longFunctionNameBonanza() and then assigns the return values to [a,b] in the order that they appear on the return statement. Again, there is the question of syntax. Should it be.... [a,b] = [c,d]; or would it be better to use... a,b = c,d; and there is also the issue of what the following means, if anything... int a; int b; int c=9; [a,b] = c; where it could be defined as an error, or as assigning the value of c to both a and b as if it were assigning an array element type value to an array. TZ
May 20 2005
prev sibling parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
TechnoZeus wrote:
 Beautiful idea... I really like this one.  :)
 
 But yes, coming up with a good syntax could be an issue.
 
 My first thought was, perhaps something similar to a built in struct with
optional members...
 
 void main()
 {
   struct{int,real} a() { return {9,1.2}}
   printf("___%d___%g___",a);
   real b = a.real;
 }
 
 but then I thought... what else could "int,real x" mean?
 
 void main()
 {
   int,real x() { return 9,1.2;}
   printf("___%d___%g___",x);
   real b = x.real;
 }
 

How about: void main() { real,real x() { return 9.0,1.2;} printf("___%d___%g___",x); real b = x.real; //ambiguity: which one?? }
May 22 2005
parent reply "Lionello Lunesu" <lio lunesu.removethis.com> writes:
 How about:

 void main()
 {
   real,real x() { return 9.0,1.2;}
   printf("___%d___%g___",x);
   real b = x.real;             //ambiguity: which one??
 }

Good example. You shouldn't be able to do that in the first place. All the values must be retreived, or none. Allowing that kind of code (retreiving only one of the return values) results in the function being called twice, possible returning a different pair of values. From the original example: int a = x.int; real b = x.real; The pair a,b might be totally useless, since the function x was evaluated twice. L.
May 23 2005
parent "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"Lionello Lunesu" <lio lunesu.removethis.com> wrote in message
news:d6s2ki$l2v$1 digitaldaemon.com...
 How about:

 void main()
 {
   real,real x() { return 9.0,1.2;}
   printf("___%d___%g___",x);
   real b = x.real;             //ambiguity: which one??
 }

Good example. You shouldn't be able to do that in the first place. All the values must be retreived, or none. Allowing that kind of code (retreiving only one of the return values) results in the function being called twice, possible returning a different pair of values. From the original example: int a = x.int; real b = x.real; The pair a,b might be totally useless, since the function x was evaluated twice. L.

Actually, yes... it's a good example of something that would have to be "dealt with" but I see two simple possibilities. The first is to simply define the standard as allowing no more than a single representative of any specific return value type. This could be justified by deciding that the "main reason" for allowing multiple return values is to facilitate a means of allowing a function to return multiple types. The second would be to recognize that the return values are an ordered set and to pass them to an assignment in order, discarding any return values that are not assigned. For example... void main() { real, real, int, char, int[], char x() { return 9.0,1.2;} printf("___%d___%g___",x); real b, c ;int d, e; char f, g; int[] h; b,c = x; //first two return parameters b = x; //very first return parameter d,f,g = x; // int return parameter, and both char return parameters, in order f,h = x; // first char return parameter, and the last (int[]) return parameter g,h,f = x // first char return parameter is assigned to g, // second char return parameter is assigned to f, // and int[] return parameter is assigned to h f,g,h = x; // error // illegal, because the there is no int[] type return after the second char type return value, // so there is no matching return parameter for h. d,e = x; // error // illegal because there isn't a second int type return parameter to assign to e. d,b = x // error // illegal, because the there is real return parameter after the int return parameter, // so there is no matching return parameter for b, // because they were requested in the wrong order. } TZ
May 23 2005
prev sibling parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
Lionello Lunesu wrote:
 I wish return values were thought of as an additional (hidden) "inout" 
 argument to the function. Much like "this" is a hidden "in" argument when 
 calling methods of an object.
 
 If this could be consistently done, then it would not only allow for 
 "return-type function overloading" but maybe also create the possibility of 
 returning multiple values (tuples)! (which basically comes down to inventing 
 a nice-enough syntax for it)
 
 L. 
 
 

You can use a Box or an array of Boxes as the return type. This way, you can return anything you want, and if you use an array, you can return many thngs of any type you want.
May 20 2005
next sibling parent "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"Hasan Aljudy" <hasan.aljudy gmail.com> wrote in message
news:d6kvhl$15fr$1 digitaldaemon.com...
 Lionello Lunesu wrote:
 I wish return values were thought of as an additional (hidden) "inout"
 argument to the function. Much like "this" is a hidden "in" argument when
 calling methods of an object.

 If this could be consistently done, then it would not only allow for
 "return-type function overloading" but maybe also create the possibility of
 returning multiple values (tuples)! (which basically comes down to inventing
 a nice-enough syntax for it)

 L.

You can use a Box or an array of Boxes as the return type. This way, you can return anything you want, and if you use an array, you can return many thngs of any type you want.

Right, but those thing have to first be put into an array, as things are now. Consider, for example, the following hypothetical code, using multiple return values... prevnext(int x;){return x-1, x+1;} void main(){ int a; int b; int c; int d = 1; int e; int f; int g; b,f = prevnext(d); a,c = prevnext(b); e,g = prevnext(f); if (c == e) [e,c] = prevnext(d); Notice that in the last assignment, I reversed the order of the elements? This type of notation removes a lot of the restrictions associated with using an array as a function's type, and allows otherwise entirely unconnected items to be used as a set without any declaration of a names type or item to contain the temporary set that they compose. TZ
May 20 2005
prev sibling parent reply "Lionello Lunesu" <lio lunesu.removethis.com> writes:
 You can use a Box or an array of Boxes as the return type.
 This way, you can return anything you want, and if you use an array, you 
 can return many thngs of any type you want.

Yes, but boxing adds some overhead though. If I but two reals in a box (both in a box array) and then the boxes are checked for the right type when trying to get the reals of them. Basically, I'm suggesting something like an anonymous struct, and some easy syntax to create it 'on the fly', without the need to declare a struct for each combination of return values. Instead of writing: struct point_t { int a; int b; }; point_t getPoint(); ..it would be nice if you could write: struct {int a;int b;} getPoint(); Maybe this syntax can be simplified even more, using an implicit struct: int, int getPoint(); Might result in some parsing problems though. In any case, it should be possible to retreive the values in seperate variables (who are not themselves in a similar struct): int b; // do something with b int a; a,b = getPoint(); Note that I don't like calling a function add being able to retreive only one of the return values, as mentioned in an earlier example: a = getPoint().int; First of all there's the ambiguity, but also the fact that this simply shouldn't be encouraged. You should retreive all of the values, or none, to prevent people calling getPoint().real and .int (with whatever syntax that would solve the ambiguity), since the function will be evaluated twice. Possibly resulting in a nonsense pair of values, but in any case resulting in the code being executed twice! L. L.
May 23 2005
parent reply "G.Vidal" <gyvidal wanadoo.fr> writes:
i Like: 

(int,double) func (int param) {
	......
	......
	return (a,b);
}


int a;
double b;

(a,b) = func(0);



This is possible to implement, I'm sure.

Unfortunately, I doubt Walter would consider it. He doesn't seem
interested by such dramatically "new" ideas.

I regret that. There should be an "unofficial" DMD version reserved for
implementing crazy things like that and test.







Le Mon, 23 May 2005 10:58:19 +0300, Lionello Lunesu a écrit :

 You can use a Box or an array of Boxes as the return type.
 This way, you can return anything you want, and if you use an array, you 
 can return many thngs of any type you want.

Yes, but boxing adds some overhead though. If I but two reals in a box (both in a box array) and then the boxes are checked for the right type when trying to get the reals of them. Basically, I'm suggesting something like an anonymous struct, and some easy syntax to create it 'on the fly', without the need to declare a struct for each combination of return values. Instead of writing: struct point_t { int a; int b; }; point_t getPoint(); ..it would be nice if you could write: struct {int a;int b;} getPoint(); Maybe this syntax can be simplified even more, using an implicit struct: int, int getPoint(); Might result in some parsing problems though. In any case, it should be possible to retreive the values in seperate variables (who are not themselves in a similar struct): int b; // do something with b int a; a,b = getPoint(); Note that I don't like calling a function add being able to retreive only one of the return values, as mentioned in an earlier example: a = getPoint().int; First of all there's the ambiguity, but also the fact that this simply shouldn't be encouraged. You should retreive all of the values, or none, to prevent people calling getPoint().real and .int (with whatever syntax that would solve the ambiguity), since the function will be evaluated twice. Possibly resulting in a nonsense pair of values, but in any case resulting in the code being executed twice! L. L.

May 23 2005
next sibling parent reply "G.Vidal" <gyvidal wanadoo.fr> writes:
I forgot to say...

With this:

 (int,double) func (int param) {
 	......
 	......
 	return (a,b);
 }

And this: int foo (int a, double d, real c) { ... ... } We should be allowed to do this: int a = foo (func(1), e); // 2+1 params ! neat...
May 23 2005
parent Marcello Gnani<marcello_gnani tiscali.it> writes:
I like it.

In article <pan.2005.05.23.14.49.16.571845 wanadoo.fr>, G.Vidal says...
I forgot to say...

With this:

 (int,double) func (int param) {
 	......
 	......
 	return (a,b);
 }

And this: int foo (int a, double d, real c) { ... ... } We should be allowed to do this: int a = foo (func(1), e); // 2+1 params ! neat...

May 23 2005
prev sibling next sibling parent reply imr1984 <imr1984_member pathlink.com> writes:
Walter is not afraid to do new things, and what youve suggested can be
implemented with structs. So there.

In article <pan.2005.05.23.14.45.22.80514 wanadoo.fr>, G.Vidal says...
i Like: 

(int,double) func (int param) {
	......
	......
	return (a,b);
}


int a;
double b;

(a,b) = func(0);



This is possible to implement, I'm sure.

Unfortunately, I doubt Walter would consider it. He doesn't seem
interested by such dramatically "new" ideas.

I regret that. There should be an "unofficial" DMD version reserved for
implementing crazy things like that and test.







Le Mon, 23 May 2005 10:58:19 +0300, Lionello Lunesu a écrit :

 You can use a Box or an array of Boxes as the return type.
 This way, you can return anything you want, and if you use an array, you 
 can return many thngs of any type you want.

Yes, but boxing adds some overhead though. If I but two reals in a box (both in a box array) and then the boxes are checked for the right type when trying to get the reals of them. Basically, I'm suggesting something like an anonymous struct, and some easy syntax to create it 'on the fly', without the need to declare a struct for each combination of return values. Instead of writing: struct point_t { int a; int b; }; point_t getPoint(); ..it would be nice if you could write: struct {int a;int b;} getPoint(); Maybe this syntax can be simplified even more, using an implicit struct: int, int getPoint(); Might result in some parsing problems though. In any case, it should be possible to retreive the values in seperate variables (who are not themselves in a similar struct): int b; // do something with b int a; a,b = getPoint(); Note that I don't like calling a function add being able to retreive only one of the return values, as mentioned in an earlier example: a = getPoint().int; First of all there's the ambiguity, but also the fact that this simply shouldn't be encouraged. You should retreive all of the values, or none, to prevent people calling getPoint().real and .int (with whatever syntax that would solve the ambiguity), since the function will be evaluated twice. Possibly resulting in a nonsense pair of values, but in any case resulting in the code being executed twice! L. L.


May 23 2005
parent reply Matthias Becker <Matthias_member pathlink.com> writes:
Walter is not afraid to do new things, and what youve suggested can be
implemented with structs. So there.

Loops can be implemented with gotos. So let's remove them.
May 24 2005
parent "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"Matthias Becker" <Matthias_member pathlink.com> wrote in message
news:d6vqvt$2068$1 digitaldaemon.com...
Walter is not afraid to do new things, and what youve suggested can be
implemented with structs. So there.

Loops can be implemented with gotos. So let's remove them.

Sarcasm aside, your point is valid. Higher level language functionality can always be implemented with sufficient low level code... but that doesn't mean it's not good to have. Walter... when you get time, please add in a short comment here about which syntax you like best for multiple return types, and how you feel at this time about the possibile future of multiple return types and return type overloading in the D language. TZ
May 30 2005
prev sibling next sibling parent Sean Kelly <sean f4.ca> writes:
In article <pan.2005.05.23.14.45.22.80514 wanadoo.fr>, G.Vidal says...
i Like: 

(int,double) func (int param) {
	......
	......
	return (a,b);
}


int a;
double b;

(a,b) = func(0);



This is possible to implement, I'm sure.

Unfortunately, I doubt Walter would consider it. He doesn't seem
interested by such dramatically "new" ideas.

Not "new" really--this is a feature of Lua, and of other languages I'm sure. It does beat template-based tuples for this purpose. Perhaps a 2.0 feature? Sean
May 23 2005
prev sibling next sibling parent "Lionello Lunesu" <lio lunesu.removethis.com> writes:
 (int,double) func (int param) {

Nice syntax! I like it.
May 24 2005
prev sibling next sibling parent reply Matthias Bekcer <Matthias_member pathlink.com> writes:
i Like: 

(int,double) func (int param) {
	......
	......
	return (a,b);
}


int a;
double b;

(a,b) = func(0);



This is possible to implement, I'm sure.

Unfortunately, I doubt Walter would consider it. He doesn't seem
interested by such dramatically "new" ideas.

I regret that. There should be an "unofficial" DMD version reserved for
implementing crazy things like that and test.

There are _so_ many languages that have tupls build in with exactly the same syntax, so what is "crazy" about it?
May 24 2005
parent reply "G.Vidal" <gyvidal wanadoo.fr> writes:
 There are _so_ many languages that have tupls build in with exactly the same
 syntax, so what is "crazy" about it?

What I meant by "crazy" is "totally different from the C/C++/C#/Java syntaxes" I'm just tired of seeing so many ideas from so many people and finally there's no response from the D compiler programmer. So what are we suppose to think ? He reads them and is still thinking about it, reads and thinks the idea is bad, or maybe he doesn't read them at all, how can we know ? If he doesn't agree with the idea, we don't even know why. Maybe there should be more programmers for D.
May 24 2005
next sibling parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
"G.Vidal" <gyvidal wanadoo.fr> wrote in message 
news:pan.2005.05.24.20.09.54.952681 wanadoo.fr...
 There are _so_ many languages that have tupls build in with exactly the 
 same
 syntax, so what is "crazy" about it?

What I meant by "crazy" is "totally different from the C/C++/C#/Java syntaxes" I'm just tired of seeing so many ideas from so many people and finally there's no response from the D compiler programmer.

"D compiler programmer" aka Walter? One can hack on gdc but that would require knowledge about how gdc works. If it can be implemented in the front-end then poking around in the dmd front-end source can be illuminating, too.
 So what are we suppose to think ? He reads them and is still thinking
 about it, reads and thinks the idea is bad, or maybe he doesn't read them
 at all, how can we know ?

It can get frustrating, I know. Walter's Jedi mind tricks don't work through the newsreader :-P
 If he doesn't agree with the idea, we don't even know why.
 Maybe there should be more programmers for D.

Suggesting changes is easy. Implementing them is hard. Deciding what to implement and what not to implement is impossible. Maybe Walter will consider this for 1.0. Maybe he'll consider it for 2.0. Maybe he'll do it for 0.126. Who knows... My guess would be it belongs in the post 1.0 bucket.
May 24 2005
parent "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"Ben Hinkle" <bhinkle mathworks.com> wrote in message
news:d702g8$2a95$1 digitaldaemon.com...

 Maybe Walter will consider this for 1.0. Maybe he'll consider it for 2.0.
 Maybe he'll do it for 0.126. Who knows... My guess would be it belongs in
 the post 1.0 bucket.

Agreed. TZ
May 30 2005
prev sibling next sibling parent reply "Unknown W. Brackets" <unknown simplemachines.org> writes:
 What I meant by "crazy" is "totally different from the C/C++/C#/Java
 syntaxes"

I agree. Why not return a box[] or: struct { TypeInfo[] types; void* values; } Or something, instead? Having this: (a, b, c) = func(1, 2, 3); Really looks like Perl to me, and thus ugly. I would say that it'd need some sort of keyword to look C-like: list (a, b, c) = func(1, 2, 3); But even that looks strange.
 I'm just tired of seeing so many ideas from so many people and finally
 there's no response from the D compiler programmer.
 
 So what are we suppose to think ? He reads them and is still thinking
 about it, reads and thinks the idea is bad, or maybe he doesn't read them
 at all, how can we know ?
 
 If he doesn't agree with the idea, we don't even know why. 
 Maybe there should be more programmers for D.

Well, Walter isn't superman. Neither am I or you. We can't be everywhere at once or read everything at once. And it's not like his life is D or anything, either. But, it seems to me he reads more than you might expect. And, in the long run... you want things changed or commented on now... but I find, at least myself, that if you give things time to simmer out, the best solution will present itself much more cleanly. Maybe Walter just doesn't want to get involved because he doesn't have the time or because he wants to watch what people come up with. Or, maybe he just doesn't like it and isn't going to waste his time reading this thread. -[Unknown]
May 24 2005
next sibling parent Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
Unknown W. Brackets wrote:
 What I meant by "crazy" is "totally different from the C/C++/C#/Java
 syntaxes"

I agree. Why not return a box[] or:

I don't agree. Wouldn't returning box[] impose too much runtime overhead ?
 Or something, instead?  Having this:
 
 (a, b, c) = func(1, 2, 3);
 
 Really looks like Perl to me, and thus ugly.  I would say that it'd need 
 some sort of keyword to look C-like:

It looks perfectly clear to me ( maybe because my mind hasn't been spoiled by Perl ;) )
 list (a, b, c) = func(1, 2, 3);
 
 But even that looks strange.

Confusing. Looks like assigning the result of one function call to the result of another. For someone with a C++ background this might look like depending on some weird side effects of the assignment or even worse tricks :o -- Tomasz Stachowiak /+ a.k.a. h3r3tic +/
May 24 2005
prev sibling next sibling parent reply "Lionello Lunesu" <lio lunesu.removethis.com> writes:
Oh no, another "it looks like X and X is ugly"..

What does "if (x is y)" look like? Or "int* b = c in hash;" ? "templ!(int)" 
?

L. 
May 25 2005
parent "Unknown W. Brackets" <unknown simplemachines.org> writes:
 What does "if (x is y)" look like?

Horrible, yes. I prefer ===, as much as blind people who insist upon using crappy fonts may disagree.
 Or "int* b = c in hash;" ?

In that case, there aren't that many other options. The in keyword in this case makes sense to me. At least it's not: if (x eq y) if (x ne y) if (x gt y) And so forth. Boy I hated those.
 "templ!(int)" 
 ?

Kinda funky, but it's a syntax. The point is, this: (x, y) = func(); Is somewhat ambiguous, especially with the way C and D already handle commas. I'd actually support this: [x, y] = func(); Or even: <x, y> = func(); Much more than with parenthesis. The parenthesis mean expression to me, at which point it makes absolutely no sense to assign to it. This is how C is. If you don't understand what I mean, compile this: int a, b; (a, b) = 1; writefln(a, " ", b); It should output: 0 1 -[Unknown]
May 25 2005
prev sibling parent reply "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"Unknown W. Brackets" <unknown simplemachines.org> wrote in message
news:d7033h$2ane$1 digitaldaemon.com...

 (a, b, c) = func(1, 2, 3);

 Really looks like Perl to me, and thus ugly.  I would say that it'd need
 some sort of keyword to look C-like:

 -[Unknown]

I would rather have it look D-like than C-like... and... (a,b,c) = func(1,2,3); is looking more and more D-like to me every day. After all, D may be "based on" the C language, but I don't think the intention was ever for it to be merely another version of C with a different name. TZ
May 30 2005
parent Trevor Parscal <Trevor_member pathlink.com> writes:
In article <d7fu8q$2u1h$1 digitaldaemon.com>, TechnoZeus says...
"Unknown W. Brackets" <unknown simplemachines.org> wrote in message
news:d7033h$2ane$1 digitaldaemon.com...

 (a, b, c) = func(1, 2, 3);

 Really looks like Perl to me, and thus ugly.  I would say that it'd need
 some sort of keyword to look C-like:

 -[Unknown]

I would rather have it look D-like than C-like... and... (a,b,c) = func(1,2,3); is looking more and more D-like to me every day. After all, D may be "based on" the C language, but I don't think the intention was ever for it to be merely another version of C with a different name. TZ

In PHP you can do list($a, $b, $c) = $array; instead of $a = $array[0]; $b = $array[1]; $c = $array[2]; Which is useful when you are breaking apart things with list($a, $b, $c) = explode(",", "one,two,thee"); But I am hard pressed to find another example. AND, it's very limited. Why? What if there is only "one,two" in the text? ERROR. What if there is "one,two,three,four" in the text? You never get "four". What is wrong with using char[][] array = split(",", "one,two,three,four"); In the defense of this concept. I can see how (r, g, b) = Color.Extract; Might make SOME sense, but it's also DUMB. cause seriously, you could just use a variadic function.. Color.Extract(&r, &g, &b); Color.Extract(&r, &g, &b, &a); To me, I would need to see why something like (... variadic output...) = function(parameters); is so needed, and it is requiring so many lines of code to work around it's absence before I could support it's addition to D. LONG before we needed something like this, we should be working on serialization of boxes or something. My 2 cents.. :) Thanks, Trevor Parscal www.trevorparscal.com trevorparscal hotmail.com
May 30 2005
prev sibling next sibling parent Oskar Linde <Oskar_member pathlink.com> writes:
In article <pan.2005.05.24.20.09.54.952681 wanadoo.fr>, G.Vidal says...
 There are _so_ many languages that have tupls build in with exactly the same
 syntax, so what is "crazy" about it?

What I meant by "crazy" is "totally different from the C/C++/C#/Java syntaxes"

C++ TR1 includes a proposal for tuples (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1403.pdf) but with slightly more awkward syntax...: tuple<int,int,double> foo add_multiply_divide(int a, int b) { return make_tuple(a+b, a*b, double(a)/double(b)); } /*...*/ int a,b; double d; tie(a,b,d) = add_multply_divide(3,7); So there is definitely reason to believe that tuples and multiple return values will become a standardised practise in C++.
May 25 2005
prev sibling next sibling parent David Medlock <noone nowhere.com> writes:
G.Vidal wrote:

There are _so_ many languages that have tupls build in with exactly the same
syntax, so what is "crazy" about it?

What I meant by "crazy" is "totally different from the C/C++/C#/Java syntaxes" I'm just tired of seeing so many ideas from so many people and finally there's no response from the D compiler programmer. So what are we suppose to think ? He reads them and is still thinking about it, reads and thinks the idea is bad, or maybe he doesn't read them at all, how can we know ? If he doesn't agree with the idea, we don't even know why. Maybe there should be more programmers for D.

good ideas. He rightly weighs each idea on how it fits with the language's capabilities and its purpose(A systems language similar to C++/Java but better :) ). Slapping feature on top of feature is one reason C++ has been described as 'an octopus created by taping four legs on a dog'. -DavidM
May 25 2005
prev sibling parent reply "TechnoZeus" <TechnoZeus PeoplePC.com> writes:
"G.Vidal" <gyvidal wanadoo.fr> wrote in message
news:pan.2005.05.24.20.09.54.952681 wanadoo.fr...
 There are _so_ many languages that have tupls build in with exactly the same
 syntax, so what is "crazy" about it?

What I meant by "crazy" is "totally different from the C/C++/C#/Java syntaxes" I'm just tired of seeing so many ideas from so many people and finally there's no response from the D compiler programmer. So what are we suppose to think ? He reads them and is still thinking about it, reads and thinks the idea is bad, or maybe he doesn't read them at all, how can we know ? If he doesn't agree with the idea, we don't even know why. Maybe there should be more programmers for D.

Well, if ideas are discussed here and never end up in the D language, the discussions may still influence the development of other languages in the future. Keep in mind that this particular language is not the first one to be named D and just possibly "may not" be the last. While I very much hope it succedes, what's even more important (in my opinion) is the trail that it's blazing in the process. TZ
May 30 2005
parent "Rolf Tollerud" <rolftollerud msn.com> writes:
One benevolent (genius) dictator is far better than any other way. As D is 
now (minus possible bugs) it will be a fantastic success. You read it here 
first! The only thing that could mar it would to put too much stuff into it 
like is always the case when something is "designed by committee". At this 
moment D is fast and sexy. Let it be that way. The difficult thing is not to 
decide what to put into a language, but what not to put in! 
May 30 2005
prev sibling parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
G.Vidal wrote:
 i Like: 
 
 (int,double) func (int param) {
 	......
 	......
 	return (a,b);
 }
 
 
 int a;
 double b;
 
 (a,b) = func(0);
 
 
 
 This is possible to implement, I'm sure.
 
 Unfortunately, I doubt Walter would consider it. He doesn't seem
 interested by such dramatically "new" ideas.
 
 I regret that. There should be an "unofficial" DMD version reserved for
 implementing crazy things like that and test.
 

Hmmm .. Looks like a struct to me. C-like Code: ------------------------- struct { int a, double b } func (..) { ... return { 4, 3.0 }; } struct { int a; double b; } x; x = func(...) ------------------------- I'm not sure if that's valid C code. This is just a "struct" with syntactic sugar, nothing new at all. Remove the "struct" keyword, and use some ( ) instead of { }. Oh, and this is not the case with goto's and while loops, because the while loop is not merely a syntactic sugar for goto. Anyway, I don't really like the original idea anyway.
May 25 2005
parent Derek Parnell <derek psych.ward> writes:
On Wed, 25 May 2005 01:06:02 -0600, Hasan Aljudy wrote:

 G.Vidal wrote:
 i Like: 
 
 (int,double) func (int param) {
 	......
 	......
 	return (a,b);
 }
 
 
 int a;
 double b;
 
 (a,b) = func(0);
 
 
 
 This is possible to implement, I'm sure.
 
 Unfortunately, I doubt Walter would consider it. He doesn't seem
 interested by such dramatically "new" ideas.
 
 I regret that. There should be an "unofficial" DMD version reserved for
 implementing crazy things like that and test.
 

Hmmm .. Looks like a struct to me.

It doesn't have to be though. (Foo.a, Bar.b) = func( x ); In other words, the receiving variables do not have to be located in the same aggregate item. It is syntactic sugar for ... struct Temp { int a; double b; } Temp r; Temp func (int param) { Temp x; ...... ...... x.a = a; x.b = b; return x; } r = func( x ); Foo.a = r.a; Bar.b = r.b; But because the 'struct' is defined and created by the compiler as a transient item, it saves the coder from having to do the menial task. -- Derek Parnell Melbourne, Australia 25/05/2005 6:46:58 PM
May 25 2005