August 19, 2001
"Bradeeoh" <bradeeoh@crosswinds.net> wrote in message news:9lnd7k$1eh8$1@digitaldaemon.com...
>
> > countAnimals() returns (int cats, int dogs, int ferrets, int goats)
> > {
> >     ....
> > }
> >
> >
> > I prefer the latter.  Anyone else really like it?  Hate it?
>
>
> That is intriguing.  Definately clear, and it could be reasonably useful.
I
> have a couple of nitpicks, one major and one minor.  Major - what is the
> formal return type of this function?  I notice you just wrote -
> countAnimals() returns (int.......goats)
>
> there is nothing before the function name.  Granted, the return type is implicitly 4 integers, but I think one of the things (possibly) holding
this
> feature back is that 4 integers is neither a primitive data type, nor a class/struct/union type.  It's just.... 4... different primitive data
types.
> If you can give a formal, simple definition as to the return type of the function, it may be worth looking into and could end up being something incredibly useful.  ;)

Hi There Bradeeoh (wassat then? :-) ).

I'm not too sure what the problem is.  I do see that 4 ints is not a primitve data type (or struct) but I don't see why that should be an issue. Are you thinking that this might provide a problem for the stack frame?  I don't see why - we have lists of parameters, lists of return types should be too hard.

Have I misunderstood your point?

> The minor nitpick - A number of ways to do this just ran through my head, but I noticed you haven't touched on the point at all - what is the syntax of return the values within the function?
>
> I'm sure you're thinking something as simple as "return
> (cats,dogs,ferrets,goats);" but, of course, that may also not be as simple
> as it seems....  ;)

Hey, I'm keen on being enlightened - what are the problems you see?  I *was* thinking "return(cats,dogs,ferrets,goats);" for the return syntax - it would be illegal to return more or less than the stated number of values just as it is illegal to call a function w/o the correct number of parameters.

Feel free to expand on the idea / issues.

Peter.



August 19, 2001
In article <9lo1e0$1r4e$1@digitaldaemon.com>, "kaffiene" <kaffiene@xtra.co.nz> wrote:
> "Bradeeoh" <bradeeoh@crosswinds.net> wrote in message news:9lnd7k$1eh8$1@digitaldaemon.com...

>> have a couple of nitpicks, one major and one minor.  Major - what is
>> the formal return type of this function?  I notice you just wrote -
>> countAnimals() returns (int.......goats)

> I'm not too sure what the problem is.  I do see that 4 ints is not a primitve data type (or struct) but I don't see why that should be an issue. Are you thinking that this might provide a problem for the stack frame?  I don't see why - we have lists of parameters, lists of return types should be too hard.
> 

i also don't see the problem. this is easy even to translate into C:
you just create a temporary structure with four members in it.
In fact, its precisely because one has to do this so often, that
it should be part of the language in the first place: ala Python.

I do agree that the names of the return values should be part of the declaration.

We can extend this further. The C declaration for read(),

	int read (int fd, char *buf, int size);

should REALLY be:

	(bytes_done_or_error int) read (int fd, char *buf, int size);
	/* (pick a notation you like) */

if you think about it, its ridiculous that, in C, the function declaration
should describe everything that the function is passed, but not what
it returns!!! Imagine the other extreme: header files containing:

	int read (int, char *, int);

which is legal ANSI C (sic).

-paul

-- 
Paul Sheer Consulting IT Services . . . Tel . . . +27 21 761 7224 Linux development, cryptography,  recuitment,  support,  training http://www.icon.co.za/~psheer . . . . http://rute.sourceforge.net L I N U X . . . . . . . . . . . .  The Choice of a GNU Generation

August 19, 2001
>
> Hi There Bradeeoh (wassat then? :-) ).
>
> I'm not too sure what the problem is.  I do see that 4 ints is not a primitve data type (or struct) but I don't see why that should be an
issue.
> Are you thinking that this might provide a problem for the stack frame?  I don't see why - we have lists of parameters, lists of return types should
be
> too hard.
>
> Have I misunderstood your point?
>

I guess the problem I'm seeing, especially as I'm not able to describe it well, is just a matter of how I "feel" about it.  I just cringe when I see it, but I cannot explain why.  The points you and others makes about it's ease of implementation, etc, are well taken.

So, to just say what Walter has said about a few other features that are up
for debate, it just doesn't "feel right".  :)
I will gracefully bow out in my debate on this topic. :)

I can make one solid point on the subject, however - I don't deny for a second this feature could be useful, but if it's chosen to be implemented, be very careful on the syntax chosen, as it could potentially turn out looking quite messy.  :)

-Brady


August 19, 2001
Just use contracts; that's what they're there for.  The contract will specify that the returned array should have three elements, and the code will (!)be commented to describe the returned contents.  Keep it simple!


> Consider these possible declarations:
>
> int[] foo();   // returns an array of ints, unknown size
> int[3] foo();   // returns an array of ints, guaranteed to be 3 long.
might
> throw an exception if function tried to return something else
>


August 19, 2001
> 
> I guess the problem I'm seeing, especially as I'm not able to describe it well, is just a matter of how I "feel" about it.  I just cringe when I see it, but I cannot explain why.  The points you and others makes about it's ease of implementation, etc, are well taken.
> 
> So, to just say what Walter has said about a few other features that are up for debate, it just doesn't "feel right".  :) I will gracefully bow out in my debate on this topic. :)
> 
> I can make one solid point on the subject, however - I don't deny for a second this feature could be useful, but if it's chosen to be implemented, be very careful on the syntax chosen, as it could potentially turn out looking quite messy.  :)
> 

yeah, i understand exactly.

none-the-less, the uglyness of trying to return multiple values has crudded up C for long enough. So this is a problem that REALLY needs fixing.

Another reason for multiple return values is simply this: in assembler,
the compiler pushes multiple arguments onto the stack whenever it does
a function call. The return value is pushed onto the stack at the end
of the function call.   C arbitrarily chose to limit the number of return
pushes to 1, even though the number of calling pushes could be many.
(Am i correct here?).

This limitation has infected all development to date. The read() function
call CLEARLY returns two values: an error code, and the number of
bytes. These are two conceptually different things. To roll them into one
value is the ugliest thing i can think of. And yet every API tries to work
around this limitation instead of extending the language in a very simple
way.

Imagine the elegance of being able to trust the return value of a read() call without having to check if it is  -1  before-hand ?!  Instead, we create extra conditionals in the calling code AND extra conditionals in the function code. All because we are trying to squeeze into the limitation of single return values.

-paul

-- 
Paul Sheer Consulting IT Services . . . Tel . . . +27 21 761 7224 Linux development, cryptography,  recuitment,  support,  training http://www.icon.co.za/~psheer . . . . http://rute.sourceforge.net L I N U X . . . . . . . . . . . .  The Choice of a GNU Generation

August 20, 2001
Another issue with that is: what happens if you use it as a function argument
(that is, f(g()), where g() return 4 things)? Does this give 4 arguments to
f(), or is it simply forbidden?

Christophe

Bradeeoh wrote:

> > countAnimals() returns (int cats, int dogs, int ferrets, int goats)
> > {
> >     ....
> > }
> >
> >
> > I prefer the latter.  Anyone else really like it?  Hate it?
>
> That is intriguing.  Definately clear, and it could be reasonably useful.  I have a couple of nitpicks, one major and one minor.  Major - what is the formal return type of this function?  I notice you just wrote - countAnimals() returns (int.......goats)
>
> there is nothing before the function name.  Granted, the return type is implicitly 4 integers, but I think one of the things (possibly) holding this feature back is that 4 integers is neither a primitive data type, nor a class/struct/union type.  It's just.... 4... different primitive data types. If you can give a formal, simple definition as to the return type of the function, it may be worth looking into and could end up being something incredibly useful.  ;)
>
> The minor nitpick - A number of ways to do this just ran through my head, but I noticed you haven't touched on the point at all - what is the syntax of return the values within the function?
>
> I'm sure you're thinking something as simple as "return
> (cats,dogs,ferrets,goats);" but, of course, that may also not be as simple
> as it seems....  ;)
>
> -Brady

August 20, 2001
"Christophe de Dinechin" <descubes@earthlink.net> wrote in message news:3B80D256.4DC6BEE8@earthlink.net...
> Another issue with that is: what happens if you use it as a function
argument
> (that is, f(g()), where g() return 4 things)? Does this give 4 arguments
to
> f(), or is it simply forbidden?

There are two obvious answers - either allow it only if the number of return values from g() matches the number of parameters to f() or disallow it on principle. You could argue that there are pros and cons each way.  I don't think it matters much as long as the compiler knows which one it's doing ;-)

Peter.


> Bradeeoh wrote:
>
> > > countAnimals() returns (int cats, int dogs, int ferrets, int goats)
> > > {
> > >     ....
> > > }
> > >
> > >
> > > I prefer the latter.  Anyone else really like it?  Hate it?
> >
> > That is intriguing.  Definately clear, and it could be reasonably
useful.  I
> > have a couple of nitpicks, one major and one minor.  Major - what is the
> > formal return type of this function?  I notice you just wrote -
> > countAnimals() returns (int.......goats)
> >
> > there is nothing before the function name.  Granted, the return type is implicitly 4 integers, but I think one of the things (possibly) holding
this
> > feature back is that 4 integers is neither a primitive data type, nor a class/struct/union type.  It's just.... 4... different primitive data
types.
> > If you can give a formal, simple definition as to the return type of the function, it may be worth looking into and could end up being something incredibly useful.  ;)
> >
> > The minor nitpick - A number of ways to do this just ran through my
head,
> > but I noticed you haven't touched on the point at all - what is the
syntax
> > of return the values within the function?
> >
> > I'm sure you're thinking something as simple as "return (cats,dogs,ferrets,goats);" but, of course, that may also not be as
simple
> > as it seems....  ;)
> >
> > -Brady
>


August 21, 2001
"Bradeeoh" <bradeeoh@crosswinds.net> wrote in message news:9lnene$1flr$1@digitaldaemon.com...
>
> >
> > In my view, it's a design distinction between "return an array of
values"
> (that
> > might have any number of values) and "return three integers".  Consider
a
> new
> > strtoul():
> >
> > int[2] strtoul(char *str,int base)

This can be easily written as
typedef struct _strtoulReturnValue { long result; int CharactresUsed; }
StrToUlReturn;

Then you access the result with
    r = strtoul("978"...);
    r.CharactersUsed

what is clearer than
    int r[2]= strtoul("123"...);
    r[1]

Those absolute indexes, so necessary sometimes aren't in this example well
choosen. Arrays haven't got named fields, more appropiate for a function
result. Of course
    int r[1024*768] = CopyScreen();

is a better example for an application of arrays being returned from functions.



August 21, 2001
"Grobbins" <grobbins@badaddress.znet.com> wrote:

> > I think this is a much better idea than in, out and inout
> > parameters.  Given something like this:
> > int a,b,x;
> > a,b = myfunc(x);
> > it's obvious the role that a,b and x play
>
> While multiple return parameters seem elegant, you end up with code that is harder to read and maintain.  Consider
>
>   int,int,int,int CountAnimals();
>
> which is called
>
>   numCats,numDogs,numFerrets,numGoats = CountAnimals();
>
> Without parameter names attached to the output values in the declaration, it's hard to know if I've picked up the return values correctly.

Then why not

int numCats, int numDogs, int numFerrets, int numGoats CountAnimals()
{
    if(m_ThisPlaceIsAPound)
    {
        numCats = 10; numDogs = 13; numFerrets = 1; numGoats = 0;
        return;
    }
    else if(m_ThisPlaceIsAPettingZoo)
    {
        numCats = 0; numDogs = 0; numFerrets = 1; numGoats = 3;
        return;
    }

    numCats = 0; numDogs = 0; numFerrets = 0;

    return; // compile time error: not all paths initialize 'numGoats'
}

What am I missing here?

Angus Graham


August 21, 2001
psheer AT icon DOT co DOT za wrote:
> none-the-less, the uglyness of trying to return multiple values has crudded up C for long enough. So this is a problem that REALLY needs fixing.
> 
> Another reason for multiple return values is simply this: in assembler,
> the compiler pushes multiple arguments onto the stack whenever it does
> a function call. The return value is pushed onto the stack at the end
> of the function call.   C arbitrarily chose to limit the number of return
> pushes to 1, even though the number of calling pushes could be many.
> (Am i correct here?).

Well, back when I still cared what the code coming out of a compiler looked like (1987-1992?), most compilers I was familiar with returned values in the "most temporary" register: (E)AX on x86, D0 on 68K, etc. -- not on the stack.

Is returning a struct really so ugly?

  struct ReturnValue
  {
     bool   success;
     int    errno;    // or perhaps "enum EErrno errno"
     int    value;
  };

  ReturnValue read( int fd, char* buf, size_t size );

  // hmm, can you access a member of the result of a function call?
  if (!read( filedesc, buffer, size ).success)
  {
     printf("read failed, sucks to be you...\n" );
  }


This assumes that a lot of functions can use this common
return value structure, but I think that's reasonable: it tells
whether or not the function succeeded, why it failed if it failed,
and what/how much it accomplished if it succeeded. You could
roll the bool and the errno together, or make the bool a
method instead of a datum:

      bool success( void ) { errno == EErrno_NoError; }

-RB