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

Perl* Abstraction

7 views
Skip to first unread message

Luke Palmer

unread,
Jul 7, 2003, 4:42:25 PM7/7/03
to perl6-i...@perl.org
Going about (finally) implementing my Infinity pmc, I noticed a lot of
redundant code in the Perl* classes. For instance, the polymorphic
behavior isn't implemented in PerlScalar, but rather in each of its
subclasses, which seems to rather defeat the purpose of making them
subclasses.

However, trying to move the functionality up to PerlScalar just got me
in more trouble, where seemingly unrelated tests would fail, &c. So
is it some implementation detail that we can't put these up in
PerlScalar? Maybe I just did something wrong that I didn't see.

But on a longer-term note, is this the way we really should be doing
it? I mean, after all, it's not a PerlInteger that's polymorphic,
it's the container -- the integer is just the value it holds. Putting
the polymorphism in the value type somewhat precludes storing any
other kind of PMC in a Perl scalar. (Maybe that's a good thing... I'm
not entirely sure of how people are envisioning scalars to work with
everything else).

The way I see this being done is by adding another level of
indirection. PerlScalar would implement its polymorphic behavior in
the set_* methods, and delegate everything else to its "contained"
pmc. Things like TiedScalar would do the same, but it would delegate
to methods on its contained object, &c.

Of course, there is a slight added cost for the extra level of
indirection, but it's worth it IMO. Is this worth persuing?

Luke

Leopold Toetsch

unread,
Jul 8, 2003, 2:21:56 AM7/8/03
to Luke Palmer, perl6-i...@perl.org
Luke Palmer wrote:

> Going about (finally) implementing my Infinity pmc, I noticed a lot of
> redundant code in the Perl* classes.

[ ... ]


> The way I see this being done is by adding another level of
> indirection. PerlScalar would implement its polymorphic behavior in
> the set_* methods, and delegate everything else to its "contained"
> pmc. Things like TiedScalar would do the same, but it would delegate
> to methods on its contained object, &c.

This is, what the intended var/value split of the vtable is for. I don't
like code duplication too, but OTOH its faster then going one more
indirection or better calling another vtable method.


> Of course, there is a slight added cost for the extra level of
> indirection, but it's worth it IMO. Is this worth persuing?

Don't know yet. When we have more experience with $HL needs and
var/value split, references or TiedScalar are in, we can look again and
more detailed at it.


> Luke

leo

Nick Glencross

unread,
Jul 10, 2003, 3:18:32 PM7/10/03
to perl6-i...@perl.org
Luke Palmer wrote:

>The way I see this being done is by adding another level of
>indirection. PerlScalar would implement its polymorphic behavior in
>the set_* methods, and delegate everything else to its "contained"
>pmc.
>

Having read up in the past on Perl5 internals, it seems to be capable of
keeping more than one representation of a Scalar active at a time. For
instance, if you assigned a number to a variable, treat it like a
string, and then again as a number, it does a number->string conversion
while still keeping the number around in case you are still going to use it.

Anyone know if there are plans to do this kind of optimisation?
(assuming that it hasn't already!)

Regards,

Nick

Benjamin Goldberg

unread,
Jul 11, 2003, 3:50:42 PM7/11/03
to perl6-i...@perl.org
Leopold Toetsch wrote:

> Nick Glencross wrote:
>
> > Having read up in the past on Perl5 internals, it seems to be
> > capable of keeping more than one representation of a Scalar active
> > at a time.
> >
> > Anyone know if there are plans to do this kind of optimisation?
>
> I don't think, this is an optimization at least not for an average
> program. Processor cycles are cheap these days, memory access still
> isn't. A lot of my recent work was to reduce the scalar size from 32
> to 20 byte (32bit). This almost doubles performance on accessing huge
> (1e6) data sets.
> OTOH, if there is a clear need for an e.g. NumStr hybrid, then it
> should be a separate PMC which is used, when $HL says so by some
> traits.

There is indeed a clear need for it -- the values produced by $! (and by
the related $^E) are dual int/string values. If you do:

$! = 3;
my $x = $!;
printf "%d: %s\n", $x, $x;

It outputs, on my system: "3: No such process", indicating that the
value in $x contains both a string and a number, in a way that cannot be
obviously generated one from the other. Also, the module Scalar::Util
has a dualvar() subroutine, which produces int/string values of this
type.

Also, consider the following:

[Windows 95] C:\WINDOWS>perl -we "$x = '';" -e "$x + 0;" -e "$x + 0;"
Useless use of addition (+) in void context at -e line 2.
Useless use of addition (+) in void context at -e line 3.
Argument "" isn't numeric in addition (+) at -e line 2.
[Windows 95] C:\WINDOWS>perl -we "$x = '1x';" -e "$x + 0;" -e "$x + 0"
Useless use of addition (+) in void context at -e line 2.
Useless use of addition (+) in void context at -e line 3.
Argument "1x" isn't numeric in addition (+) at -e line 2.

Note that the 'Argument ... isn't numeric' warning only appeared once
for each of these one-liners -- this is because $x was upgraded from a
mere "" to a dualvar("", 0).

We don't *need* to do things this way, of course -- but that's how perl5
does it, and we might or might not find this to be the simplest
solution.

Another possibility is to have, for our String PMC class, a flag
indicating not to warn when numifiying. The first time we numify a
string which isn't really a proper number, we warn, then set this flag.
After that, we still have to numify (since we didn't cache the extracted
number), but we don't warn due to seeing the flag.

But we'd still need some sort of dualvar/NumStr for $! and $^E.

--
$a=24;split//,240513;s/\B/ => /for@@=qw(ac ab bc ba cb ca
);{push(@b,$a),($a-=6)^=1 for 2..$a/6x--$|;print "$@[$a%6
]\n";((6<=($a-=6))?$a+=$_[$a%6]-$a%6:($a=pop @b))&&redo;}

Chip Salzenberg

unread,
Jul 11, 2003, 4:20:34 PM7/11/03
to Benjamin Goldberg, perl6-i...@perl.org
According to Benjamin Goldberg:
> There is indeed a clear need for it ...

False.

> We don't *need* to do things this way, of course ...

True.

Having gone through the pain of numstr implementation, I suggest that
normal variables should not be forced to do anything so unnatural.
(Customized PMCs can of course respond with anything they like.)
--
Chip Salzenberg - a.k.a. - <ch...@pobox.com>
"I wanted to play hopscotch with the impenetrable mystery of existence,
but he stepped in a wormhole and had to go in early." // MST3K

Brent Dax

unread,
Jul 11, 2003, 4:36:35 PM7/11/03
to Benjamin Goldberg, perl6-i...@perl.org
Benjamin Goldberg:
# There is indeed a clear need for it -- the values produced by $! (and
by
# the related $^E) are dual int/string values.

In Perl 5, yes. However, in Perl 6, $! is set for *all* exceptions, not
just C<errno> errors, so I suspect that this behavior is no longer
appropriate. (IIRC, C<errno> errors are unthrown exceptions--a normal
exception object sits in $!, but it's never thrown.)

I expect that in Perl 6 after an C<errno> error, $! will be set to an
exception of class X::Errno (or something like it); that class may have
overloaded prefix:+ and prefix:~ operators as necessary.

--Brent Dax <br...@brentdax.com>
Perl and Parrot hacker

"Yeah, and my underwear is flame-retardant--that doesn't mean I'm gonna
set myself on fire to prove it."

Steve Fink

unread,
Jul 11, 2003, 9:19:29 PM7/11/03
to Chip Salzenberg, Benjamin Goldberg, perl6-i...@perl.org
On Fri, Jul 11, 2003 at 04:20:34PM -0400, Chip Salzenberg wrote:
> According to Benjamin Goldberg:
> > There is indeed a clear need for it ...
>
> False.
>
> > We don't *need* to do things this way, of course ...
>
> True.
>
> Having gone through the pain of numstr implementation, I suggest that
> normal variables should not be forced to do anything so unnatural.
> (Customized PMCs can of course respond with anything they like.)

These sound very close to what we'll need to imlement any() and all(),
so we'll probably need container PMCs that can represent multiple
contained PMCs of any type.

$status = any(4, "Interrupted system call");

? :-)

(I think Brent Dax has it right, though, that $! should be a full
exception object.)

Leopold Toetsch

unread,
Jul 13, 2003, 2:22:28 PM7/13/03
to Benjamin Goldberg, perl6-i...@perl.org
Benjamin Goldberg <ben.go...@hotpop.com> wrote:

> Leopold Toetsch wrote:
>> OTOH, if there is a clear need for an e.g. NumStr hybrid, then it
>> should be a separate PMC which is used, when $HL says so by some
>> traits.

> There is indeed a clear need for it -- the values produced by $! (and by
> the related $^E) are dual int/string values. If you do:

This can simply be achieved by PerlError's vtables get_string and
get_int. No need for caching/dual values.

leo

0 new messages