www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Ditch "out" variables

reply James Dunne <james.jdunne gmail.com> writes:
"out" variables would be much more useful as a set of multiple return values:

: (int x, real y, float[] a) myfunction (int b);

I'd say the only complications arise in handling the return statement syntax -
whether or not to specify a set of return values, or to implicitly return values
by setting return-value variables.

method 1: return with a set of values
: (int, real, float[]) myfunction (int b) {
:     return (b + 2, b * 4.5, null);
: }

or

method 2: return by setting return-value variables
: (int x, real y, float[] a) myfunction (int b) {
:     x = b + 2;
:     y = b * 4.5;
:     a = null;
:     return;
: }

Both *examples* are equivalent, but each approach has its strengths and
weaknesses.  No weaker than forgetting to set an "out" variable as the language
is now.

Method 1 allows for cleaner reading until the list of return values gets
unreasonably large.  It also accomodates all return-values on function return.

Method 2 allows more readability for longer lists of return values, but
sacrifices understandability in following setting of return values throughout a
complex control flow.

Personally, I'd prefer method 2; but perhaps both forms can be supported.

Calling syntax is up for debate as well:

: int x;
: real y;
: float[] a;
: (x, y, a) = myfunction(4);

Thoughts?  Opinions?  Concerns?

Regards,
James Dunne
Jun 07 2005
next sibling parent Hasan Aljudy <hasan.aljudy gmail.com> writes:
so much hassle for so little (read: for nothing).

I prefer the "out" method much better.

Just my opinion.

James Dunne wrote:
 "out" variables would be much more useful as a set of multiple return values:
 
 : (int x, real y, float[] a) myfunction (int b);
 
 I'd say the only complications arise in handling the return statement syntax -
 whether or not to specify a set of return values, or to implicitly return
values
 by setting return-value variables.
 
 method 1: return with a set of values
 : (int, real, float[]) myfunction (int b) {
 :     return (b + 2, b * 4.5, null);
 : }
 
 or
 
 method 2: return by setting return-value variables
 : (int x, real y, float[] a) myfunction (int b) {
 :     x = b + 2;
 :     y = b * 4.5;
 :     a = null;
 :     return;
 : }
 
 Both *examples* are equivalent, but each approach has its strengths and
 weaknesses.  No weaker than forgetting to set an "out" variable as the language
 is now.
 
 Method 1 allows for cleaner reading until the list of return values gets
 unreasonably large.  It also accomodates all return-values on function return.
 
 Method 2 allows more readability for longer lists of return values, but
 sacrifices understandability in following setting of return values throughout a
 complex control flow.
 
 Personally, I'd prefer method 2; but perhaps both forms can be supported.
 
 Calling syntax is up for debate as well:
 
 : int x;
 : real y;
 : float[] a;
 : (x, y, a) = myfunction(4);
 
 Thoughts?  Opinions?  Concerns?
 
 Regards,
 James Dunne
Jun 07 2005
prev sibling next sibling parent "Unknown W. Brackets" <unknown simplemachines.org> writes:
Many functions are logical using "out".  Anyway, this is an idea that 
comes from interfaces, and goes along with "in" and "inout".

Since your proposal doesn't remove the need for, or the keywords for, 
"in" and "inout" it seems strange to remove the corresponding "out".

-[Unknown]


 "out" variables would be much more useful as a set of multiple return values:
 
 : (int x, real y, float[] a) myfunction (int b);
 
 I'd say the only complications arise in handling the return statement syntax -
 whether or not to specify a set of return values, or to implicitly return
values
 by setting return-value variables.
 
 method 1: return with a set of values
 : (int, real, float[]) myfunction (int b) {
 :     return (b + 2, b * 4.5, null);
 : }
 
 or
 
 method 2: return by setting return-value variables
 : (int x, real y, float[] a) myfunction (int b) {
 :     x = b + 2;
 :     y = b * 4.5;
 :     a = null;
 :     return;
 : }
 
 Both *examples* are equivalent, but each approach has its strengths and
 weaknesses.  No weaker than forgetting to set an "out" variable as the language
 is now.
 
 Method 1 allows for cleaner reading until the list of return values gets
 unreasonably large.  It also accomodates all return-values on function return.
 
 Method 2 allows more readability for longer lists of return values, but
 sacrifices understandability in following setting of return values throughout a
 complex control flow.
 
 Personally, I'd prefer method 2; but perhaps both forms can be supported.
 
 Calling syntax is up for debate as well:
 
 : int x;
 : real y;
 : float[] a;
 : (x, y, a) = myfunction(4);
 
 Thoughts?  Opinions?  Concerns?
 
 Regards,
 James Dunne
Jun 07 2005
prev sibling next sibling parent "Craig Black" <cblack ara.com> writes:
 Calling syntax is up for debate as well:

 : int x;
 : real y;
 : float[] a;
 : (x, y, a) = myfunction(4);

 Thoughts?  Opinions?  Concerns?
Requires support for tuples, no? Definitely cool, more intuitive function calls, but requires a lot of changes to compiler. Walter would never do this. -Craig
Jun 07 2005
prev sibling next sibling parent reply John Reimer <brk_6502 yahoo.com> writes:
James Dunne wrote:
 "out" variables would be much more useful as a set of multiple return values:
 
 : (int x, real y, float[] a) myfunction (int b);
 
 I'd say the only complications arise in handling the return statement syntax -
 whether or not to specify a set of return values, or to implicitly return
values
 by setting return-value variables.
 
 method 1: return with a set of values
 : (int, real, float[]) myfunction (int b) {
 :     return (b + 2, b * 4.5, null);
 : }
 
 or
 
 method 2: return by setting return-value variables
 : (int x, real y, float[] a) myfunction (int b) {
 :     x = b + 2;
 :     y = b * 4.5;
 :     a = null;
 :     return;
 : }
 
 Both *examples* are equivalent, but each approach has its strengths and
 weaknesses.  No weaker than forgetting to set an "out" variable as the language
 is now.
 
 Method 1 allows for cleaner reading until the list of return values gets
 unreasonably large.  It also accomodates all return-values on function return.
 
 Method 2 allows more readability for longer lists of return values, but
 sacrifices understandability in following setting of return values throughout a
 complex control flow.
 
 Personally, I'd prefer method 2; but perhaps both forms can be supported.
 
 Calling syntax is up for debate as well:
 
 : int x;
 : real y;
 : float[] a;
 : (x, y, a) = myfunction(4);
 
 Thoughts?  Opinions?  Concerns?
 
 Regards,
 James Dunne
I really can sympathize with the desire for separating input and output. It seems to make so much more sense to do in this fashion. Not only is it simple to understand, but it's clear to read. If you keep input as "input" in the function parameter section, and output separate... well it just seems more intuitive. About the only reason we still use the 'in' and 'out' methods is because of it's relationship to the old C/C++ style; but compatibility with that is simply maintained with the presence or absense '&' operator (more or less, I know... it's more equivalent to inout). Interestingly, we call inputs to a function "arguments" or "parameters" for a reason. We don't think of them as "outputs." That seems to be something computer languages have crammed into the design. In short, James, I like the general idea. It makes much more sense. This may not be the exact way one would go about this, but it's something to think about for the future. At the very least, it would be nice if it were enabled as an "alternative" in D, such that the current scheme would not be lost; breaking huge compatibility might not be a popular move. -JJR
Jun 07 2005
parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
John Reimer wrote:
 James Dunne wrote:
 
 "out" variables would be much more useful as a set of multiple return 
 values:

 : (int x, real y, float[] a) myfunction (int b);

 I'd say the only complications arise in handling the return statement 
 syntax -
 whether or not to specify a set of return values, or to implicitly 
 return values
 by setting return-value variables.

 method 1: return with a set of values
 : (int, real, float[]) myfunction (int b) {
 :     return (b + 2, b * 4.5, null);
 : }

 or

 method 2: return by setting return-value variables
 : (int x, real y, float[] a) myfunction (int b) {
 :     x = b + 2;
 :     y = b * 4.5;
 :     a = null;
 :     return;
 : }

 Both *examples* are equivalent, but each approach has its strengths and
 weaknesses.  No weaker than forgetting to set an "out" variable as the 
 language
 is now.

 Method 1 allows for cleaner reading until the list of return values gets
 unreasonably large.  It also accomodates all return-values on function 
 return.

 Method 2 allows more readability for longer lists of return values, but
 sacrifices understandability in following setting of return values 
 throughout a
 complex control flow.

 Personally, I'd prefer method 2; but perhaps both forms can be supported.

 Calling syntax is up for debate as well:

 : int x;
 : real y;
 : float[] a;
 : (x, y, a) = myfunction(4);

 Thoughts?  Opinions?  Concerns?

 Regards,
 James Dunne
I really can sympathize with the desire for separating input and output. It seems to make so much more sense to do in this fashion. Not only is it simple to understand, but it's clear to read. If you keep input as "input" in the function parameter section, and output separate... well it just seems more intuitive. About the only reason we still use the 'in' and 'out' methods is because of it's relationship to the old C/C++ style; but compatibility with that is simply maintained with the presence or absense '&' operator (more or less, I know... it's more equivalent to inout). Interestingly, we call inputs to a function "arguments" or "parameters" for a reason. We don't think of them as "outputs." That seems to be something computer languages have crammed into the design. In short, James, I like the general idea. It makes much more sense. This may not be the exact way one would go about this, but it's something to think about for the future. At the very least, it would be nice if it were enabled as an "alternative" in D, such that the current scheme would not be lost; breaking huge compatibility might not be a popular move. -JJR
There are alot of things that can be done in new languages, but one of D's design goals is to keep the "look and feel" of C/C++ syntax. I see no problem with the "out" parameter. If it's not broken, don't fix it. unintuitive? well, I have to disagree. Any half decent programmer will find it familiar since it's applied the same way in many other languages. Even if it wasn't so intuitive, it makes for simple syntax. I think multipe return values would add uneeded complexity to the syntax.
Jun 07 2005
parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
John Reimer wrote:
 Hasan Aljudy wrote:
 
 There are alot of things that can be done in new languages, but one of 
 D's design goals is to keep the "look and feel" of C/C++ syntax.

 I see no problem with the "out" parameter. If it's not broken, don't 
 fix it.
 unintuitive? well, I have to disagree. Any half decent programmer will 
 find it familiar since it's applied the same way in many other languages.
 Even if it wasn't so intuitive, it makes for simple syntax.
 I think multipe return values would add uneeded complexity to the syntax.
Hmmm... you stated your opinion already, so there was no need to give it again; and I've been around here longer than you to know what D is about, so you stated nothing that nobody knows already. I was just giving my own opinion on this. I know D's relationship to C. I know languages have used this method of passing/returning arguments for a long time. I just decided to step "outside the box" for a moment and evaluate what might be more logical. What are trying to do? Pick a fight? Well good for you. -JJR
whoa man, chill.
Jun 07 2005
parent John Reimer <brk_6502 yahoo.com> writes:
Hasan Aljudy wrote:
 John Reimer wrote:
 
 Hasan Aljudy wrote:

 There are alot of things that can be done in new languages, but one 
 of D's design goals is to keep the "look and feel" of C/C++ syntax.

 I see no problem with the "out" parameter. If it's not broken, don't 
 fix it.
 unintuitive? well, I have to disagree. Any half decent programmer 
 will find it familiar since it's applied the same way in many other 
 languages.
 Even if it wasn't so intuitive, it makes for simple syntax.
 I think multipe return values would add uneeded complexity to the 
 syntax.
Hmmm... you stated your opinion already, so there was no need to give it again; and I've been around here longer than you to know what D is about, so you stated nothing that nobody knows already. I was just giving my own opinion on this. I know D's relationship to C. I know languages have used this method of passing/returning arguments for a long time. I just decided to step "outside the box" for a moment and evaluate what might be more logical. What are trying to do? Pick a fight? Well good for you. -JJR
whoa man, chill.
Gotchya... sorry. Just a little touchy today. -JJR
Jun 07 2005
prev sibling next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Tue, 7 Jun 2005 13:02:29 +0000 (UTC), James Dunne wrote:

 "out" variables would be much more useful as a set of multiple return values:
 
: (int x, real y, float[] a) myfunction (int b);
 
 I'd say the only complications arise in handling the return statement syntax -
 whether or not to specify a set of return values, or to implicitly return
values
 by setting return-value variables.
 
 method 1: return with a set of values
: (int, real, float[]) myfunction (int b) {
:     return (b + 2, b * 4.5, null);
: }
 
 or
 
 method 2: return by setting return-value variables
: (int x, real y, float[] a) myfunction (int b) {
:     x = b + 2;
:     y = b * 4.5;
:     a = null;
:     return;
: }
 
 Both *examples* are equivalent, but each approach has its strengths and
 weaknesses.  No weaker than forgetting to set an "out" variable as the language
 is now.
 
 Method 1 allows for cleaner reading until the list of return values gets
 unreasonably large.  It also accomodates all return-values on function return.
 
 Method 2 allows more readability for longer lists of return values, but
 sacrifices understandability in following setting of return values throughout a
 complex control flow.
 
 Personally, I'd prefer method 2; but perhaps both forms can be supported.
 
 Calling syntax is up for debate as well:
 
: int x;
: real y;
: float[] a;
: (x, y, a) = myfunction(4);
 
 Thoughts?
What problem is this trying to solve? I'll take a guess at a couple... (A) Making it clearer to a reader looking at a call statement as to which parameters are being modified by the called function. (B) Making the visual appearance of function declarations tidier and thus cheaper to maintain.
 Opinions?
Using some general principles (large changes to the language's syntax should be minimised, D syntax should retain the flavour of the C family, syntax changes must benefit people using the language, syntax changes must not overly complicate the compiler). I think that problem (A) could also be solved by allowing the 'out' specifier on a standard function call. e.g. a = myfunction(4, out x, out y); This could also be used for inout arguments as well. Problem (B) is, in essence, a style issue. It could be said that (int x, real y, float[] a) myfunction (int b) is easier or harder to read than float[] a myfunction (int b, out int x, out real y) depending on the way individuals see things. However, one difference between the two syntaxes is that the current method *requires* that the return value is mandatory but it is not a requirement that the 'out' arguments are updated. The proposed method implies that none of the 'return' values are mandatory, and this is a fundamental idiom shift.
 Concerns?
I suspect that this would be a medium change in the syntax rules and it is a definite step away from the C family syntax. I can see that the problem (A) is one that is justifiably addressed though a simpler way might be better. And problem (B) is not easily fixed because it might mean alternative syntaxes are needed to cater for personal styles. I also suspect that your suggestion would add quite a degree of new complexity to the compiler, as both function declarations and assignment statements would need extra parsing and different code generation. -- Derek Melbourne, Australia 8/06/2005 10:10:02 AM
Jun 07 2005
parent reply James Dunne <james.jdunne gmail.com> writes:
In article <7v4u469qtki1$.1tdcxi3k65eui.dlg 40tude.net>, Derek Parnell says...
On Tue, 7 Jun 2005 13:02:29 +0000 (UTC), James Dunne wrote:

 "out" variables would be much more useful as a set of multiple return values:
 
: (int x, real y, float[] a) myfunction (int b);
 
 I'd say the only complications arise in handling the return statement syntax -
 whether or not to specify a set of return values, or to implicitly return
values
 by setting return-value variables.
 
 method 1: return with a set of values
: (int, real, float[]) myfunction (int b) {
:     return (b + 2, b * 4.5, null);
: }
 
 or
 
 method 2: return by setting return-value variables
: (int x, real y, float[] a) myfunction (int b) {
:     x = b + 2;
:     y = b * 4.5;
:     a = null;
:     return;
: }
 
 Both *examples* are equivalent, but each approach has its strengths and
 weaknesses.  No weaker than forgetting to set an "out" variable as the language
 is now.
 
 Method 1 allows for cleaner reading until the list of return values gets
 unreasonably large.  It also accomodates all return-values on function return.
 
 Method 2 allows more readability for longer lists of return values, but
 sacrifices understandability in following setting of return values throughout a
 complex control flow.
 
 Personally, I'd prefer method 2; but perhaps both forms can be supported.
 
 Calling syntax is up for debate as well:
 
: int x;
: real y;
: float[] a;
: (x, y, a) = myfunction(4);
 
 Thoughts?
What problem is this trying to solve?
We always view changes as trying to solve problems ... interesting. Sometimes I just like to go against the flow of current and try something different, just for change's sake. Some people say, "If it ain't broke, don't fix it." Well, I'd be one to say "It is broke, so I am fixing it"; but to some it just doesn't *look* broke.
I'll take a guess at a couple...

(A) Making it clearer to a reader looking at a call statement as to which
parameters are being modified by the called function.

(B) Making the visual appearance of function declarations tidier and thus
cheaper to maintain.
You certainly nailed the two problems I was trying to solve here!
 Opinions?
Using some general principles (large changes to the language's syntax should be minimised, D syntax should retain the flavour of the C family, syntax changes must benefit people using the language, syntax changes must not overly complicate the compiler).
That's not a sentence, but I get your parenthesized meaning ;). I was more throwing the idea out there because I'm working on my own pet language (ask me about it sometime - here is not the place).
I think that problem (A) could also be solved by allowing the 'out'
specifier on a standard function call.

e.g.

  a = myfunction(4, out x, out y);
Hmm, that could get a bit ugly when your function parameters are numerous. But you're right - it certainly would be clear where the inputs and outputs lie.
This could also be used for inout arguments as well.

Problem (B) is, in essence, a style issue. It could be said that

  (int x, real y, float[] a) myfunction (int b)

is easier or harder to read than 

  float[] a myfunction (int b, out int x, out real y)

depending on the way individuals see things.
Exactly. I think that in order to progress we must disobey the Bob of Backwards Compatibility every now and then. You can't serve two masters.
However, one difference between the two syntaxes is that the current method
*requires* that the return value is mandatory but it is not a requirement
that the 'out' arguments are updated. The proposed method implies that none
of the 'return' values are mandatory, and this is a fundamental idiom
shift.
I noticed this as well. Doesn't it seem odd that forgetting to set the value of "out" arguments is allowed? It seems to me that they are outputs, and not input-outputs, and should be set at all times. Returning an output argument value with its default type initializer just doesn't seem to have much of a point to me. (Unless Exceptions are thrown, but let's not get into that - they're exceptional)
 Concerns?
I suspect that this would be a medium change in the syntax rules and it is a definite step away from the C family syntax. I can see that the problem (A) is one that is justifiably addressed though a simpler way might be better.
Do you have a "simpler way" suggestion? As I said before, I'm working on my own pet language, so any insight you've got could be helpful to me.
And problem (B) is not easily fixed because it might mean
alternative syntaxes are needed to cater for personal styles. I also
suspect that your suggestion would add quite a degree of new complexity to
the compiler, as both function declarations and assignment statements would
need extra parsing and different code generation.

-- 
Derek
Melbourne, Australia
8/06/2005 10:10:02 AM
Regards, James Dunne
Jun 08 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Wed, 8 Jun 2005 13:05:15 +0000 (UTC), James Dunne wrote:


[snip]

What problem is this trying to solve?
We always view changes as trying to solve problems ... interesting. Sometimes I just like to go against the flow of current and try something different, just for change's sake. Some people say, "If it ain't broke, don't fix it." Well, I'd be one to say "It is broke, so I am fixing it"; but to some it just doesn't *look* broke.
Another way of looking at this sort of change is that it involves a cost. Is that cost justified? One way of working that out is to see if it is solving a problem that is already costing us so as to reduce that.
I'll take a guess at a couple...

(A) Making it clearer to a reader looking at a call statement as to which
parameters are being modified by the called function.

(B) Making the visual appearance of function declarations tidier and thus
cheaper to maintain.
You certainly nailed the two problems I was trying to solve here!
Lucky guess ;-)
 Opinions?
Using some general principles (large changes to the language's syntax should be minimised, D syntax should retain the flavour of the C family, syntax changes must benefit people using the language, syntax changes must not overly complicate the compiler).
That's not a sentence, but I get your parenthesized meaning ;).
The final period was meant to be an ellipsis.
  I was more
 throwing the idea out there because I'm working on my own pet language (ask me
 about it sometime - here is not the place).
You have talking pets !?!? :D
I think that problem (A) could also be solved by allowing the 'out'
specifier on a standard function call.

e.g.

  a = myfunction(4, out x, out y);
Hmm, that could get a bit ugly when your function parameters are numerous. But you're right - it certainly would be clear where the inputs and outputs lie.
Beauty is in the eye of the beholder...;-) I suggested this because it is very simple to implement and does not change the syntax in any dramatic manner.
This could also be used for inout arguments as well.

Problem (B) is, in essence, a style issue. It could be said that

  (int x, real y, float[] a) myfunction (int b)

is easier or harder to read than 

  float[] a myfunction (int b, out int x, out real y)

depending on the way individuals see things.
Exactly. I think that in order to progress we must disobey the Bob of Backwards Compatibility every now and then. You can't serve two masters.
Oh! I didn't realize you were asking to replace the current syntax with your alternative. That would break *so* much existing code it could create enemies ;-)
However, one difference between the two syntaxes is that the current method
*requires* that the return value is mandatory but it is not a requirement
that the 'out' arguments are updated. The proposed method implies that none
of the 'return' values are mandatory, and this is a fundamental idiom
shift.
I noticed this as well. Doesn't it seem odd that forgetting to set the value of "out" arguments is allowed? It seems to me that they are outputs, and not input-outputs, and should be set at all times. Returning an output argument value with its default type initializer just doesn't seem to have much of a point to me. (Unless Exceptions are thrown, but let's not get into that - they're exceptional)
To repeat: one of your proposals makes all 'return' values optional.
 Concerns?
I suspect that this would be a medium change in the syntax rules and it is a definite step away from the C family syntax. I can see that the problem (A) is one that is justifiably addressed though a simpler way might be better.
Do you have a "simpler way" suggestion? As I said before, I'm working on my own pet language, so any insight you've got could be helpful to me.
For D, only the one I've already mentioned. However, for a totally new/different language then returning tuples seems a nice idea. The only sugar needed would be some syntax to indicate that you are accepting a pseudo tuple. The simple case would be something like ... tuple A; A = myfunction(4); but a pseudo tuple might be needed if updating elements currently belonging to disparate variables... int A; real B; string C; { A, B, C } = myfunction(4); But back to D, eh? -- Derek Parnell Melbourne, Australia 8/06/2005 11:33:07 PM
Jun 08 2005
parent James Dunne <james.jdunne gmail.com> writes:
In article <ip8as8je57ds$.jwl7zh79xait.dlg 40tude.net>, Derek Parnell says...
On Wed, 8 Jun 2005 13:05:15 +0000 (UTC), James Dunne wrote:


[snip]

What problem is this trying to solve?
We always view changes as trying to solve problems ... interesting. Sometimes I just like to go against the flow of current and try something different, just for change's sake. Some people say, "If it ain't broke, don't fix it." Well, I'd be one to say "It is broke, so I am fixing it"; but to some it just doesn't *look* broke.
Another way of looking at this sort of change is that it involves a cost. Is that cost justified? One way of working that out is to see if it is solving a problem that is already costing us so as to reduce that.
I'll take a guess at a couple...

(A) Making it clearer to a reader looking at a call statement as to which
parameters are being modified by the called function.

(B) Making the visual appearance of function declarations tidier and thus
cheaper to maintain.
You certainly nailed the two problems I was trying to solve here!
Lucky guess ;-)
 Opinions?
Using some general principles (large changes to the language's syntax should be minimised, D syntax should retain the flavour of the C family, syntax changes must benefit people using the language, syntax changes must not overly complicate the compiler).
That's not a sentence, but I get your parenthesized meaning ;).
The final period was meant to be an ellipsis.
  I was more
 throwing the idea out there because I'm working on my own pet language (ask me
 about it sometime - here is not the place).
You have talking pets !?!? :D
African Grey parrots do
I think that problem (A) could also be solved by allowing the 'out'
specifier on a standard function call.

e.g.

  a = myfunction(4, out x, out y);
Hmm, that could get a bit ugly when your function parameters are numerous. But you're right - it certainly would be clear where the inputs and outputs lie.
Beauty is in the eye of the beholder...;-) I suggested this because it is very simple to implement and does not change the syntax in any dramatic manner.
This could also be used for inout arguments as well.

Problem (B) is, in essence, a style issue. It could be said that

  (int x, real y, float[] a) myfunction (int b)

is easier or harder to read than 

  float[] a myfunction (int b, out int x, out real y)

depending on the way individuals see things.
Exactly. I think that in order to progress we must disobey the Bob of Backwards Compatibility every now and then. You can't serve two masters.
Oh! I didn't realize you were asking to replace the current syntax with your alternative. That would break *so* much existing code it could create enemies ;-)
Agreed, but I wasn't referring to D specifically - I have a bad habit of doing that... My bad
However, one difference between the two syntaxes is that the current method
*requires* that the return value is mandatory but it is not a requirement
that the 'out' arguments are updated. The proposed method implies that none
of the 'return' values are mandatory, and this is a fundamental idiom
shift.
I noticed this as well. Doesn't it seem odd that forgetting to set the value of "out" arguments is allowed? It seems to me that they are outputs, and not input-outputs, and should be set at all times. Returning an output argument value with its default type initializer just doesn't seem to have much of a point to me. (Unless Exceptions are thrown, but let's not get into that - they're exceptional)
To repeat: one of your proposals makes all 'return' values optional.
 Concerns?
I suspect that this would be a medium change in the syntax rules and it is a definite step away from the C family syntax. I can see that the problem (A) is one that is justifiably addressed though a simpler way might be better.
Do you have a "simpler way" suggestion? As I said before, I'm working on my own pet language, so any insight you've got could be helpful to me.
For D, only the one I've already mentioned. However, for a totally new/different language then returning tuples seems a nice idea. The only sugar needed would be some syntax to indicate that you are accepting a pseudo tuple. The simple case would be something like ... tuple A; A = myfunction(4); but a pseudo tuple might be needed if updating elements currently belonging to disparate variables... int A; real B; string C; { A, B, C } = myfunction(4);
My new language is more or less like C with a few extensions and a slightly "new" paradigm. I don't want it to turn into LISP by throwing tuples everywhere - only where they make sense.
But back to D, eh?
Indeed. Sorry about my digressions, but it seems this is a familiar place for me to discuss general language features/syntax/ideas.
-- 
Derek Parnell
Melbourne, Australia
8/06/2005 11:33:07 PM
Regards, James Dunne
Jun 08 2005
prev sibling parent reply "Eelco Hoogendoorn" <eelco_hoogendoorn hotmail.com> writes:
seems im the only one who likes this idea?

also, i dont see why it would have to break any code. the compiler should be 
easily capable of converting between both syntaxes, no? its basicly just a 
matter of sweeping all out parameters to the left.

both syntaxes could coexist with a little change here and there.

"James Dunne" <james.jdunne gmail.com> wrote in message 
news:d845t5$2ck6$1 digitaldaemon.com...
 "out" variables would be much more useful as a set of multiple return 
 values:

 : (int x, real y, float[] a) myfunction (int b);

 I'd say the only complications arise in handling the return statement 
 syntax -
 whether or not to specify a set of return values, or to implicitly return 
 values
 by setting return-value variables.

 method 1: return with a set of values
 : (int, real, float[]) myfunction (int b) {
 :     return (b + 2, b * 4.5, null);
 : }

 or

 method 2: return by setting return-value variables
 : (int x, real y, float[] a) myfunction (int b) {
 :     x = b + 2;
 :     y = b * 4.5;
 :     a = null;
 :     return;
 : }

 Both *examples* are equivalent, but each approach has its strengths and
 weaknesses.  No weaker than forgetting to set an "out" variable as the 
 language
 is now.

 Method 1 allows for cleaner reading until the list of return values gets
 unreasonably large.  It also accomodates all return-values on function 
 return.

 Method 2 allows more readability for longer lists of return values, but
 sacrifices understandability in following setting of return values 
 throughout a
 complex control flow.

 Personally, I'd prefer method 2; but perhaps both forms can be supported.

 Calling syntax is up for debate as well:

 : int x;
 : real y;
 : float[] a;
 : (x, y, a) = myfunction(4);

 Thoughts?  Opinions?  Concerns?

 Regards,
 James Dunne 
Jun 17 2005
parent reply Rodolfo Borges <Rodolfo_member pathlink.com> writes:
In article <d8u60n$vdm$1 digitaldaemon.com>, Eelco Hoogendoorn says...
seems im the only one who likes this idea?
me too
"James Dunne" <james.jdunne gmail.com> wrote in message 
news:d845t5$2ck6$1 digitaldaemon.com...
 "out" variables would be much more useful as a set of multiple return 
 values:
 : (int x, real y, float[] a) myfunction (int b);
Good idea, we should learn more from Perl. Not that D should be like Perl, but some good ideas could be borrowed.
 method 1: return with a set of values
 : (int, real, float[]) myfunction (int b) {
 :     return (b + 2, b * 4.5, null);
 : }

 or

 method 2: return by setting return-value variables
 : (int x, real y, float[] a) myfunction (int b) {
 :     x = b + 2;
 :     y = b * 4.5;
 :     a = null;
 :     return;
 : }
 Personally, I'd prefer method 2; but perhaps both forms can be supported.
I think method 1 has to be there. It's much pratical in many situations. Both should be supported.
 Calling syntax is up for debate as well:
 : int x;
 : real y;
 : float[] a;
 : (x, y, a) = myfunction(4);
I prefer: : (int x, real y, float[] a) = myfunction(4); Also: : /* function returning arrays should be flexible: */ : : int[] fA(int n) { : if(n == 1) return 1; : if(n == 2) return [1, 2]; : if(n == 3) return [1, 2, 3]; : return; : } : : a = fA(1); // a=1 : (a, b) = fA(1); // a=1, b=null : (a, b) = fA(2); // a=1, b=2 : (a, b) = fA(3); // a=1, b=2 (third return value discarded) : (a, b) = fA(0); // a=null, b=null : (a, b) = fA(3)[1..3]; // a=2, b=3 : (a, null, b) = fA(3); // a=1, b=3 (discard second value) : (int x, int y) = fA(2); // declare and set : : : /* for list of types, it's more controversial : to loosen syntax restriction so much : */ : : (int i, char c) fM(int n) { : if(n == 1) return 1; // syntax ok? c would be null : if(n == 2) return (1, 'a'); : return; // syntax ok? both would be null : } Rodolfo Borges
Jun 18 2005
parent "Unknown W. Brackets" <unknown simplemachines.org> writes:
Value types, like int and char, cannot be null.  They'd have to be 0 in 
your example.

-[Unknown]


 In article <d8u60n$vdm$1 digitaldaemon.com>, Eelco Hoogendoorn says...
 
seems im the only one who likes this idea?
me too
"James Dunne" <james.jdunne gmail.com> wrote in message 
news:d845t5$2ck6$1 digitaldaemon.com...

"out" variables would be much more useful as a set of multiple return 
values:
: (int x, real y, float[] a) myfunction (int b);
Good idea, we should learn more from Perl. Not that D should be like Perl, but some good ideas could be borrowed.
method 1: return with a set of values
: (int, real, float[]) myfunction (int b) {
:     return (b + 2, b * 4.5, null);
: }

or

method 2: return by setting return-value variables
: (int x, real y, float[] a) myfunction (int b) {
:     x = b + 2;
:     y = b * 4.5;
:     a = null;
:     return;
: }
Personally, I'd prefer method 2; but perhaps both forms can be supported.
I think method 1 has to be there. It's much pratical in many situations. Both should be supported.
Calling syntax is up for debate as well:
: int x;
: real y;
: float[] a;
: (x, y, a) = myfunction(4);
I prefer: : (int x, real y, float[] a) = myfunction(4); Also: : /* function returning arrays should be flexible: */ : : int[] fA(int n) { : if(n == 1) return 1; : if(n == 2) return [1, 2]; : if(n == 3) return [1, 2, 3]; : return; : } : : a = fA(1); // a=1 : (a, b) = fA(1); // a=1, b=null : (a, b) = fA(2); // a=1, b=2 : (a, b) = fA(3); // a=1, b=2 (third return value discarded) : (a, b) = fA(0); // a=null, b=null : (a, b) = fA(3)[1..3]; // a=2, b=3 : (a, null, b) = fA(3); // a=1, b=3 (discard second value) : (int x, int y) = fA(2); // declare and set : : : /* for list of types, it's more controversial : to loosen syntax restriction so much : */ : : (int i, char c) fM(int n) { : if(n == 1) return 1; // syntax ok? c would be null : if(n == 2) return (1, 'a'); : return; // syntax ok? both would be null : } Rodolfo Borges
Jun 18 2005