Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

wishlist for NQP

1 view
Skip to first unread message

Klaas-Jan Stol

unread,
Mar 26, 2008, 9:25:06 AM3/26/08
to Perl6 Internals
hi,

having used NQP a bit, I feel like I'm missing a few things. I'm not
entirely sure what the fate of NQP is; will it always be a bootstrap
stage for Perl 6,or is it a tool for now and will it be discarded
later on.
Anyway, if NQP is to stay, the following features would come in handy,
IMHO. I understand that NQP is designed to be small, but these
features won't clutter the implementation that much, and are pretty
easy to implement, I think.

* other relational operators, such as <, <=, > and >=. I keep writing
these, but NPQ only has == and !=.
* postincrement/decrement ops, or at least +=. Often you need syntax
like $index := $index + 1; Writing += 1 is so much nicer.
* the ternary operator ?: This allows for shorter/easier notation when
both the Then and Else part of an ifstatement are 1 line. Typical for
this in the PCT is writing:

if $?BLOCK.symbol($name) {
$scope := 'lexical';
}
else {
$scope := 'package';
}

which could be nicely written as

$scope := $?BLOCK.symbol($name) ? 'lexical' : 'package';

* list ops ( I think this is meant by list ops? )
All languages that have some kind of scope mechanism now have to
define a class "List", which has an unshift and shift method, which
are just wrappers for the equally named parrot ops. Being able to
write

unshift @?BLOCK, $?BLOCK;

would be useful, as it prevents the need for creating the List class
over and over again.
I feel that these ops are so basic, it would be well worth it to have
them around.


* MAIN support: this feature is a nice-to-have, but not that important.
I don't think it's there already: when writing an NQP script, I'd like
to have access to the command line options. To be precise, I'd like to
write the compiler driver in NQP instead of in PIR. So, creating a new
HLLCompiler, setting the grammar stuff and invoking the command_line
method on it with the commandline args. How do I get access to these
args from NQP?

Comments most welcome.

kjs

Geoffrey Broadwell

unread,
Mar 26, 2008, 12:12:18 PM3/26/08
to Klaas-Jan Stol, Perl6 Internals
>From the point of view of someone working through the PCT tutorial
(quite rockin', BTW!):

On Wed, 2008-03-26 at 14:25 +0100, Klaas-Jan Stol wrote:
> having used NQP a bit, I feel like I'm missing a few things. I'm not
> entirely sure what the fate of NQP is; will it always be a bootstrap
> stage for Perl 6,or is it a tool for now and will it be discarded
> later on.

If NQP isn't available in the long term, then something at least as cool
should be. If that's real Perl 6, so much the better. But I certainly
wouldn't be doing the PCT tutorial -- and thus in the future working on
adding or improving languages in the Parrot compiler collection -- if I
didn't feel like the language I was working in was:

A) Fun to work with,
B) Giving me skills useful for other tasks, and
C) Not tendonitis inducing.

(Note that PIR qualifies under A and B, but not C -- which is why I am
limiting my PIR work to places where it's actually necessary or clearly
superior.)

> Anyway, if NQP is to stay, the following features would come in handy,
> IMHO. I understand that NQP is designed to be small, but these
> features won't clutter the implementation that much, and are pretty
> easy to implement, I think.

Agreed.

> * other relational operators, such as <, <=, > and >=. I keep writing
> these, but NPQ only has == and !=.

Definitely agree WRT numeric ops. What about string ops?

> * postincrement/decrement ops, or at least +=. Often you need syntax
> like $index := $index + 1; Writing += 1 is so much nicer.

God yes, please. I certainly like having -- and ++, but I'm willing to
do without. Not having op= is harsh.

> * the ternary operator ?: This allows for shorter/easier notation when
> both the Then and Else part of an ifstatement are 1 line. Typical for
> this in the PCT is writing:

> [six lines]


> which could be nicely written as
>
> $scope := $?BLOCK.symbol($name) ? 'lexical' : 'package';

This one seems easy and very valuable. I hate wasting vertical real
estate in my editor. I'm willing to pay a certain amount of coding tax
for NQP < P6, but six lines instead of one is a bit excessive. Just
allowing an if statement to be used as an expression in some (presumably
Perl 6 compatible) way would be OK, if ugly.

> * list ops ( I think this is meant by list ops? )
> All languages that have some kind of scope mechanism now have to
> define a class "List", which has an unshift and shift method, which
> are just wrappers for the equally named parrot ops. Being able to
> write
>
> unshift @?BLOCK, $?BLOCK;
>
> would be useful, as it prevents the need for creating the List class
> over and over again.
> I feel that these ops are so basic, it would be well worth it to have
> them around.

I disagree with the syntax, but agree with the sentiment. I'm fine with
requiring everything in NQP to use method or sub call syntax (as opposed
to adding listop syntax) -- but having to write the PIR wrappers for
array shift and unshift seemed really silly and wartish. The most basic
array methods (shift, unshift, push, pop, elems) should all just be
there, because there's no reason for every language implementor to
rewrite them.

> * MAIN support: this feature is a nice-to-have, but not that important.
> I don't think it's there already: when writing an NQP script, I'd like
> to have access to the command line options. To be precise, I'd like to
> write the compiler driver in NQP instead of in PIR. So, creating a new
> HLLCompiler, setting the grammar stuff and invoking the command_line
> method on it with the commandline args. How do I get access to these
> args from NQP?

MAIN support would definitely be very cool -- but that seems like a big
thing for a small language, so I'd settle for @ARGS.


-'f


Patrick R. Michaud

unread,
Mar 26, 2008, 1:30:49 PM3/26/08
to Klaas-Jan Stol, Perl6 Internals
On Wed, Mar 26, 2008 at 02:25:06PM +0100, Klaas-Jan Stol wrote:
> having used NQP a bit, I feel like I'm missing a few things. I'm not
> entirely sure what the fate of NQP is; will it always be a bootstrap
> stage for Perl 6,or is it a tool for now and will it be discarded
> later on.

Neither! It's important to be wary of viewing NQP solely in the
context of Rakudo and Perl 6 -- NQP is designed to be a tool that
many Parrot HLLs can use to build tools, not just Rakudo and/or Perl 6.
So, it's entirely possible that Rakudo will stop using NQP as part
of its build process at some point, but NQP will still be around
for other translators to use (as many of them are). As noted
in README.pod:

The key feature of NQP is that it's designed to be a very
small compiler (as compared with, say, perl6) and is focused
on being a high-level way to create transformers for Parrot
(especially hll compilers). In addition, unlike perl6, NQP
attempts to restrict itself to generating code that can run
in Parrot without the existence of any NQP-specific runtime
libraries.

> [...] I understand that NQP is designed to be small, but these


> features won't clutter the implementation that much, and are pretty
> easy to implement, I think.
>
> * other relational operators, such as <, <=, > and >=. I keep writing
> these, but NPQ only has == and !=.
> * postincrement/decrement ops, or at least +=. Often you need syntax
> like $index := $index + 1; Writing += 1 is so much nicer.

One of the overarching principles behind NQP is to add features
and operators only as they are actually needed, as opposed to
"would be nice to have". And since I haven't really needed
the relational ops, I haven't put them into NQP. But if you
really need them we can certainly add them.

> * the ternary operator ?: This allows for shorter/easier notation when
> both the Then and Else part of an ifstatement are 1 line.

Adding the ternary operator is no problem, except remember that it's
??!! and not ?: . The tricky part for the ternary op is getting it
into the grammar. We can either use PGE's built-in "ternary:"
category, or we can try to follow STD.pm's approach.

> * list ops ( I think this is meant by list ops? )
> All languages that have some kind of scope mechanism now have to
> define a class "List", which has an unshift and shift method, which
> are just wrappers for the equally named parrot ops.

I don't quite understand what is meant by "have to define a class
'List'". Can you give an example?

> Being able to write
> unshift @?BLOCK, $?BLOCK;
> would be useful, as it prevents the need for creating the List class
> over and over again.
> I feel that these ops are so basic, it would be well worth it to have
> them around.

Thus far NQP has avoided most forms of listop parsing (i.e., functions
w/o parens), so the above really ought to be written as

unshift(@?BLOCK, $?BLOCK);

Now that listop parsing is available in Rakudo, we could see about
backporting it into NQP and using that. But even if we allow
the listop form, having something like "unshift" work means that we
need a mechanism to map specific function names into equivalent
inline PIR instructions. On the whole this would probably be
a very good thing to have... still, going back to the earlier
principle -- I haven't run across a case where it's really needed,
so it hasn't been added yet.

Perhaps I'll understand better when I understand the "all languages ...
have to define a class 'List'" comment above.

> * MAIN support: this feature is a nice-to-have, but not that important.
> I don't think it's there already: when writing an NQP script, I'd like
> to have access to the command line options. To be precise, I'd like to
> write the compiler driver in NQP instead of in PIR.

This is explicitly a goal for NQP, and you're correct that we
haven't gotten there yet. The likely answer is that any subroutine
named 'MAIN' will automatically get Parrot's ':main' flag added
to the sub. The command line arguments are then just
a parameter to that subroutine:

sub MAIN ( @args ) {
...
}

Hope this helps,

Pm

Patrick R. Michaud

unread,
Mar 26, 2008, 1:38:38 PM3/26/08
to Geoffrey Broadwell, Klaas-Jan Stol, Perl6 Internals
On Wed, Mar 26, 2008 at 09:12:18AM -0700, Geoffrey Broadwell wrote:
> > Being able to write
> >
> > unshift @?BLOCK, $?BLOCK;
> >
> > would be useful, as it prevents the need for creating the List class
> > over and over again.
> > I feel that these ops are so basic, it would be well worth it to have
> > them around.
>
> I disagree with the syntax, but agree with the sentiment. I'm fine with
> requiring everything in NQP to use method or sub call syntax (as opposed
> to adding listop syntax) -- but having to write the PIR wrappers for
> array shift and unshift seemed really silly and wartish. The most basic
> array methods (shift, unshift, push, pop, elems) should all just be
> there, because there's no reason for every language implementor to
> rewrite them.

This might in fact be an argument that Parrot's base PMC types should
provide these methods by default.

Pm

Klaas-Jan Stol

unread,
Mar 27, 2008, 5:33:54 PM3/27/08
to Patrick R. Michaud, Perl6 Internals
On Wed, Mar 26, 2008 at 6:30 PM, Patrick R. Michaud <pmic...@pobox.com> wrote:
> On Wed, Mar 26, 2008 at 02:25:06PM +0100, Klaas-Jan Stol wrote:
> > having used NQP a bit, I feel like I'm missing a few things. I'm not
> > entirely sure what the fate of NQP is; will it always be a bootstrap
> > stage for Perl 6,or is it a tool for now and will it be discarded
> > later on.
>
> Neither! It's important to be wary of viewing NQP solely in the
> context of Rakudo and Perl 6 -- NQP is designed to be a tool that
> many Parrot HLLs can use to build tools, not just Rakudo and/or Perl 6.
> So, it's entirely possible that Rakudo will stop using NQP as part
> of its build process at some point, but NQP will still be around
> for other translators to use (as many of them are). As noted
> in README.pod:
>
> The key feature of NQP is that it's designed to be a very
> small compiler (as compared with, say, perl6) and is focused
> on being a high-level way to create transformers for Parrot
> (especially hll compilers). In addition, unlike perl6, NQP
> attempts to restrict itself to generating code that can run
> in Parrot without the existence of any NQP-specific runtime
> libraries.
>

Ok, that's clear; I didn't mean to mention Rakudo specifically.


> > [...] I understand that NQP is designed to be small, but these
>
> > features won't clutter the implementation that much, and are pretty
> > easy to implement, I think.
> >
> > * other relational operators, such as <, <=, > and >=. I keep writing
> > these, but NPQ only has == and !=.
> > * postincrement/decrement ops, or at least +=. Often you need syntax
> > like $index := $index + 1; Writing += 1 is so much nicer.
>
> One of the overarching principles behind NQP is to add features
> and operators only as they are actually needed, as opposed to
> "would be nice to have". And since I haven't really needed
> the relational ops, I haven't put them into NQP. But if you
> really need them we can certainly add them.
>

Well, I don't really need them that much, but I think they're
interesting for 2 reasons: they're so 'basic', in the sense that many
a programmer will expect them to be present, and 2) they're
"self-documenting": writing "while $i != $max" doesn't tell me whether
$i is going up or down; of course I can check out the code in the
while block, but still... Also, it feels somewhat "safer": writing
while $i < $max will make sure $i is never greater than $max; $i !=
$max doesn't express this assertion.

>
> > * the ternary operator ?: This allows for shorter/easier notation when
> > both the Then and Else part of an ifstatement are 1 line.
>
> Adding the ternary operator is no problem, except remember that it's
> ??!! and not ?: . The tricky part for the ternary op is getting it
> into the grammar. We can either use PGE's built-in "ternary:"
> category, or we can try to follow STD.pm's approach.

Ok, i just guessed the syntax as it's written ? : in the NQP pseudo
code (Actions.pir of NQP implementation). But that's a spelling issue.

More importantly: is it worth adding, and how to implement it. Both
adding it and leaving it out has its advantages, so I will leave it to
the Powers that Be ;-) I just proposed this, and based on the first
comment in this thread, at least one other person agreed.

>
>
> > * list ops ( I think this is meant by list ops? )
> > All languages that have some kind of scope mechanism now have to
> > define a class "List", which has an unshift and shift method, which
> > are just wrappers for the equally named parrot ops.
>
> I don't quite understand what is meant by "have to define a class
> 'List'". Can you give an example?

Yes, sorry, I didn't explain the context. In order to write
@?BLOCK.shift() (and unshift() ) (for implementation of the scope
stack in pretty much all languages), @?BLOCK must be an object that
has these methods. As ResizablePMCArray doesn't have such methods, the
"trick" here is to subclass ResizablePMCArray (calling it "List") and
wrapping the shift and unshift instructions in the equally-named
methods.

>
>
> > Being able to write
> > unshift @?BLOCK, $?BLOCK;
> > would be useful, as it prevents the need for creating the List class
> > over and over again.
> > I feel that these ops are so basic, it would be well worth it to have
> > them around.
>
> Thus far NQP has avoided most forms of listop parsing (i.e., functions
> w/o parens), so the above really ought to be written as
>
> unshift(@?BLOCK, $?BLOCK);

This would work for me too. My point is, all languages I have worked
on that have scope, I had to write (well, copy/paste, but still) this
List class I mentioned above so that the @?BLOCK object (which is a
List object) can shift and unshift PAST::Blocks. I'd rather leave out
this "wrapping class" for ResizablePMCArray. What exact syntax is not
that important, but using the method invocation syntax requires
@?BLOCK to have methods.

>
> Now that listop parsing is available in Rakudo, we could see about
> backporting it into NQP and using that. But even if we allow
> the listop form, having something like "unshift" work means that we
> need a mechanism to map specific function names into equivalent
> inline PIR instructions.

So, as a recap of what I mean: the "shift" and "unshift" methods of
@?BLOCK are just wrappers for the shift and unshift instructions. I'd
like to remove the need of writing a class ("List") that provides
these wrappers, and use "built-in" unshift and shift functions.

On the whole this would probably be
> a very good thing to have... still, going back to the earlier
> principle -- I haven't run across a case where it's really needed,
> so it hasn't been added yet.
>
> Perhaps I'll understand better when I understand the "all languages ...
> have to define a class 'List'" comment above.
>
>
> > * MAIN support: this feature is a nice-to-have, but not that important.
> > I don't think it's there already: when writing an NQP script, I'd like
> > to have access to the command line options. To be precise, I'd like to
> > write the compiler driver in NQP instead of in PIR.
>
> This is explicitly a goal for NQP, and you're correct that we
> haven't gotten there yet. The likely answer is that any subroutine
> named 'MAIN' will automatically get Parrot's ':main' flag added
> to the sub. The command line arguments are then just
> a parameter to that subroutine:
>
> sub MAIN ( @args ) {
> ...
> }

This would be very useful. Ideally, IMHO, we can write the "main" file
(where the HLLCompiler is created and the grammar stuff and
commandline prompt and such is specified) for all language compilers
in NQP as well, instead of PIR. (I'm not a PIR hater, but NQP is just
nicer)

>
> Hope this helps,
>
> Pm

hope my intention gets more clear.
kjs
>

Patrick R. Michaud

unread,
Mar 27, 2008, 9:20:21 PM3/27/08
to Klaas-Jan Stol, Perl6 Internals
On Thu, Mar 27, 2008 at 10:33:54PM +0100, Klaas-Jan Stol wrote:
> On Wed, Mar 26, 2008 at 6:30 PM, Patrick R. Michaud <pmic...@pobox.com> wrote:
> > On Wed, Mar 26, 2008 at 02:25:06PM +0100, Klaas-Jan Stol wrote:
> > > * list ops ( I think this is meant by list ops? )
> > > All languages that have some kind of scope mechanism now have to
> > > define a class "List", which has an unshift and shift method, which
> > > are just wrappers for the equally named parrot ops.
> >
> > I don't quite understand what is meant by "have to define a class
> > 'List'". Can you give an example?
>
> Yes, sorry, I didn't explain the context. In order to write
> @?BLOCK.shift() (and unshift() ) (for implementation of the scope
> stack in pretty much all languages), @?BLOCK must be an object that
> has these methods. As ResizablePMCArray doesn't have such methods, the
> "trick" here is to subclass ResizablePMCArray (calling it "List") and
> wrapping the shift and unshift instructions in the equally-named
> methods.

Actually, it can be done without subclassing via the following

.namespace [ 'ResizablePMCArray' ]

.sub 'unshift' :method
.param pmc list
.param pmc value
unshift list, value
.end

.sub 'shift' :method
.param pmc list
.param pmc value
shift list, value
.end


I've already commented that perhaps these should be a built-in
part of the ResizablePMCArray in Parrot. However, if that's
not likely to happen, then perhaps either PCT or NQP should
go ahead and provide them, so that they're available whenever
PCT is loaded. But part of me feels that adding methods to
ResizablePMCArray is a little out of NQP's scope.

So, our choices become:

1. Have NQP automatically recognize shift/unshift/push/pop
as "special functions" (keywords) and map them directly to
Parrot's shift/unshift opcodes.

2. Add shift/unshift/push/pop methods to ResizablePMCArray
(or one of its superclasses) in Parrot

3. Have PCT and/or NQP supply the shift/unshift/push/pop methods.

4. Have PCT and/or NQP define their own "List" subclass
that provide shift/unshift/push/pop (this could conflict with
"List" classes in other languages).

5. Advise compiler writers to use some other existing class
for things like @?BLOCK (any of Capture_PIR, Match, or PAST::Node
would work, but could be confusing).

Opinions from the gallery would be greatly welcomed here.

The other items in your message all make good sense and
I think I'm likely to adopt them as soon as we can get
implementations for them. :-)

Thanks!

Pm

Patrick R. Michaud

unread,
Mar 28, 2008, 8:41:25 AM3/28/08
to Klaas-Jan Stol, Perl6 Internals
On Fri, Mar 28, 2008 at 10:51:16AM +0100, Klaas-Jan Stol wrote:
> Attached is a patch implementing:
>
> * ++ and -- postfix operators, implemented as n_sub and n_add (taking
> "1" as the 3rd operand), this is because each instruction must have an
> output register as far as I can tell (so "inc"/"dec" won't work).

It really needs to be inc/dec. And not only that, but the output
value of postfix ++ and -- needs to be the value _before_ the
inc/dec operation. So the PIR code for postfix:++ should be
something like:

%r = clone %0
inc %0

Also, they need to have the "is lvalue(1)" trait so that PAST
knows that the operand is to be treated as an lvalue.

> I wasn't sure how to implement +=; how to spell that? (as there's only
> a ":=" operator right now). I figured that ++ and -- are probably more
> used anyway, and if you want to += 2, then you can always use the
> normal assignment syntax.

Ideally += should be implemented as the two-argument 'add' opcode
in PIR... something like

add %0, %1

But the PAST compiler doesn't yet have a great way for distinguishing
a 2-argument add from a 3-argument add. We can get close with

add_p_p %0, %1

but of course that means that an expression like += 2 would end up
creating a PMC for the 2 constant. And PAST needs a way to know
that the result is in the %0 argument as opposed to a new
unique register (this is planned but not yet implemented).

> * <, <=, > and >= operators

The relational ops in the patch appear to be using iseq and
isne; I think it would make more sense for them to use islt,
isle, isgt, isge.

Also, we should have tests for all of the above.

Thanks!

Pm

Patrick R. Michaud

unread,
Mar 28, 2008, 9:19:50 AM3/28/08
to Klaas-Jan Stol, Perl6 Internals
On Fri, Mar 28, 2008 at 07:41:25AM -0500, Patrick R. Michaud wrote:
> Ideally += should be implemented as the two-argument 'add' opcode
> in PIR... something like
>
> add %0, %1
>
> But the PAST compiler doesn't yet have a great way for distinguishing
> a 2-argument add from a 3-argument add. We can get close with
>
> add_p_p %0, %1
>
> but of course that means that an expression like += 2 would end up
> creating a PMC for the 2 constant. And PAST needs a way to know
> that the result is in the %0 argument as opposed to a new
> unique register (this is planned but not yet implemented).

Thinking about this further, perhaps PAST should default to
providing the 2-argument form of the 'add' opcode. This would make
implementing += and friends easier, and with the current design
of PAST there don't seem to be many places where the 3-argument
form of 'add' is more suitable than the existing 'n_add' opcode.

Then infix:<+=> would be something like

proto infix:<+=> is equiv(infix:<:=>)
is pirop('add')
is lvalue(1)
{ ... }

Pm

Klaas-Jan Stol

unread,
Mar 28, 2008, 9:41:28 AM3/28/08
to Patrick R. Michaud, Perl6 Internals
On Fri, Mar 28, 2008 at 1:41 PM, Patrick R. Michaud <pmic...@pobox.com> wrote:
> On Fri, Mar 28, 2008 at 10:51:16AM +0100, Klaas-Jan Stol wrote:
> > Attached is a patch implementing:
> >
> > * ++ and -- postfix operators, implemented as n_sub and n_add (taking
> > "1" as the 3rd operand), this is because each instruction must have an
> > output register as far as I can tell (so "inc"/"dec" won't work).
>
> It really needs to be inc/dec. And not only that, but the output
> value of postfix ++ and -- needs to be the value _before_ the
> inc/dec operation. So the PIR code for postfix:++ should be
> something like:
>
> %r = clone %0
> inc %0
>

Yes, that's right. I was too quick.

> Also, they need to have the "is lvalue(1)" trait so that PAST
> knows that the operand is to be treated as an lvalue.
>

is this really necessary? It seems to work without. This is also a
problem when writing "1++"; not sure if this is allowed, but the
grammar allows it. PAST::Val doesn't have an lvalue method.

>
> > I wasn't sure how to implement +=; how to spell that? (as there's only
> > a ":=" operator right now). I figured that ++ and -- are probably more
> > used anyway, and if you want to += 2, then you can always use the
> > normal assignment syntax.
>
> Ideally += should be implemented as the two-argument 'add' opcode
> in PIR... something like
>
> add %0, %1
>
> But the PAST compiler doesn't yet have a great way for distinguishing
> a 2-argument add from a 3-argument add. We can get close with
>
> add_p_p %0, %1
>
> but of course that means that an expression like += 2 would end up
> creating a PMC for the 2 constant. And PAST needs a way to know
> that the result is in the %0 argument as opposed to a new
> unique register (this is planned but not yet implemented).

maybe the PCT can include optimizations to remove the creation of PMCs
for constants?

>
> > * <, <=, > and >= operators
>
> The relational ops in the patch appear to be using iseq and
> isne; I think it would make more sense for them to use islt,
> isle, isgt, isge.

is there any reason that == and != have to use cmp_num, and not use
iseq and isne directly on the operands?

reasons I used iseq and isne, is that cmp_num returns -1, 0 or 1, so I
checked for these return values.

I think, if the new rel.ops can use islt and friends, then == and !=
can use iseq and isne directly too without cmp_num, right?

>
> Also, we should have tests for all of the above.
>
> Thanks!
>
> Pm
>


kjs

Patrick R. Michaud

unread,
Mar 28, 2008, 11:18:24 AM3/28/08
to Klaas-Jan Stol, Perl6 Internals
On Fri, Mar 28, 2008 at 02:41:28PM +0100, Klaas-Jan Stol wrote:
> On Fri, Mar 28, 2008 at 1:41 PM, Patrick R. Michaud <pmic...@pobox.com> wrote:
> > It really needs to be inc/dec. And not only that, but the output
> > value of postfix ++ and -- needs to be the value _before_ the
> > inc/dec operation. So the PIR code for postfix:++ should be
> > something like:
> >
> > %r = clone %0
> > inc %0
> >
>
> Yes, that's right. I was too quick.
>
> > Also, they need to have the "is lvalue(1)" trait so that PAST
> > knows that the operand is to be treated as an lvalue.
>
> is this really necessary? It seems to work without. This is also a
> problem when writing "1++"; not sure if this is allowed, but the
> grammar allows it. PAST::Val doesn't have an lvalue method.

I know it's often necessary in the general case, it might not
be necessary for NQP. Consider:

our $a;
$a++;

The "our $a" defines $a as having package scope, but doesn't bind
the variable to a value. The "$a++" will then automatically create
an Undef value for $a (since it's not vivified yet), but unless
something says it's to be an lvalue it won't bind that auto-generated
Undef back to the $a symbol in the namespace.

But now that you've mentioned it, ISTR that Parrot Undef objects
throw an exception on inc/dec anyway, so perhaps we don't need
to worry about this case in NQP.

> > [...] We can get close with


> >
> > add_p_p %0, %1
> >
> > but of course that means that an expression like += 2 would end up
> > creating a PMC for the 2 constant.
>

> maybe the PCT can include optimizations to remove the creation of PMCs
> for constants?

Actually, PCT tends to work the other way -- it uses constants whenever
it can and PMCs when told otherwise (or can't figure it out). In the
above case, 'add_p_p' explicitly indicates that the second operand is
a PMC, so PCT would feel obligated to create one.

In the general case we can't do a global "remove creation of PMCs
for constants" because not all opcodes work with all operand types.
So, before we choose to optimize or not optimize, we have to know
how the operand is going to be used. The PAST compiler handles this
through its %piropsig table, which indicates what kinds of operands
are allowed for each opcode.

> > > * <, <=, > and >= operators
> >
> > The relational ops in the patch appear to be using iseq and
> > isne; I think it would make more sense for them to use islt,
> > isle, isgt, isge.
>
> is there any reason that == and != have to use cmp_num, and not use
> iseq and isne directly on the operands?

Yes, because iseq, isne, islt, isgt, etc. aren't guaranteed to
do numeric comparisons. They do comparisons based on the underlying
PMC type (which might not be numeric).

> reasons I used iseq and isne, is that cmp_num returns -1, 0 or 1, so I
> checked for these return values.
>
> I think, if the new rel.ops can use islt and friends, then == and !=
> can use iseq and isne directly too without cmp_num, right?

I think my previous message was unclear... I wasn't aiming to
eliminate the cmp_num, but rather to use islt and friends on
the result of cmp_num (instead of iseq and isne). For example:

## infix:<
$I0 = cmp_num %0, %1
$I0 = islt $I0, 0

## infix:<=
$I0 = cmp_num %0, %1
$I0 = isle $I0, 0

## etc.

Pm

Patrick R. Michaud

unread,
Mar 28, 2008, 3:02:08 PM3/28/08
to Klaas-Jan Stol, Perl6 Internals
On Fri, Mar 28, 2008 at 04:35:42PM +0100, Klaas-Jan Stol wrote:
>
> attached an updated patch including some tests.

Patch applied in r26597. I made a few modifications before
applying:

- Updated the precedence of postfix:++ and postfix:-- to match

- Fixed the relational ops to use e.g., infix:«>» instead of 'infix:>'
(to preserve Perl 6 syntax in the grammar)

- Fixed the tests for relational ops to follow Perl 6 semantics.
In particular, in Perl 6 the expression 1 < 2 == 1 will always
evaluate to false because relational ops are chained and 2 is
never equal to 1. (For a couple of reasons NQP doesn't implement
chained relational ops just yet so the above "appears" to work,
but we should still restrict ourselves to Perl 6 semantics.
Perhaps for now we should force the relational operators to be
non-associative so people don't inadvertently expect them to
associate the old-fashioned way.)

Thanks for the excellent patch!

Pm

Chromatic

unread,
Mar 29, 2008, 5:48:11 PM3/29/08
to parrot-...@perl.org, Patrick R. Michaud
On Thursday 27 March 2008 18:20:21 Patrick R. Michaud wrote:

> Actually, it can be done without subclassing via the following
>
> .namespace [ 'ResizablePMCArray' ]
>
> .sub 'unshift' :method
> .param pmc list
> .param pmc value
> unshift list, value
> .end
>
> .sub 'shift' :method
> .param pmc list
> .param pmc value
> shift list, value
> .end
>
>
> I've already commented that perhaps these should be a built-in
> part of the ResizablePMCArray in Parrot. However, if that's
> not likely to happen, then perhaps either PCT or NQP should
> go ahead and provide them, so that they're available whenever
> PCT is loaded. But part of me feels that adding methods to
> ResizablePMCArray is a little out of NQP's scope.
>
> So, our choices become:
>
> 1. Have NQP automatically recognize shift/unshift/push/pop
> as "special functions" (keywords) and map them directly to
> Parrot's shift/unshift opcodes.

That's not too bad, but I'd like to reduce the amount of special magic in
Parrot as a general rule.

> 2. Add shift/unshift/push/pop methods to ResizablePMCArray
> (or one of its superclasses) in Parrot

This is my preference. It feels like a role.

> 3. Have PCT and/or NQP supply the shift/unshift/push/pop methods.
>
> 4. Have PCT and/or NQP define their own "List" subclass
> that provide shift/unshift/push/pop (this could conflict with
> "List" classes in other languages).

Conflicts are no fun.

-- c

Patrick R. Michaud

unread,
Mar 31, 2008, 2:53:25 PM3/31/08
to chromatic, parrot-...@perl.org
On Sat, Mar 29, 2008 at 02:48:11PM -0700, chromatic wrote:
> On Thursday 27 March 2008 18:20:21 Patrick R. Michaud wrote:
> > 2. Add shift/unshift/push/pop methods to ResizablePMCArray
> > (or one of its superclasses) in Parrot
>
> This is my preference. It feels like a role.

This is my preference as well -- done in r26670.
This should make things much simpler for NQP code.
There's part of me that doesn't like proliferating
the built-in types with lots of methods, but these
are fairly standard and we're already seeing method-based
interfaces for many other Parrot base types (e.g., classes,
roles, namespaces, etc.).

Thanks!

Pm

Bob Rogers

unread,
Mar 31, 2008, 11:33:42 PM3/31/08
to Patrick R. Michaud, chromatic, parrot-...@perl.org
From: "Patrick R. Michaud" <pmic...@pobox.com>
Date: Mon, 31 Mar 2008 13:53:25 -0500

On Sat, Mar 29, 2008 at 02:48:11PM -0700, chromatic wrote:
> On Thursday 27 March 2008 18:20:21 Patrick R. Michaud wrote:
> > 2. Add shift/unshift/push/pop methods to ResizablePMCArray
> > (or one of its superclasses) in Parrot
>
> This is my preference. It feels like a role.

This is my preference as well -- done in r26670.

This should make things much simpler for NQP code . . .

Thanks!

Pm

Do you remember the discussion two years ago [1] about eliminating the
user stack in favor of arrays? Chip made the following comment [2]:

From: Chip Salzenberg <ch...@pobox.com>
Subject: User stack: Worthwhile?
Date: Mon, 27 Feb 2006 09:46:42 -0800

Is there any other client of the user stack that can't be easily
replaced by some kind of *Array? It'd be nice to lop off such a
low-value feature.

The response (including yours) was generally in favor of chucking this
vestige of 1960's computer architecture, but nobody took up the mantle.
What is the current thinking on this?

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

[1] http://groups.google.com/group/perl.perl6.internals/browse_thread/thread/578d53dcbf0204cf/05971e618c6957d2

[2] http://www.nntp.perl.org/group/perl.perl6.internals/2006/02/msg33138.html

Jerry Gay

unread,
Mar 31, 2008, 11:43:12 PM3/31/08
to Bob Rogers, Patrick R. Michaud, chromatic, parrot-...@perl.org
my current thinking agrees with chip's and patrick's. the closer to
stackless we are, the better we handle threading. if you want to kill
it, i will not stand in your way.

~jerry

Chromatic

unread,
Mar 31, 2008, 11:45:14 PM3/31/08
to parrot-...@perl.org, Bob Rogers
On Monday 31 March 2008 20:33:42 Bob Rogers wrote:

> Do you remember the discussion two years ago [1] about eliminating the
> user stack in favor of arrays? Chip made the following comment [2]:
>
> From: Chip Salzenberg <ch...@pobox.com>
> Subject: User stack: Worthwhile?
> Date: Mon, 27 Feb 2006 09:46:42 -0800
>
> Is there any other client of the user stack that can't be easily
> replaced by some kind of *Array? It'd be nice to lop off such a
> low-value feature.
>
> The response (including yours) was generally in favor of chucking this
> vestige of 1960's computer architecture, but nobody took up the mantle.
> What is the current thinking on this?

If it's clean, I'm all for it.

-- c

Patrick R. Michaud

unread,
Apr 1, 2008, 12:15:43 AM4/1/08
to Bob Rogers, chromatic, parrot-...@perl.org
On Mon, Mar 31, 2008 at 11:33:42PM -0400, Bob Rogers wrote:
> Do you remember the discussion two years ago [1] about eliminating the
> user stack in favor of arrays? Chip made the following comment [2]:
>
> From: Chip Salzenberg <ch...@pobox.com>
> Subject: User stack: Worthwhile?
> Date: Mon, 27 Feb 2006 09:46:42 -0800
>
> Is there any other client of the user stack that can't be easily
> replaced by some kind of *Array? It'd be nice to lop off such a
> low-value feature.
>
> The response (including yours) was generally in favor of chucking this
> vestige of 1960's computer architecture, but nobody took up the mantle.
> What is the current thinking on this?

Unless user stack operations are somehow more efficient than
Resizable*Array PMCs, I don't see any reason for keeping them around.

Pm

Bob Rogers

unread,
Apr 1, 2008, 9:37:18 PM4/1/08
to jerry gay, chromatic, Patrick R. Michaud, parrot-...@perl.org
From: "Patrick R. Michaud" <pmic...@pobox.com>
Date: Mon, 31 Mar 2008 23:15:43 -0500

On Mon, Mar 31, 2008 at 11:33:42PM -0400, Bob Rogers wrote:

> Do you remember the discussion two years ago [1] about eliminating the
> user stack in favor of arrays? Chip made the following comment [2]:
>
> From: Chip Salzenberg <ch...@pobox.com>
> Subject: User stack: Worthwhile?
> Date: Mon, 27 Feb 2006 09:46:42 -0800
>
> Is there any other client of the user stack that can't be easily
> replaced by some kind of *Array? It'd be nice to lop off such a
> low-value feature.
>
> The response (including yours) was generally in favor of chucking this
> vestige of 1960's computer architecture, but nobody took up the mantle.
> What is the current thinking on this?

Unless user stack operations are somehow more efficient than


Resizable*Array PMCs, I don't see any reason for keeping them around.

Pm

To my great surprise, save and restore are more than 5x slower compared
to array push/pop, at least according to the simple benchmarks attached.
The save/restore version takes about 19s (user CPU) on my machine, but
the array push/pop version takes less than 3.6s. I haven't calibrated
the loops, nor have I tried types other than integer, but given the huge
difference for integers, I'm not sure I even need to bother.

================
From: "jerry gay" <jerr...@gmail.com>
Date: Mon, 31 Mar 2008 20:43:12 -0700

my current thinking agrees with chip's and patrick's. the closer to
stackless we are, the better we handle threading. if you want to kill
it, i will not stand in your way.

~jerry

The stack is actually stored in the Parrot_Context (oddly enough), so
IIUC it shouldn't affect threading. True?

================
From: chromatic <chro...@wgz.org>
Date: Mon, 31 Mar 2008 20:45:14 -0700

If it's clean, I'm all for it.

-- c

I'm way too short of tuits right now, but I'll add a ticket when I get a
chance. (Anybody who wants to help could start by rewriting code that
uses anything in src/ops/stack.ops -- and TIA!)

-- Bob

push-test-native.pir
push-test-array.pir
0 new messages