[bitc-dev] Variable Arity Functions?

Jonathan S. Shapiro shap at eros-os.org
Fri Feb 17 22:12:32 EST 2006


On Sat, 2006-02-18 at 02:30 +0000, David Hopwood wrote:
> > at one point, we had in mind that the rule would be "pair consing" --
> > that is, that an application of the form above would be interpreted as
> > 
> > 	(a (pair b (pair c ( ... (pair y z)))))
> 
> Or (a (pair b (pair c ( ... (pair y (pair z nil))))), which allows the
> arity zero case to be neatly expressed as (a nil).

Unfortunately not. PAIR is not CONS. PAIR is a *value* type, and there
is no direct equivalent to NIL.

The closest analogy to what you write would be:
  (pair a (pair b ( ... (pair y (pair z ())))))

where the last () is the way to write UNIT in BitC (i.e. it is not NIL).
The problem with this is that we need to generate a C structure for that
last pair, which is going to end up being something like:

   struct pair_SomeUglyMangle {
     __typeof(z) fst;
     bitc_unit_t snd;
   };

The C language does not have any means to specify a type that occupies
zero bits, so the BitC runtime currently typedef's bitc_unit_t to
'char'.

Now all of this still might work, because that unit value is at the end
of the frame, so we will end up with a call frame that is compatible
with C.  Like I said, we need to go back and look at it.

But stop and think about think about the declaration of C printf:

	(proclaim printf : (fn (string 'a) word))

Do we mean for that second argument to be a varargs argument, or do we
mean for it to be a singleton? If we do implicit pair-consing, it
actually becomes impossible NOT to do varargs functions, and we would
lose the ability to check argument counts.

One option, I suppose, would be to reserve syntactic support for this,
perhaps:

	(proclaim printf : (fn (string 'a ...) word))

but then we are left with the following interesting oddity. Given:

	(proclaim f: (fn ('a 'b) 'a))

the call

	(f 1 2)

is legal, and the calls

	(f 1 (pair 2 3))
	(f 1 (pair 2 (pair 3 ()))

are legal, but the call

	(f 1 2 3)

is not, even though under the pair-consing rule it is semantically
identical to

	(f 1 (pair 2 3))
or	(f 1 (pair 2 (pair 3 ())))

depending on which specification of pair-consing we are using. This is
just weird. We felt that it was important to be able to check the
argument arity at the call site.

However, all is not lost. Consider that we can accomplish something very
close to printf as follows:

	(printf "ab%s\{linefeed}" (tuple rest-of-args))

this constructs a call frame that is compatible in all respects with C's
printf specification...

> In order
> > to really deal with variadic procedures, you really do need to introduce
> > something like type classes,
> 
> Or a Dynamic type...

Yes. We have explicitly rejected dynamic types in BitC. We did it on
purpose, and we're not going to back off from that.


shap



More information about the bitc-dev mailing list