From: Bram Geron <[EMAIL PROTECTED]>
   Date: Sat, 05 Jan 2008 23:38:57 +0100

   Hi,

   Currently, argument passing is done using the same code as return value
   passing (with :flat and :slurpy stuff). But there's a small difference:
   argument passing can generate more errors than return value passing
   . . .

It used to be that Parrot did not signal any such errors, because it did
not know what the HLL signatures were.  When Leo++ implemented the
present arg/return passing scheme, the arg-count error was turned on
(gingerly) by default, since that was deemed A Good Thing, but the
return-count error was left off because it was feared (with reason) that
too much code would break.

   . . . If you do $P0 = myfun(), where myfun returns two
   values, then the first value is stored in $P0 and that's it. This is
   wanted behaviour for a lot of languages, I think. A lesser known fact is
   probably that if myfun returns no values, then $P0 is unchanged.

Hmm.  This ought to be documented better.

   Very few languages want this, I think. For example, Common Lisp fills
   missing values with nil, and Perl with undef. Octave and Scheme seem to
   error. Are there languages with other behaviour?

Scheme errors because returning multiple values *is* argument passing,
and that's how argument passing in Scheme works.  (And Schemers would
gag on the inconsistency.  ;-)

   Creating Octave/Scheme behaviour is easy.

       errorson .PARROT_ERRORS_RESULT_COUNT_FLAG

Deceptively easy.  The problem with this is that it affects all bytecode
running in that interpreter, no matter what language it came from.  This
is going to break other languages' assumptions.

   The simplest thing I can imagine to create CL/Perl behavior is to
   initialize $P0 with nil/undef. But it Doesn't Feel Right(tm) to me doing
   this every time. What's your opinion?

To receive values, the Kea-CL compiler generates code like this:

                . . .
                ($P42 :optional, $I42 :opt_flag) = $P44($P40)
                $P45 = constants[1]     ## NIL
                if $I42 goto L1
                $P42 = $P45
        L1:
                . . .

This is semi-robust w.r.t. PARROT_ERRORS_RESULT_COUNT_FLAG:  If the flag
is on, this call doesn't complain if $P44 returns zero values, and is
insensitive to what Parrot does with $P42 in that case.  On the other
hand, it would fail if $P44 returned two or more values.  Adding another
"$P999 :slurpy" arg would fix that, but at the cost of allocating an
array (usually empty) for each call -- which is why I don't bother.
Better would be an ":ignored" keyword that skipped the slurp step
without allocating anything.  (Seems to me this was discussed at one
point, but was not a priority.)

   Granted, it would be slicker to have a way to say "optional-
defaulting-to-something" for all return values, but as you point out,
different languages have different requirements for what that
"something" should be.  So I think the current mechanism for defaulting
is acceptable; there are more important fish to fry.

   (BTW, initializing $P42 with NIL in advance would require fewer
instructions, but would break if $P42 were a lexical variable that was
used by the $P44 sub; it would expect to see the original value before
assignment.  It's a good idea for optimization, though.)

   Other question: what should compilers do for languages that don't
   support multiple values? If such a language allows calling functions
   from other languages, I can imagine obscure bugs appearing.

   Cheers,
   Bram Geron

Good point.  Perhaps we need PIR syntax like:

                () = $P44($P40)

to require exactly zero values, and

                ($P42 :required) = $P44($P40)

to require exactly one?

   In any case, I would argue that such things are lexically determined,
usually by the language, and would ditch PARROT_ERRORS_RESULT_COUNT_FLAG
entirely in favor of PIR syntax at the point of call to give each
compiler complete control.  This, IMHO, would be worth the trouble.

                                        -- Bob Rogers
                                           http://rgrjr.dyndns.org/

Reply via email to