August 21, 2001
kaffiene wrote:

> "Russell Bornschlegel" <kaleja@estarcion.com> wrote in message news:3B82E1F6.851406A@estarcion.com...
> >
> >
> > kaffiene wrote:
> > >
> > > "Russell Bornschlegel" <kaleja@estarcion.com> wrote in message news:3B82917B.FB34BD40@estarcion.com...
> > > > So, I repeat the question: is returning a struct from a commonly used library routine such an ugly construct that we need to come up with a better way to handle the return of multiple values from a function?
> > > >
> > >
> > > You cannot guarantee that all fields of a struct are populated.
> >
> > Give it a constructor.
>
> You can guarantee the struct has initialisers (or constructors if D had them for structs) on user functions.  The compiler can guarantee a binding for returned values from *all* functions.
>
> > > You have to have different structs for different kinds of functions,
> making
> > > the number of types you have to learn to use system functions much
> larger
> > > (plus this multiplies per user function which has a different struct
> return
> > > type)
> >
> > This point is granted; you can define your APIs in such a way that the number of return-struct types is minimized, however.
> >
> > > And YES it is *UGLY* =)
> >
> > Well, I'm not thrilled with:
> >
> >    numCats,numDogs,numFerrets,numGoats = CountAnimals();
> >
> > ...either. I think the parser would want at least some sort of marker around the return list, also, something like:
> >
> >   [numCats, numDogs, numFerrets, numGoats] = CountAnimals();
> >   {numCats, numDogs, numFerrets, numGoats} = CountAnimals();
> >   (numCats, numDogs, numFerrets, numGoats) = CountAnimals();
> >   <numCats, numDogs, numFerrets, numGoats> = CountAnimals();
> >   [numCats, numDogs, numFerrets, numGoats] = CountAnimals();
> >   `numCats, numDogs, numFerrets, numGoats` = CountAnimals();
> >   \numCats, numDogs, numFerrets, numGoats\ = CountAnimals();
>
> No - a compiler can do:
>
>     a,b = myfunc(x);

Actually, the compiler will mis-recognize that as a compound statement:

a
,
b = myfunc(x);


August 21, 2001
> > > > So, I repeat the question: is returning a struct from a commonly used library routine such an ugly construct that we need to come up with a better way to handle the return of multiple values from a function?
> > > >
> > >
> > > You cannot guarantee that all fields of a struct are populated.
> >
> > Give it a constructor.
>
> You can guarantee the struct has initialisers (or constructors if D had
them
> for structs) on user functions.  The compiler can guarantee a binding for returned values from *all* functions.

oops!  that should have been "... cannot guarantree the struct has initialisers..."

sorry =)

Peter.


August 21, 2001
"Russ Lewis" <russ@deming-os.org> wrote in message news:3B82EEBD.BAB2CA67@deming-os.org...
> kaffiene wrote:
>
> > "Russell Bornschlegel" <kaleja@estarcion.com> wrote in message news:3B82E1F6.851406A@estarcion.com...
> > >
> > >
> > > kaffiene wrote:
> > > >
> > > > "Russell Bornschlegel" <kaleja@estarcion.com> wrote in message news:3B82917B.FB34BD40@estarcion.com...
> > > > > So, I repeat the question: is returning a struct from a commonly used library routine such an ugly construct that we need to come up with a better way to handle the return of multiple values from a function?
> > > > >
> > > >
> > > > You cannot guarantee that all fields of a struct are populated.
> > >
> > > Give it a constructor.
> >
> > You can guarantee the struct has initialisers (or constructors if D had
them
> > for structs) on user functions.  The compiler can guarantee a binding
for
> > returned values from *all* functions.
> >
> > > > You have to have different structs for different kinds of functions,
> > making
> > > > the number of types you have to learn to use system functions much
> > larger
> > > > (plus this multiplies per user function which has a different struct
> > return
> > > > type)
> > >
> > > This point is granted; you can define your APIs in such a way that the number of return-struct types is minimized, however.
> > >
> > > > And YES it is *UGLY* =)
> > >
> > > Well, I'm not thrilled with:
> > >
> > >    numCats,numDogs,numFerrets,numGoats = CountAnimals();
> > >
> > > ...either. I think the parser would want at least some sort of marker around the return list, also, something like:
> > >
> > >   [numCats, numDogs, numFerrets, numGoats] = CountAnimals();
> > >   {numCats, numDogs, numFerrets, numGoats} = CountAnimals();
> > >   (numCats, numDogs, numFerrets, numGoats) = CountAnimals();
> > >   <numCats, numDogs, numFerrets, numGoats> = CountAnimals();
> > >   [numCats, numDogs, numFerrets, numGoats] = CountAnimals();
> > >   `numCats, numDogs, numFerrets, numGoats` = CountAnimals();
> > >   \numCats, numDogs, numFerrets, numGoats\ = CountAnimals();
> >
> > No - a compiler can do:
> >
> >     a,b = myfunc(x);
>
> Actually, the compiler will mis-recognize that as a compound statement:
>
> a
> ,
> b = myfunc(x);

What I am saying is that you can write a compiler to recognise that - have you ever used yacc or bison?

Peter.


August 21, 2001
kaffiene wrote:

> "Russ Lewis" <russ@deming-os.org> wrote in message news:3B82EEBD.BAB2CA67@deming-os.org...
> > kaffiene wrote:
> >
> > > "Russell Bornschlegel" <kaleja@estarcion.com> wrote in message news:3B82E1F6.851406A@estarcion.com...
> > > >
> > > >
> > > > kaffiene wrote:
> > > > >
> > > > > "Russell Bornschlegel" <kaleja@estarcion.com> wrote in message news:3B82917B.FB34BD40@estarcion.com...
> > > > > > So, I repeat the question: is returning a struct from a commonly used library routine such an ugly construct that we need to come up with a better way to handle the return of multiple values from a function?
> > > > > >
> > > > >
> > > > > You cannot guarantee that all fields of a struct are populated.
> > > >
> > > > Give it a constructor.
> > >
> > > You can guarantee the struct has initialisers (or constructors if D had
> them
> > > for structs) on user functions.  The compiler can guarantee a binding
> for
> > > returned values from *all* functions.
> > >
> > > > > You have to have different structs for different kinds of functions,
> > > making
> > > > > the number of types you have to learn to use system functions much
> > > larger
> > > > > (plus this multiplies per user function which has a different struct
> > > return
> > > > > type)
> > > >
> > > > This point is granted; you can define your APIs in such a way that the number of return-struct types is minimized, however.
> > > >
> > > > > And YES it is *UGLY* =)
> > > >
> > > > Well, I'm not thrilled with:
> > > >
> > > >    numCats,numDogs,numFerrets,numGoats = CountAnimals();
> > > >
> > > > ...either. I think the parser would want at least some sort of marker around the return list, also, something like:
> > > >
> > > >   [numCats, numDogs, numFerrets, numGoats] = CountAnimals();
> > > >   {numCats, numDogs, numFerrets, numGoats} = CountAnimals();
> > > >   (numCats, numDogs, numFerrets, numGoats) = CountAnimals();
> > > >   <numCats, numDogs, numFerrets, numGoats> = CountAnimals();
> > > >   [numCats, numDogs, numFerrets, numGoats] = CountAnimals();
> > > >   `numCats, numDogs, numFerrets, numGoats` = CountAnimals();
> > > >   \numCats, numDogs, numFerrets, numGoats\ = CountAnimals();
> > >
> > > No - a compiler can do:
> > >
> > >     a,b = myfunc(x);
> >
> > Actually, the compiler will mis-recognize that as a compound statement:
> >
> > a
> > ,
> > b = myfunc(x);
>
> What I am saying is that you can write a compiler to recognise that - have you ever used yacc or bison?
>
> Peter.

No, I haven't used either, though from what I've heard they're very good.

Sorry to misunderstand - I thought that you meant that it would be an easy addition to the language as-is.

August 22, 2001

Russ Lewis wrote:
> 
> Russell Bornschlegel wrote:
> 
> > kaffiene wrote:
> > >
> > > "Russell Bornschlegel" <kaleja@estarcion.com> wrote in message news:3B82917B.FB34BD40@estarcion.com...
> > > > So, I repeat the question: is returning a struct from a commonly used library routine such an ugly construct that we need to come up with a better way to handle the return of multiple values from a function?
> > > >
> > >
> > > You cannot guarantee that all fields of a struct are populated.
> >
> > Give it a constructor.
> 
> Remember that in D structs are NOT classes, so they don't have constructors or other member functions.  You can define default initializers for all of the members, though.

/me rolls eyes

Sorry. Make the return type a class.

-RB
August 22, 2001
"Russell Bornschlegel" <kaleja@estarcion.com> wrote in message news:3B82FFBA.BB5CB70D@estarcion.com...
>
>
> Russ Lewis wrote:
> >
> > Russell Bornschlegel wrote:
> >
> > > kaffiene wrote:
> > > >
> > > > "Russell Bornschlegel" <kaleja@estarcion.com> wrote in message news:3B82917B.FB34BD40@estarcion.com...
> > > > > So, I repeat the question: is returning a struct from a commonly used library routine such an ugly construct that we need to come up with a better way to handle the return of multiple values from a function?
> > > > >
> > > >
> > > > You cannot guarantee that all fields of a struct are populated.
> > >
> > > Give it a constructor.
> >
> > Remember that in D structs are NOT classes, so they don't have
constructors or
> > other member functions.  You can define default initializers for all of
the
> > members, though.
>
> /me rolls eyes
>
> Sorry. Make the return type a class.
>


then you can't guarantee that the class has a constructor for user functions which implement this pattern


August 22, 2001
Russell Bornschlegel <kaleja@estarcion.com> writes:

> Well, I'm not thrilled with:
> 
>    numCats,numDogs,numFerrets,numGoats = CountAnimals();

For example, if we are calling CountAnimals inside a member function, and want to set the return values in miscellanous member variables, it will be quite clumsy to make a seperate class the return values.  I like the Perl way:

(foo, bar) = func();

This would be very useful.

-- 
Teemu Hirsimäki
August 22, 2001
It's not ugly, but it's infrequent enough that most compilers generate inefficient code for that. Hence people don't use it. Catch 22.

Typically, you get a lot of extra copies while returning a struct (at least one, sometimes 2). LX tries to solve that with the "result" pseudo-variable.

Christophe

Russell Bornschlegel wrote:

> Richard Krehbiel wrote:
> >
> > "Russell Bornschlegel" <kaleja@estarcion.com> wrote in message news:3B81DC85.7321FD3E@estarcion.com...
> > >   // 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" );
> > >   }
> >
> > I just tested this, and it compiled and worked. [snip example]
>
> In C, no less! Will wonders never cease. (What compiler was that,
> by the way?)
>
> So, I repeat the question: is returning a struct from a commonly used library routine such an ugly construct that we need to come up with a better way to handle the return of multiple values from a function?
>
> -RB

August 23, 2001
"Christophe de Dinechin" <descubes@earthlink.net> wrote in message news:3B841E54.D4D364A9@earthlink.net...
> Russell Bornschlegel wrote:
> > So, I repeat the question: is returning a struct from a commonly used library routine such an ugly construct that we need to come up with a better way to handle the return of multiple values from a function?
>
> It's not ugly, but it's infrequent enough that most compilers generate inefficient code for that. Hence people don't use it. Catch 22.
>
> Typically, you get a lot of extra copies while returning a struct (at least one, sometimes 2). LX tries to solve that with the "result" pseudo-variable.

GCC also offers that extension.

struct bigstruct func(void) return bs
{
    bs.a = 0;
    // ... whatever...
    return;
}

When I first saw that, I wondered if the compiler could optimize-away the extra copying away.

I recall that Lattice C for the Amiga ASM calling conventions specified that to call a function which returns a struct, the caller passes in the address where the function should place the struct.  The called function could build the return value right there (using the "result" spec, or by compiler optimization).  And in fact, the compiler may have optimized "struct T a; a = func();" by calling func() giving a pointer to a, resulting in *no* struct copying.

--
Richard Krehbiel, Arlington, VA, USA
rich@kastle.com (work) or krehbiel3@home.com (personal)


August 25, 2001
Teemu Hirsimaki wrote:
> 
> Russell Bornschlegel <kaleja@estarcion.com> writes:
> 
> > Well, I'm not thrilled with:
> >
> >    numCats,numDogs,numFerrets,numGoats = CountAnimals();
> 
> For example, if we are calling CountAnimals inside a member function, and want to set the return values in miscellanous member variables, it will be quite clumsy to make a seperate class the return values.  I like the Perl way:
> 
> (foo, bar) = func();
> 
> This would be very useful.
> 
> --
> Teemu Hirsimäki

It's also nicer when you want the returned data in certain variables ratherthan a struct.  Less copying than.

ret_t ret = func();
foo = ret.f;
bar = ret.b;


Dan