How would I do this in Perl6? #1

2004-09-14 Thread Michele Dondi
Dear all,

I've recently thought of a possible syntax extension for (Perl5's) 
[un]pack() and I posted my RFC to clpmisc where it didn't have much 
success, I must say. However I'm not interested in proposing it here, only 
I would like to investigate a possible Perl6 technique inspired by those 
thoughts...

Well, to come to the point, it does happen, even if admittedly not too
often and with not too long sequences, to use cascaded [un]pack()s. Now
I'm not specifically interested in *these* functions anymore, but more
generally in a generic function that accepts a first argument as a
template according to which it interpretates the other ones. For clarity I
will still use, say, pack().

Now I want to take a list of templates, say $t1, ... $tn and get the 
result of

  $result = pack $tn, ... pack $t2, pack $t1, @input;

without actually writing the whole thing. To my knowledge and great
pleasure Perl6 will support currying and a builtin reduce/fold operator.

So what I would like to do is (i) Cmap the list of templates to a list 
of curried closures in which the first parameter is fixed to each given 
template, (ii) Creduce this list by means of right pipe binop
( C ==  ) with a starting value (leftmost) of, say, @input.

What I'm asking is (i) wether this would actually be possible, and if so, 
then (ii) what it would probably look like in actual Perl6 code.

BTW: I guess something like
  
  my $result = @input ==
reduce operator:==, map {...}, @templates;

where {...} would represent the curried closures, if only I knew how they 
are supposed to look like!


TIA,
Michele
-- 
{$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}-(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^RY]*YB='
.'KYU;*EVH[.FHF2W+#\Z*5TI/ERZ`S(G.DZZ9OX0Z')=~/./g)x2,$_,
256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:\r;print,redo}#JAPH,


But is it intuitive?

2004-09-14 Thread Austin Hastings
I was thinking about removing files this morning, and realized that I 
wish rm supported inclusion/exclusion.

In particular, I wanted to remove * but not Makefile (since my 
Makefile uses lwp-download to re-fetch the source code, etc.)

It occurred to me to wonder: can P6's cbut do the same thing?
That is, can I say:
 $my_rex = qr/fo*/ but not 'foo';
 while () {
   unlink if /$my_rex/;
 }
and have it DWIM? What about globbing?
In general, what needs to be done to support this 'but, used as part of 
a boolean'?

In this case, but really means 'and':
 $my_rex = { my $re = qr/fo*/; $re.eval := sub { $_ ne 'foo'  call; 
}; return $re; };

This has interesting implications for specification of generators, too. 
Comment?

=Austin


Re: But is it intuitive?

2004-09-14 Thread Abhijit Mahabal

On Tue, 14 Sep 2004, Austin Hastings wrote:

 I was thinking about removing files this morning, and realized that I
 wish rm supported inclusion/exclusion.

 In particular, I wanted to remove * but not Makefile (since my
 Makefile uses lwp-download to re-fetch the source code, etc.)

 It occurred to me to wonder: can P6's cbut do the same thing?

 That is, can I say:

   $my_rex = qr/fo*/ but not 'foo';

   while () {
 unlink if /$my_rex/;
   }

The word junction came to my mind as I read your mail.

$my_rex = qr/fo*/  qr:not/foo/;

(I don't think that :not is the option to negate, but there must be some
syntax that works)

I am not saying this is a better way to do it, but just another way that
seems to do the same thing in the same way.

 In general, what needs to be done to support this 'but, used as part of
 a boolean'?


--abhijit



Re: But is it intuitive?

2004-09-14 Thread Mark J. Reed

On 2004-09-14 at 08:40:55, Austin Hastings wrote:
 In particular, I wanted to remove * but not Makefile (since my 
 Makefile uses lwp-download to re-fetch the source code, etc.)

Well, you can, depending on your shell:

in ksh: rm !(Makefile)

in bash: ditto, but you have to turn on the extglob option first with
 shopt -s extglob

in csh: think you're out of luck here.

Note that ksh/bash support multiple exclusions via alternation:

rm !(Makefile|configure|config.in)


-Mark


Re: But is it intuitive?

2004-09-14 Thread Luke Palmer
Abhijit Mahabal writes:
 
 On Tue, 14 Sep 2004, Austin Hastings wrote:
 
  I was thinking about removing files this morning, and realized that I
  wish rm supported inclusion/exclusion.
 
  In particular, I wanted to remove * but not Makefile (since my
  Makefile uses lwp-download to re-fetch the source code, etc.)
 
  It occurred to me to wonder: can P6's cbut do the same thing?
 
  That is, can I say:
 
$my_rex = qr/fo*/ but not 'foo';
 
while () {
  unlink if /$my_rex/;
}
 
 The word junction came to my mind as I read your mail.
 
 $my_rex = qr/fo*/  qr:not/foo/;

Judging from this, maybe we ought to have :not.

Anyway, it's still possible:

$my_rex = rx/fo*/  none(rx/^foo$/);

Luke


Re: But is it intuitive?

2004-09-14 Thread Austin Hastings
Luke Palmer wrote:
Judging from this, maybe we ought to have :not.
Anyway, it's still possible:
   $my_rex = rx/fo*/  none(rx/^foo$/);
 

For sure. On a side note, there should be a negating match operator for 
use inside:

  rx/\d+/  none(rx/1984/)
could get awfully long if you had to handle several exceptions.
I like rx:not, though -- a little easier to read IMO.
=Austin


Re: But is it intuitive?

2004-09-14 Thread Aaron Sherman
On Tue, 2004-09-14 at 10:11, Abhijit Mahabal wrote:
 On Tue, 14 Sep 2004, Austin Hastings wrote:

  That is, can I say:
 
$my_rex = qr/fo*/ but not 'foo';

 The word junction came to my mind as I read your mail.
 
 $my_rex = qr/fo*/  qr:not/foo/;

Of course, the regex itself can do this:

qr{(fo*) ({$1 ne 'foo'})}

This is probably the superior option, as it can backtrack, where the
others cannot. Thus for the string foo you would match fo because
you find foo first, and it fails, causing the first subexpression to
backtrack, but you can still match fooo correctly on the first try.

-- 
 781-324-3772
 [EMAIL PROTECTED]
 http://www.ajs.com/~ajs



Re: How would I do this in Perl6? #1

2004-09-14 Thread Aaron Sherman
On Tue, 2004-09-14 at 06:45, Michele Dondi wrote:
[... snip ...]
 Now I want to take a list of templates, say $t1, ... $tn and get the 
 result of
 
   $result = pack $tn, ... pack $t2, pack $t1, @input;

Assuming Perl 6 has a pack, which it may not:

for @t {
$result = pack $_, ($result // @input);
}

no?

-- 
 781-324-3772
 [EMAIL PROTECTED]
 http://www.ajs.com/~ajs



Re: But is it intuitive?

2004-09-14 Thread Juerd
Aaron Sherman skribis 2004-09-14 14:02 (-0400):
   qr{(fo*) ({$1 ne 'foo'})}

What is the second set of parens for? Will the following suffice?

rx/ (fo*) { $1 ne 'foo' } /

And it is because of the lack of anchors that this won't work as
expected?

rx/ !before foo fo* /


Juerd


Re: But is it intuitive?

2004-09-14 Thread Larry Wall
On Tue, Sep 14, 2004 at 02:02:22PM -0400, Aaron Sherman wrote:
: Of course, the regex itself can do this:
: 
:   qr{(fo*) ({$1 ne 'foo'})}

Er, at the moment bare closures don't care about their return value,
so as it currently stands, you'd want something more like:

rx/(fo*) {fail if $1 eq 'foo'}/

or

rx/(fo*) ($1 ne 'foo')/

But yes, backtracking is a decent way to handle it.

Larry


Re: But is it intuitive?

2004-09-14 Thread Larry Wall
On Tue, Sep 14, 2004 at 08:30:45PM +0200, Juerd wrote:
: Aaron Sherman skribis 2004-09-14 14:02 (-0400):
:  qr{(fo*) ({$1 ne 'foo'})}
: 
: What is the second set of parens for? Will the following suffice?
: 
: rx/ (fo*) { $1 ne 'foo' } /

Bare closures are used only for their side effects in the current design.
It's vaguely possible that we could recognize a top level boolean operator
and do something different, but there are problems with that approach.

: And it is because of the lack of anchors that this won't work as
: expected?
: 
: rx/ !before foo fo* /

No, the f pretty well anchors the front of it in any case.  It's the
other end that is the problem.  Your solution disallows fooo.
You'd have to say something like:

 rx/ !before foo !before o fo* /

Larry


Re: But is it intuitive?

2004-09-14 Thread Aaron Sherman
On Tue, 2004-09-14 at 14:40, Larry Wall wrote:
 On Tue, Sep 14, 2004 at 02:02:22PM -0400, Aaron Sherman wrote:
 : Of course, the regex itself can do this:
 : 
 : qr{(fo*) ({$1 ne 'foo'})}
 
 Er, at the moment bare closures don't care about their return value,
 so as it currently stands, you'd want something more like:
 
 rx/(fo*) {fail if $1 eq 'foo'}/

Dang, where's that Perl 6 compiler when I need it to clear up this sort
of thing? ;-)

Thanks for the correction. I notice I fell for the qx vs rx thing
too. Heh, old habits die hard.

-- 
 781-324-3772
 [EMAIL PROTECTED]
 http://www.ajs.com/~ajs



Re: How would I do this in Perl6? #1

2004-09-14 Thread Michele Dondi
On Tue, 14 Sep 2004, Aaron Sherman wrote:

 Assuming Perl 6 has a pack, which it may not:

I know: this is one of the reasons why I wrote (hopefully *clearly*
enough) that I was just using it as an example. A user defined pack()
whoud do just the same here, anyway.

   for @t {
   $result = pack $_, ($result // @input);
   }

It's hard to believe, but surprising as it may be, I could have thought of 
a (ton, possibly, of) solution(s) along those lines (the C// op is 
cool though).

The point here is that I find it conceptually appealing, elegant and smart 
to be able to use functions as primitive data types as in functional 
languages. I'm not saying that I want to enforce only such constructs, but 
I'd like to be allowed to use them. So the question is: even being aware 
of more traditional solutions of the kind of that cited above, will it 
be possible to adopt one similar to that hinted to in my previous post? 
And if so, then how would it probably look like?

 no?

Yes...

...So what?!?


Michele
-- 
It's not considered polite in my circles to tell others that
they are being impolite, unless the others are your children.  
Looks like I'm not very polite, doesn't it?
- Mike Prager on comp.text.tex, thread usenet news group style


Re: How would I do this in Perl6? #1

2004-09-14 Thread Matt Diephouse
On Tue, 14 Sep 2004 12:45:17 +0200 (CEST), Michele Dondi
[EMAIL PROTECTED] wrote:
 Now I want to take a list of templates, say $t1, ... $tn and get the
 result of
 
   $result = pack $tn, ... pack $t2, pack $t1, @input;
 
 without actually writing the whole thing. To my knowledge and great
 pleasure Perl6 will support currying and a builtin reduce/fold operator.

You could do this with a recursive function (They're your friends. Really.).

sub extended_pack( [EMAIL PROTECTED] =  ($t1, ... , $tn), [EMAIL PROTECTED] ) {
# start with the last template so we can use tail recursion
@input = pack pop(@templates), @input;
# if there aren't any more templates, we're done
return @input if not @templates;
return extended_pack(@templates, [EMAIL PROTECTED]);
}

Or in Perl 5, which has to use 2 subs to have the same interface (code
untested):

sub extended_pack {
my (@input)   = @_;
my @templates = ($t1, ..., $tn);
return extended_pack_rec([EMAIL PROTECTED], [EMAIL PROTECTED]);
}

sub extended_pack_rec {
my ($input, $templates) = @_;
@$input = pack pop(@$templates), @$input;
return @$input if not @$templates;
# special goto magic for tail recursion
@_ = ($input, $templates);
goto extended_pack_rec;
}

I prefer Perl 6.

-- 
matt