[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Chicken-users] MV in foreign-lambdas
From: |
Peter Keller |
Subject: |
Re: [Chicken-users] MV in foreign-lambdas |
Date: |
Mon, 7 Oct 2002 16:18:31 -0500 |
User-agent: |
Mutt/1.2i |
On Mon, Oct 07, 2002 at 09:50:10PM +0100, address@hidden wrote:
> > The paradox with the above question is that since C doesn't have
> > multiple return values, the *only* way you can get multiple values back
> > is through the pass by reference mechanism. Because these two concepts
> > are not seperated in C, you cannot seperate them in the scheme interface
> > to it either.
>
> Good point. What about having the equivalent of IN/OUT/INOUT in CORBA
> IDL (and other languages which I forget)?
Well, IN is already implemented in chicken's FFI--a chicken type
unsigned-int gets translated to a C type "unsigned int" and vice versa
(the OUT, read: the return parameter of the function call) without
intervention(for something more complicated, look at c-string).
OUT is a bit wierder since you can only have one of them in both C
and Scheme--except with multiple values in scheme. Frankly, I've never
really understood why multiple values is ever needed since you can always
compose the two sets of results into a single list the function returns
and use accessors to gain access to them. But, that just might be my
stupidity showing through... :) I need to read up on them and see why
they are what they are.
The reason why you're even wanting multiple values is because it seems
difficult to just construct a list that chicken understands and return it.
I suppose you could do this(in chicken C API pseudo code):
(define foo (foreign-lambda* ((int z) (int x) (int y))
"C_word lst = C_ALLOC(C_LIST_ELEMS(3));
C_APPEND_LIST(lst, C_FIX(z));
C_APPEND_LIST(lst, C_FIX(x));
C_APPEND_LIST(lst, C_FIX(y));
return (lst);"))
And now what would be the need of the multiple values, or the OUT construct
that adjusts parameters in the argument list?
> For foreign-lambda*, again, it makes no difference - declare both a
> parameter and a result for the one you want to be inout - but for
> foreign-lambda, if you said #:out, it could be a pure result, and
> #:inout it could be both a parameter and a result...?
Since you can always model IN and OUT easily, the only interesting one is
INOUT. INOUT is really just kind of a shortcut of a functional application
with an accompanying set! so that you don't have to explicitly write it(in
more practical terms though, it is a nice efficiency boost in compiled
code). As an aside, you have to be careful with an INOUT shortcut since
you can't pass immediates to the function anymore....
I think the main problem is that there is a vague area between the
Scheme object implementation representation and the hard type the C
function requires. The problem can be seen here:
(define foo 42)
Now, you, I, and the scheme implementation know that foo is an integer
type--but only because it is tagged in some composite structure as being
an integer(secretly determined though a bit of type inferencing). If you
wanted to pass foo to some C function expecting a int*, then the compiler
has to a) perform a check at runtime to make sure that foo really is an
integer variable just before the C function application, and not just an
immediate, and b) have some internal secret representation of foo where
an actual int* address of the representation itself(only valid if foo
really WAS an integer) can be passed to the C function to be modified. In
this way, you'd be able to do a pass by reference of primitive types to
C functions without any intervention by the programmer at all. However,
the compiler has to be designed with this in mind, and I don't know if
chicken was.
Eh, enough rambling. Where's my coffee!
-pete