Mailing List Archive

classes of hard-to-prototype
- having to do with file/directory handles (the notorious File Object Wars :-)
(-X, binmode, closedir, eof, ...)

- regexps (no compiled regexps saved into scalars)
(m, s, split)

- blocks (blocks can be emulated with code refs (closures) to some extent
but this leads to more complicated code *))
(eval, grep, map, sort)

I tried writing a generalised 'reduce' operation of which e.g. sum,
product, min, max, are just special cases. Sort of a cousin to map
or grep. My idea of the interface is

reduce BLOCK, LIST;

where the block would have $a and $b (a la sort()), $a being the result,
initialised to be the first element of the list, $b iterating down
the list, $a changing to be the result of evaluating the block with
$a and $b inside it. At the moment I can do either:

sub reduce1 {
my $e = shift;
my $a = shift;
my $b;

for (@_) {
$b = $_;
$a = &$e($a, $b);
}
$a;
}

reduce1 sub { my ($a, $b) = @_; $a + $b }, @LIST; # yuk! *)

or

sub reduce2 {
my $e = shift;
my $a = shift;
my $b;

for (@_) {
$b = $_;
$a = eval $e;
}
$a;
}

reduce2 '{ $a + $b }', @LIST; # 'blech'.

to do sums but I cannot really have a block

reduce3 { $a + $b }, @LIST;

as an argument. Well, hoping for the sort() magic of $a and $b may be
too much to hope for... the reduce2 is almost in there, the block is
evaluated in the context where $a and $b mean something, the only ugly
thing is the required quoting.

As usual, I am probably missing something...

++jhi;
Re: classes of hard-to-prototype [ In reply to ]
>- having to do with file/directory handles (the notorious File Object Wars :-)
> (-X, binmode, closedir, eof, ...)

Really? I thought that a prototype of \*SYM would do those. Larry
wrote thqt it did "whatever was right" to pass a bareword as a
proper stab ref, or words I took to be of that effect.

>- regexps (no compiled regexps saved into scalars)
> (m, s, split)

m and s are hard because they've got those funky pseudo delims. split is hard
because it's prototyped to take a regexp or a string, and we can't protoregexps. Hm..
Hey Lar, this is just another bug fix get compiled regexps. :-)

More seriously, there was a patch floating around to "do the right thing" so we
woudlnt' have to remember to do /o or use a match_any() function. Did it happen?
Whose was it?

>- blocks (blocks can be emulated with code refs (closures) to some extent
> but this leads to more complicated code *))
> (eval, grep, map, sort)

>I tried writing a generalised 'reduce' operation of which e.g. sum,
>product, min, max, are just special cases. Sort of a cousin to map
>or grep. My idea of the interface is

> reduce BLOCK, LIST;


That should proto out as

sub reduce(\*@);

and then you should be able to use

@list = reduce { $a + $b } @list;
or maybe
@list = reduce { $a + $b } => @list;

Although arranging to load the proper $a nad $b in the face of lexicals
is a severe difficulty solved not even by sort().

--tom
Re: classes of hard-to-prototype [ In reply to ]
>- having to do with file/directory handles (the notorious File Object Wars :-)
> (-X, binmode, closedir, eof, ...)

Really? I thought that a prototype of \*SYM would do those. Larry
wrote thqt it did "whatever was right" to pass a bareword as a
proper stab ref, or words I took to be of that effect.

>- regexps (no compiled regexps saved into scalars)
> (m, s, split)

m and s are hard because they've got those funky pseudo delims. split is hard
because it's prototyped to take a regexp or a string, and we can't protoregexps. Hm..
Hey Lar, this is just another bug fix get compiled regexps. :-)

More seriously, there was a patch floating around to "do the right thing" so we
woudlnt' have to remember to do /o or use a match_any() function. Did it happen?
Whose was it?

>- blocks (blocks can be emulated with code refs (closures) to some extent
> but this leads to more complicated code *))
> (eval, grep, map, sort)

>I tried writing a generalised 'reduce' operation of which e.g. sum,
>product, min, max, are just special cases. Sort of a cousin to map
>or grep. My idea of the interface is

> reduce BLOCK, LIST;


That should proto out as

sub reduce(\*@);

and then you should be able to use

@list = reduce { $a + $b } @list;
or maybe
@list = reduce { $a + $b } => @list;

Although arranging to load the proper $a nad $b in the face of lexicals
is a severe difficulty solved not even by sort().

--tom
Re: classes of hard-to-prototype [ In reply to ]
: >- having to do with file/directory handles (the notorious File Object Wars :-)
: > (-X, binmode, closedir, eof, ...)
:
: Really? I thought that a prototype of \*SYM would do those. Larry
: wrote thqt it did "whatever was right" to pass a bareword as a
: proper stab ref, or words I took to be of that effect.

The problem with some of those is that they take a filehandle or a filename.

: >- regexps (no compiled regexps saved into scalars)
: > (m, s, split)
:
: m and s are hard because they've got those funky pseudo delims. split is hard
: because it's prototyped to take a regexp or a string, and we can't protoregexps. Hm..
: Hey Lar, this is just another bug fix get compiled regexps. :-)

I don't answer to "Lar". Well, okay, just this once...

: More seriously, there was a patch floating around to "do the right thing" so we
: woudlnt' have to remember to do /o or use a match_any() function. Did it happen?
: Whose was it?

Yes and no. There's a patch in 5.002 to do stupid caching of a particular
pattern match so it doesn't recompile if the pattern string is the same.
But the cache is still with the syntax, not with the compiled string.
I didn't get around to doing a smart patch that would cache the compiled
regexp with the regexp string.

: >- blocks (blocks can be emulated with code refs (closures) to some extent
: > but this leads to more complicated code *))
: > (eval, grep, map, sort)
:
: >I tried writing a generalised 'reduce' operation of which e.g. sum,
: >product, min, max, are just special cases. Sort of a cousin to map
: >or grep. My idea of the interface is
:
: > reduce BLOCK, LIST;
:
: That should proto out as
:
: sub reduce(\*@);
:
: and then you should be able to use
:
: @list = reduce { $a + $b } @list;
: or maybe
: @list = reduce { $a + $b } => @list;

No, you want the form without a comma, declared as (&@). A (\*@) would
FORCE you to say

reduce *{whatever}, LIST;

Here's what you want:

sub reduce (&@) {
my $code = shift;
local $a = shift;
foreach $b (@_) {
$a = &$code;
}
$a;
}

print reduce { $a + $b } 1,2,3,4,5;

This prints 15.

: Although arranging to load the proper $a nad $b in the face of lexicals
: is a severe difficulty solved not even by sort().

In the absence of that problem, $a and $b are just dynamically scoped
variables. I'm wondering whether I should just disallow lexical $a and $b.

Larry
Re: classes of hard-to-prototype [ In reply to ]
Lar was short for Lars; just trying to prep you for your week in
Scandihoovia, as would frequently called the old terra mater back in
Wisconsin where >50% of the surnames =~ /s+[eo]n$/ :-)

I meant \& not \*. Nice that it's just &. You wouldn't believe the
keyboard I'm typing on (German version very highly remapped -- I do better
with my eyes closed).

>: is a severe difficulty solved not even by sort().

>In the absence of that problem, $a and $b are just dynamically scoped
>variables. I'm wondering whether I should just disallow lexical $a
>and $b.

Hm... perhaps. Or emitting a warning at least. Dunno on that. I guess
it would help. I'm also having severe problems with folks and their
foreach() loop indices being lexicals that they're trying to get at in
their format()s, which just doesn't work. I warned about it in the new
perlsyn, but I forgot to also warn of it in perlform.

That's enough. It's 11:30pm here, and I have to quit before it's already
tomorrow. :-)

--tom
Re: classes of hard-to-prototype [ In reply to ]
Larry Wall writes:
> Here's what you want:
>
> sub reduce (&@) {
> my $code = shift;
> local $a = shift;
> foreach $b (@_) {
> $a = &$code;
> }
> $a;
> }
>
> print reduce { $a + $b } 1,2,3,4,5;
>
> This prints 15.
>
> : Although arranging to load the proper $a nad $b in the face of lexicals
> : is a severe difficulty solved not even by sort().
>
> In the absence of that problem, $a and $b are just dynamically scoped
> variables. I'm wondering whether I should just disallow lexical $a and $b.

Hmm, from your code it looks like foreach localizes the variable, not
lexicalizes it?

This goes along another feature I want in mind. I would like to
prototype
myforeach $var (getarray) {something}
possibly
matrix $x ,? $y ,? (17,4) ,? sub? {$x * $y + 1};
with a prototype
(##@&)
Here the "pound" ;-) is just 1.6 times a dollar, i.e., it localizes
the variable, & after @ does not need comma and a "sub". It looks like
final ';' is better there than not, since the function may return
something.

Just a wild speculation so far, but now the real question: in the absence
of a suitable prototype I may code it so that it takes
matrix $x, $y, 17, 4, sub {$x * $y + 1};
The question is: how to localize a variable in XS subject to
a possibility of longjump? Or should I do G_EVAL and rethrow die after
reproducing previous values manually?

Ilya
Re: classes of hard-to-prototype [ In reply to ]
In <9511282221.AA05678@scalpel.netlabs.com>
On Tue, 28 Nov 95 14:21:16 -0800
Larry Wall <lwall@scalpel.netlabs.com> writes:
>
>In the absence of that problem, $a and $b are just dynamically scoped
>variables. I'm wondering whether I should just disallow lexical $a and $b.
>
-w warning for them?