Re: branches/leo-ctx5 update

0 views
Skip to first unread message

Patrick R. Michaud

unread,
Jul 7, 2005, 9:40:44 AM7/7/05
to Leopold Toetsch, Perl 6 Internals
On Thu, Jul 07, 2005 at 03:36:01PM +0200, Leopold Toetsch wrote:
> I've now implement full type conversions, thus making argument passing
> strictly positional. This also implies that we don't need separate
> argument counts per register type, these are gone now.
>
> Instead we have the new opcode:
>
> get_argc(out INT)
>
> which returns the argument/result count of the recent call/return.

Yay!

Pm

Leopold Toetsch

unread,
Jul 7, 2005, 9:36:01 AM7/7/05
to Perl 6 Internals
I've now implement full type conversions, thus making argument passing
strictly positional. This also implies that we don't need separate
argument counts per register type, these are gone now.

Instead we have the new opcode:

get_argc(out INT)

which returns the argument/result count of the recent call/return.

leo

Chip Salzenberg

unread,
Jul 7, 2005, 10:55:50 AM7/7/05
to Leopold Toetsch, Perl 6 Internals
On Thu, Jul 07, 2005 at 03:36:01PM +0200, Leopold Toetsch wrote:
> Instead we have the new opcode:
> get_argc(out INT)
> which returns the argument/result count of the recent call/return.

Why do we need this?
--
Chip Salzenberg <ch...@pobox.com>

Will Coleda

unread,
Jul 7, 2005, 10:57:40 AM7/7/05
to Chip Salzenberg, Leopold Toetsch, Perl 6 Internals
To manage varargs-style subroutines?

Leopold Toetsch

unread,
Jul 7, 2005, 11:28:04 AM7/7/05
to Chip Salzenberg, Perl 6 Internals
Chip Salzenberg wrote:
> On Thu, Jul 07, 2005 at 03:36:01PM +0200, Leopold Toetsch wrote:
>
>>Instead we have the new opcode:
>> get_argc(out INT)
>>which returns the argument/result count of the recent call/return.
>
>
> Why do we need this?

To know, if :optional args where passed in or not.

leo

Patrick R. Michaud

unread,
Jul 7, 2005, 11:43:45 AM7/7/05
to Chip Salzenberg, Will Coleda, Leopold Toetsch, Perl 6 Internals
On Thu, Jul 07, 2005 at 11:22:27AM -0400, Chip Salzenberg wrote:
> On Thu, Jul 07, 2005 at 10:09:27AM -0500, Patrick R. Michaud wrote:
> > On Thu, Jul 07, 2005 at 11:05:00AM -0400, Chip Salzenberg wrote:
> > > On Thu, Jul 07, 2005 at 10:57:40AM -0400, Will Coleda wrote:
> > > > To manage varargs-style subroutines?
> > >
> > > But that's what :slurpy is for.
> >
> > But :slurpy always pulls things into a PMC (and creates PMCs
> > along the way).
> >
> > We need get_argc in order to know how many things were passed
> > into params marked :optional .
>
> Hm. Well, as long as everybody knows it defeats lazy evaluation, I
> guess that works.

Well, there's another way of looking at it: I don't really need
to know exactly how many total arguments were passed in by the caller,
I just need to know how many :optional param registers were filled
in. In other words, with something like

.sub "foo"
.param int beta
.param string gamma :optional
.param string delta :optional
.param pmc epislon :slurpy

I think it's okay if get_argc (which perhaps should be called something
else) simply tells me something like "4" -- the number of registers
filled in -- even if epsilon ends up (lazily?) grabbing 100 arguments
from a list.

If I need to know the number of arguments slurped, I can just check
the length of the slurpy pmc.

So, all we really need is something that can tell us how many :optional
arguments were filled in. In the above example that something could
return 0, 1, or 2 depending on which of gamma or delta were supplied
by the caller. In fact, this might be greatly preferable, since if
I later decide I need another non-optional parameter

.sub "foo"
.param int beta
.param int omega
.param string gamma :optional
.param string delta :optional
.param pmc epislon :slurpy

I don't have to go through my code and fix all of the optional
argument counts.

Pm

Patrick R. Michaud

unread,
Jul 7, 2005, 11:09:27 AM7/7/05
to Chip Salzenberg, Will Coleda, Leopold Toetsch, Perl 6 Internals
On Thu, Jul 07, 2005 at 11:05:00AM -0400, Chip Salzenberg wrote:
> On Thu, Jul 07, 2005 at 10:57:40AM -0400, Will Coleda wrote:
> > To manage varargs-style subroutines?
>
> But that's what :slurpy is for.

But :slurpy always pulls things into a PMC (and creates PMCs
along the way).

We need get_argc in order to know how many things were passed
into params marked :optional .

Pm

Chip Salzenberg

unread,
Jul 7, 2005, 11:22:27 AM7/7/05
to Patrick R. Michaud, Will Coleda, Leopold Toetsch, Perl 6 Internals

Hm. Well, as long as everybody knows it defeats lazy evaluation, I
guess that works.
--
Chip Salzenberg <ch...@pobox.com>

Patrick R. Michaud

unread,
Jul 7, 2005, 11:47:10 AM7/7/05
to Chip Salzenberg, Will Coleda, Leopold Toetsch, Perl 6 Internals
On Thu, Jul 07, 2005 at 10:43:45AM -0500, Patrick R. Michaud wrote:
> In fact, this might be greatly preferable, since if
> I later decide I need another non-optional parameter
>
> .sub "foo"
> .param int beta
> .param int omega
> .param string gamma :optional
> .param string delta :optional
> .param pmc epislon :slurpy
>
> I don't have to go through my code and fix all of the optional
> argument counts.

I would, of course, likely have to go through and update all of
my calls to "foo" to include the extra mandatory parameter -- but
that's a slightly different issue. Such is the price of changing
subroutine signatures. :-)

Pm

Chip Salzenberg

unread,
Jul 7, 2005, 11:05:00 AM7/7/05
to Will Coleda, Leopold Toetsch, Perl 6 Internals
On Thu, Jul 07, 2005 at 10:57:40AM -0400, Will Coleda wrote:
> To manage varargs-style subroutines?

But that's what :slurpy is for.

--
Chip Salzenberg <ch...@pobox.com>

Patrick R. Michaud

unread,
Jul 7, 2005, 12:09:24 PM7/7/05
to Chip Salzenberg, Will Coleda, Leopold Toetsch, Perl 6 Internals
On Thu, Jul 07, 2005 at 12:02:40PM -0400, Chip Salzenberg wrote:
> On Thu, Jul 07, 2005 at 10:43:45AM -0500, Patrick R. Michaud wrote:
> > With something like

> >
> > .sub "foo"
> > .param int beta
> > .param string gamma :optional
> > .param string delta :optional
> > .param pmc epislon :slurpy
> >
> > So, all we really need is something that can tell us how many :optional
> > arguments were filled in.
>
> ITYM "parameters". I know it's confusing, but at least for now, the
> terminology is that arguments are passed and parameters are bound to
> (or assigned) the argument values.

Yes, you're correct, no, it's not confusing -- I normally try to keep
my use of the terms "argument" and "parameter" straight but just
slipped here. :-|

> If it would otherwise be necessary to keep state, it might be best
> included right in the get_params/get_results opcodes. Say a new bit
> ":opt_count", which means that the given register should be assigned
> the count?
> ...
> Would that work for everyone?

Yes, yes, yes! Especially since one of the first thing I'm going to
have to do is assign the optional argument count into a register, it'd
be fantastic if PIR could just do it for me and not have to worry
about an opcode for it.

Pm

Patrick R. Michaud

unread,
Jul 7, 2005, 12:13:16 PM7/7/05
to Chip Salzenberg, Will Coleda, Leopold Toetsch, Perl 6 Internals
On Thu, Jul 07, 2005 at 12:11:53PM -0400, Chip Salzenberg wrote:
> Thus, this is probably better:

>
> .sub "foo"
> .param int beta
> .param string gamma :optional(have_gamma)
> .param string delta :optional(have_delta)
> .param pmc epsilon :slurpy

As you might guess, this approach totally works for me. :-)
Then we likely don't need any form of argument/parameter count.

Pm

Leopold Toetsch

unread,
Jul 7, 2005, 12:36:51 PM7/7/05
to Chip Salzenberg, Perl 6 Internals, Patrick R.Michaud

On Jul 7, 2005, at 18:02, Chip Salzenberg wrote:
> Say a new bit
> ":opt_count", which means that the given register should be assigned
> the count?
>
> .sub "foo"
> .param int beta
> .param string gamma :optional
> .param string delta :optional
> .param int optc :opt_count
> .param pmc epsilon :slurpy
>
> In this example, the range of values for optc would be 0..2. That's
> because epsilon is not optional, and will thus always be set to an
> aggregate PMC, just maybe an empty one.
>
> It could likely be illegal for :optional to appear after the
> :opt_count, not that there's any need for such a thing anyway.

My gut feeling is that it isn't a problem, when an :optional appers
after :opt_count. I think, I just remember the arg number/type of
:opt_count and fill it at the end of the argument passing.

>
> Would that work for everyone?


Works fine for me and sounds very reasonable. It also just saves
executing the get_argc opcode, the result is already there.

If no one beats me (and if there are no major objections) I'll just
implement it tomorrow.

leo

Chip Salzenberg

unread,
Jul 7, 2005, 12:11:53 PM7/7/05
to Patrick R. Michaud, Will Coleda, Leopold Toetsch, Perl 6 Internals
And I just realized my proposal fails to address something important.
But I'm not entirely sure it's Parrot's job to do the important thing
in question. Still, the possibility exists. Thus:

On Thu, Jul 07, 2005 at 12:02:40PM -0400, Chip Salzenberg wrote:

> .sub "foo"
> .param int beta
> .param string gamma :optional
> .param string delta :optional

> .param int optc :opt_count
> .param pmc epsilon :slurpy

This fails in the face of the named parameter calling sequence, which
can end up passing delta with a value but omitting gamma. Of course
the get_params opcode doesn't yet have a way to specify parameter
names, but it likely will have to soon.

Thus, this is probably better:

.sub "foo"
.param int beta


.param string gamma :optional(have_gamma)
.param string delta :optional(have_delta)
.param pmc epsilon :slurpy

This implies declaration of integer (pseudo-)registers named
"have_gamma" and "have_delta". If gamma was passed, then have_gamma
will be true, else false.

This would be syntactic sugar for something like:

.sub "foo"
.param int beta
.param string gamma :optional

.param int have_gamma :got_last_optional
.param string delta :optional
.param int have_delta :got_last_optional
.param pmc epsilon :slurpy

This allows for the possibility of named parameter passing, and it
also is even more robust against signature changes than :opt_count
would have been.
--
Chip Salzenberg <ch...@pobox.com>

Leopold Toetsch

unread,
Jul 7, 2005, 12:07:49 PM7/7/05
to Patrick R. Michaud, Chip Salzenberg, Perl 6 Internals
Patrick R. Michaud wrote:

> ... get_argc (which perhaps should be called something
> else)

Better names are welcome.

> So, all we really need is something that can tell us how many :optional
> arguments were filled in.

Sounds reasonable.

op optional_count(out INT)

Another question: do we want two distinct opocdes:

- get_args: (or optional_count) of this subroutine (valid throughout the
whole sub)
- get_retc: current result count of the *recent* function return

or should we have just one opcode like now, that holds only the state of
the recent call/return?

> Pm

leo

Chip Salzenberg

unread,
Jul 7, 2005, 12:02:40 PM7/7/05
to Patrick R. Michaud, Will Coleda, Leopold Toetsch, Perl 6 Internals
On Thu, Jul 07, 2005 at 10:43:45AM -0500, Patrick R. Michaud wrote:
> With something like

>
> .sub "foo"
> .param int beta
> .param string gamma :optional
> .param string delta :optional
> .param pmc epislon :slurpy
>
> So, all we really need is something that can tell us how many :optional
> arguments were filled in.

ITYM "parameters". I know it's confusing, but at least for now, the


terminology is that arguments are passed and parameters are bound to
(or assigned) the argument values.

If it would otherwise be necessary to keep state, it might be best
included right in the get_params/get_results opcodes. Say a new bit


":opt_count", which means that the given register should be assigned
the count?

.sub "foo"


.param int beta
.param string gamma :optional
.param string delta :optional

.param int optc :opt_count
.param pmc epsilon :slurpy

In this example, the range of values for optc would be 0..2. That's


because epsilon is not optional, and will thus always be set to an
aggregate PMC, just maybe an empty one.

It could likely be illegal for :optional to appear after the
:opt_count, not that there's any need for such a thing anyway.

Would that work for everyone?

(I suppose there might be a use case for :optional :slurpy, but I
haven't seen one. If array PMC creation were expensive enough to make
creating the slurpy array prohibitive, that'd be a bug. IMO.)
--
Chip Salzenberg <ch...@pobox.com>

Leopold Toetsch

unread,
Jul 8, 2005, 9:58:50 AM7/8/05
to Chip Salzenberg, Patrick R. Michaud, Perl 6 Internals
Chip Salzenberg wrote:
> And I just realized my proposal fails to address something important.
> But I'm not entirely sure it's Parrot's job to do the important thing
> in question. Still, the possibility exists. Thus:
>
> On Thu, Jul 07, 2005 at 12:02:40PM -0400, Chip Salzenberg wrote:
>
>> .sub "foo"
>> .param int beta
>> .param string gamma :optional
>> .param string delta :optional
>> .param int optc :opt_count
>> .param pmc epsilon :slurpy
>
>
> This fails in the face of the named parameter calling sequence, which
> can end up passing delta with a value but omitting gamma. Of course
> the get_params opcode doesn't yet have a way to specify parameter
> names, but it likely will have to soon.
>
> Thus, this is probably better:
>
> .sub "foo"
> .param int beta
> .param string gamma :optional(have_gamma)
> .param string delta :optional(have_delta)

This needs more parsing rules in imcc.y so it's not (yet) implemented.

But I've now implemented :opt_count, with an extension to the original
proposal: the opt_count is reset after :opt_count is seen, so that
multiple :opt_count flags work.

.param pmc p1 :optional
.param pmc p2 :optional
.param int i12 :opt_count # = 2
.param pmc p3 :optional
.param int i3 :opt_count # = 1

(if these argumens are passed of course)

leo

Patrick R. Michaud

unread,
Jul 8, 2005, 10:12:38 AM7/8/05
to Leopold Toetsch, Chip Salzenberg, Perl 6 Internals
On Fri, Jul 08, 2005 at 03:58:50PM +0200, Leopold Toetsch wrote:
> Chip Salzenberg wrote:
> >Thus, this is probably better:
> >
> > .sub "foo"
> > .param int beta
> > .param string gamma :optional(have_gamma)
> > .param string delta :optional(have_delta)
>
> This needs more parsing rules in imcc.y so it's not (yet) implemented.
>
> But I've now implemented :opt_count, with an extension to the original
> proposal: the opt_count is reset after :opt_count is seen, so that
> multiple :opt_count flags work.

I'll note that with Leo's resetting version of :opt_count, we might
not really need the parameterized form of :optional, since one
can simply do:

.sub "foo"
.param int beta
.param string gamma :optional

.param int have_gamma :opt_count
.param string delta :optional
.param int have_delta :opt_count

and each of have_gamma and have_delta is 0 or 1, depending on the parameter
before it. And if a subroutine only needs the total count of
optional parameters, there's an easy way to do that.

OTOH, the :optional(reg) syntax has its uses as well.

At any rate, having both available seems to give a nice level of
flexibility to subroutine authors (I haven't thought too deeply yet
about potential conflicts/confusions).

Pm

Chip Salzenberg

unread,
Jul 8, 2005, 11:13:27 AM7/8/05
to Leopold Toetsch, Patrick R. Michaud, Perl 6 Internals
On Fri, Jul 08, 2005 at 03:58:50PM +0200, Leopold Toetsch wrote:
> This needs more parsing rules in imcc.y so it's not (yet) implemented.

Grammar changes shouldn't be such an issue. It's just yacc.

> But I've now implemented :opt_count ...


> .param pmc p1 :optional
> .param pmc p2 :optional
> .param int i12 :opt_count # = 2
> .param pmc p3 :optional
> .param int i3 :opt_count # = 1

Well, I'm about >< this close to asking you to _un_implement it as
inadequate in the face of named parameters. It implies a semantic of
parameter binding being driven by a single loop through the list of
parameters, which, given the possibility of supporting named parameter
passing, is not wise...

Tt makes sense to scan the pairs containing named arguments by
iterating through the list of pairs (if any), not by iterating through
the parameters and doing a sequential scan for an appropriately named
pair for each one. Therefore, it's possible that there will
eventually no longer be a single loop through the parameters. The
concept of strict temporal ordering might thus be lost, and the idea
of "optional parameter up to this point" might also be lost.

So apparently I'm going to have to figure out exactly how we support
named parameters or this won't get settled. Fine....
--
Chip Salzenberg <ch...@pobox.com>

Larry Wall

unread,
Jul 8, 2005, 2:18:01 PM7/8/05
to Perl 6 Internals
On Fri, Jul 08, 2005 at 11:13:27AM -0400, Chip Salzenberg wrote:
: Tt makes sense to scan the pairs containing named arguments by

: iterating through the list of pairs (if any), not by iterating through
: the parameters and doing a sequential scan for an appropriately named
: pair for each one.

Actually, there are use cases for both approaches. Consider the case
where your named parameters are actually a hash of many defaults, only
a few of which you might pick out for this call. That is essentially
how we've defined the %_ hash to work for Perl 6. It is not an error
to have extra unbound named parameters on a method call, because
we're passing in the inital values for all the various attributes
set by the entire class hierarchy, and each class only picks out the
values it's interested in. In such a case it makes sense the main
loop to iterate over the positionals and do lookups on any missing
ones in the named zone.

Even in the absence of a hash representation, the brute force approach
will often beat the finessed approach for a small number of arguments,
especially if people *usually* fill positional parameters with
positional arguments, in which case you get to the end of the positional
arguments without making any passes on the named zone.

I'm not saying that Perl 6 requires you to do it this way, only that
we've intentionally defined the semantics to make the position-major
approach feasible. As far as I can see, the only way in which this
makes the named-major approach more difficult is that we specify
"first wins" rather than "last wins" if there are collisions in the
named list so that you don't always have to scan the whole list if you
take a position-major approach, and so that you can know that you
can pass a specific named argument to override the default in the hash
as long as you pass it first. So a named-major approach would need to
be a bit careful not to turn into "last wins" semantics.

I suppose a hybrid approach is possible, where you do position-major
till you find a "hole", then named-major till you run into a hash in
the named zone, then finish out doing position-major with lookups
on the rest of the name list, on the assumption that the hash is
probably the last named colletion, or at least all the hashes will
tend to clump at the end of the named zone.

: Therefore, it's possible that there will


: eventually no longer be a single loop through the parameters. The
: concept of strict temporal ordering might thus be lost,

Why would strict temporal order be needed for mere binding?

: and the idea of "optional parameter up to this point" might also be lost.

I don't grok that part.

: So apparently I'm going to have to figure out exactly how we support


: named parameters or this won't get settled. Fine....

Mmm, have the appropriate amount of fun... :-)

Larry

Chip Salzenberg

unread,
Jul 8, 2005, 3:17:42 PM7/8/05
to Perl 6 Internals
Larry on p6i? I didn't expect some kind of Perlish Exposition!

On Fri, Jul 08, 2005 at 11:18:01AM -0700, Larry Wall wrote:
> Even in the absence of a hash representation, the brute force approach
> will often beat the finessed approach for a small number of arguments,

Well-taken. (Not that the rest isn't, but the danger of misoptimization
is always with us.) More commentary may be forthcoming soon.

Incidentally, under the "appropriate amount of fun" topic: An
interesting Parrot/Perl6 intersection problem with named parameters
is the representation of <==. Given

foo('a' => 1) <== ('b' => 2, ...)

It's necessary to _somehow_ pass the first pair distinctly from the
second pair without knowing the _name_ of the user-declared slurpy
parameter of &foo. I suppose the Perl 6 compiler will have to settle
on a pseudo-parameter-name that will be used to represent a <== style
list. Assuming that name is '_', the above call could be compiled to:

foo('a' => 1, '_' => ('b' => 2, ...))

or something similar. It would then be the responsibility of a Perl 6
function preamble to bind the contents of the '_' argument, if any, to
the user-declared slurpy parameter, if any. Non-Perl6 functions would
perhaps see the '_' parameter and have to deal with it.

> : Therefore, it's possible that there will
> : eventually no longer be a single loop through the parameters. The
> : concept of strict temporal ordering might thus be lost,
>
> Why would strict temporal order be needed for mere binding?
>
> : and the idea of "optional parameter up to this point" might also be lost.
>
> I don't grok that part.

It's a Parrot calling convention API thing. Leo proposed (and
implemented) a highly time-bound feature for subroutines to learn
whether optional parameters were passed in or not. It more or less
lets the user request: "Store >here< the number of optional parameters
that _so_far_ have been filled in _since_ the last time I asked".
That API requires either strict left-to-right binding or an amazing
simulation thereof.

I've since requested an API that doesn't impose even a simulation of
left-to-right processing among parameters: "Store >here< whether the
caller passed a value for >that< specific optional parameter."

> : So apparently I'm going to have to figure out exactly how we support
> : named parameters or this won't get settled. Fine....
>
> Mmm, have the appropriate amount of fun... :-)

/me giggles madly
--
Chip Salzenberg <ch...@pobox.com>

Larry Wall

unread,
Jul 8, 2005, 4:10:28 PM7/8/05
to Perl 6 Internals
On Fri, Jul 08, 2005 at 03:17:42PM -0400, Chip Salzenberg wrote:
: Larry on p6i? I didn't expect some kind of Perlish Exposition!

Hey, I'm the chief Lurky Turkey around here...

: Incidentally, under the "appropriate amount of fun" topic: An


: interesting Parrot/Perl6 intersection problem with named parameters
: is the representation of <==. Given
:
: foo('a' => 1) <== ('b' => 2, ...)
:
: It's necessary to _somehow_ pass the first pair distinctly from the
: second pair without knowing the _name_ of the user-declared slurpy
: parameter of &foo. I suppose the Perl 6 compiler will have to settle
: on a pseudo-parameter-name that will be used to represent a <== style
: list. Assuming that name is '_', the above call could be compiled to:
:
: foo('a' => 1, '_' => ('b' => 2, ...))
:
: or something similar. It would then be the responsibility of a Perl 6
: function preamble to bind the contents of the '_' argument, if any, to
: the user-declared slurpy parameter, if any. Non-Perl6 functions would
: perhaps see the '_' parameter and have to deal with it.

Yes, that should work, though in fact the Perl 6 binder has to do
more work even than that, since once it sees the _ parameter, it has
to decide whether it's binding multiple pipes or semicolons, and if
so, whether the target slurpy type wants to treat the pipe/semicolon
boundaries multidimensionally or as a flat list. To a non-Perl 6
function it would appear to be a list of lazy lists, but Perl 6 is
trying to keep semicolons from becoming accidental sublist builders
*except* in contexts that are expecting multiple sublists (such
as subscripts that are lists of slices, or zip-like operators that
are processing multiple lists in parallel). Accidental semicolons
tend to happen at the ends of lists, and it's really antisocial to
retroactively wrap a [...] around the entire list merely because of
a trailing semicolon.

Plus it settles the whole issue of what to do with multiple pipes into
the same function. But I don't think Parrot has to worry about that,
as long as Perl 6 can hook the binding of the slurpy sufficiently well
to think about it.

Larry

Leopold Toetsch

unread,
Jul 8, 2005, 5:52:33 PM7/8/05
to Larry Wall, Perl 6 Internals
Larry Wall wrote:
> On Fri, Jul 08, 2005 at 03:17:42PM -0400, Chip Salzenberg wrote:

> : foo('a' => 1) <== ('b' => 2, ...)

[ ... ]

> Plus it settles the whole issue of what to do with multiple pipes into
> the same function. But I don't think Parrot has to worry about that,

Thanks. Again. I think, we should keep *parrot* calling conventions at a
reasonable maintanable (and implementable) level, which is AFAIK around
"usual" function calls, i.e. around the level of Python calling conventions.

> Larry

my 2 ¢

leo

Reply all
Reply to author
Forward
0 new messages