Re: When scoping

2005-05-05 Thread Luke Palmer
On 5/4/05, Larry Wall [EMAIL PROTECTED] wrote:
 To get the other behavior, you have to say one of:
 
 given hello {
 when /hello/ {
 say One;
 when /hello/ { say Two; continue; }
 when /hello/ { say Three; continue; }
 continue;
 }
 say Four;
 }
 
 given hello {
 when /hello/ {
 say One;
 say Two when /hello/;
 say Three when /hello/;
 continue;
 }
 say Four;
 }
 
 given hello {
 when /hello/ {
 say One;
 if /hello/ { say Two; }
 if /hello/ { say Three; }
 continue;
 }
 say Four;
 }
 
 That seems like enough WTDI. 

Not quite.  There's also the way that I have it in the pugs IRC bot:

given hello {
when /hello/ {
given $_ {
say One;
when /hello/ { say Two }
when /hello/ { say Three }
}
}
say Four;
}

Which I actually like the best.  If only it weren't so heavily indented.

Hmmm, maybe I should go implement Acme::Whiven:

given hello {
whiven /hello/ {
when /hello/ {...}
...
}
}

Luke


Re: reduce metaoperator

2005-05-05 Thread Damian Conway
Luke Palmer wrote:
On 5/4/05, Larry Wall [EMAIL PROTECTED] wrote:
[] could mean monotonically increasing.
Not unless we make boolean operators magic.  There are arguments for
doing that, but I don't really want to think about how that would be
done at the moment.  Reduce over a straight-up (or left) boolean
operator doesn't make much sense...
But the comparators *are* magic in Perl 6. They're not binary, they're 
n-ary.
So, since:
[] @vals
actually means:
@vals[0]  @vals[1]  @vals[2]  @vals[3]
we get the n-ary behaviour, which is true if those values *are* in that order.
Perhaps you're forgetting the difference between what reduce means 
mathematically, and how its semantics are approximated in Perl 5 (in 
List::Util). Reduce means bung this operator in between each of the 
elements of this list. But there's no way[*] to do that directly in Perl 5, 
so we currently have to live with a pairwise binary approximation.

That's perhaps the nicest feature of Larry's proposed reduction operator: that 
it will finally allow us to implement the real semantics of reduce and so 
get all the handy metaoperators (sum, product, sum-of-squares, monotonicity, 
first-true, first-defined) we've been missing to date.

Damian
[*] Okay, that's not strictly true. Evil Damian is already contemplating how
to implement n-ary reduction in Perl 5. Bwah-ha-ha-ha!


Re: stdio

2005-05-05 Thread Larry Wall
On Thu, May 05, 2005 at 08:39:52AM +0300, Gaal Yahas wrote:
: How do I open a file named -?

Um, depending on what you mean, and whether we continue to support
the '=' pseudofile, maybe:

$fh = io(-);

or

$fh = open -;

or

$fh = $name eq '-' ?? $*IN :: open $name;

: How do I open stdout (and the other standard handles)?

Maybe something like:

$fh = open file, :w:c:usefd(1);

or

$*OUT.reopen(file,:w:c);

or

reopen $*OUT: file, :w:c;

give or take a few options.

Larry


Re: stdio

2005-05-05 Thread Gaal Yahas
On Wed, May 04, 2005 at 11:44:58PM -0700, Larry Wall wrote:
 : How do I open a file named -?
 
 Um, depending on what you mean, and whether we continue to support
 the '=' pseudofile, maybe:
 
 $fh = io(-);
 $fh = open -;
 $fh = $name eq '-' ?? $*IN :: open $name;

My concern is again with magic control. I've no gripes with the first
or last of those, but I think the second should not be allowed by
default. There has to be a safe mode for opening a file and knowing
that's what you're opening: not a pipe, not stdio (hence there are places
I can't permit myself to use #1). But as your third example suggests,
never allowing open - will make unixish tools tedious to write, so
maybe we need something like

getopt(...);
$fh = open $in, :allowstdio;

(only named more eloquently).

 : How do I open stdout (and the other standard handles)?
 
 Maybe something like:
 
 $fh = open file, :w:c:usefd(1);
 $*OUT.reopen(file,:w:c);
 reopen $*OUT: file, :w:c;
 
 give or take a few options.

What does 'file' do in these examples? If we take your trailing-args
suggestion from the Open and pipe thread, the filename could be optional.

How to make this --friendly? If my earlier suggestion is okay, then
by symmetry:

$logfile = -;
open $log, :a:allowstdio;

-- 
Gaal Yahas [EMAIL PROTECTED]
http://gaal.livejournal.com/


Re: Open and pipe

2005-05-05 Thread Graham Barr
On May 4, 2005, at 8:13 AM, Uri Guttman wrote:
  AS Why? Because IO::Socket.new takes parameters that are built out 
of its
  AS entire inheritance tree, so a change to IO::Handle might 
radically
  AS modify the signature of the constructor.

makes sense. we should look at the p5 IO:: tree and see what we want to
salvage/savage from it as well as io::all. each has its good and bad
points and hopefully we can figure out which is which. :)
Yes. p5 IO:: has evolved a bit over time and some things have turned 
out to be bad choices in hindsight.

For example, one thing I am still not convinced was the right thing was 
to create a hierarchy such that a given class only had methods that 
were valid for it. For example the recent issue on p5p with seek etc 
not being in IO::Handle but IO::Seekable and the core using IO::Handle.

Also the way IO::Socket::* was done instead of all sockets created by 
IO::Socket-new

these are all things that should be reconsidered and I am sure in all 
cases there will be people on both sides of the fence

Graham.


Re: When scoping

2005-05-05 Thread Larry Wall
On Wed, May 04, 2005 at 11:00:46PM -0700, David Wheeler wrote:
: On May 4, 2005, at 22:31 , Larry Wall wrote:
: 
: given hello {
: when /hello/ {
: say One;
: if /hello/ { say Two; }
: if /hello/ { say Three; }
: continue;
: }
: say Four;
: }
: 
: Is there no more
: 
:   say Two if /hello/;
: 
: ?

You must have missed the implied ... at the end of my list of other WTDI.
You can also do any of:

say Two if /hello/;
/hello/  say Two;
/hello/ and say Two;
/hello/ ?? say Two :: leave;
infix:and(/hello/, { say Two })
continue unless /hello/; say Two;
/hello { say Two }/;
s/hello/{ say Two }$0/;
({}, { say Two })[?/hello/]();

and probably a few more I can't think of off the top of my head.

Larry


Re: reduce metaoperator

2005-05-05 Thread Larry Wall
On Wed, May 04, 2005 at 11:58:59PM -0600, Luke Palmer wrote:
: On 5/4/05, Larry Wall [EMAIL PROTECTED] wrote:
:  [] could mean monotonically increasing.
: 
: Not unless we make boolean operators magic.  There are arguments for
: doing that, but I don't really want to think about how that would be
: done at the moment.  Reduce over a straight-up (or left) boolean
: operator doesn't make much sense...

It could be admitted under the rewrite rule as applied to chaining
comparison operators, such that

if [](1,2,3) {...}

is the same as

if 1  2  3 {...}

Likewise, one could write [|] to mean any and [] to mean all,
but that'd be kind of silly.

On the other hand, I freely admit that those don't work under a recursive
binary view that artificially forces left-associativity.

Larry


Re: Cmmposition binop

2005-05-05 Thread Michele Dondi
On Thu, 5 May 2005, Stuart Cook wrote:
What I refer to now is something that takes two {coderefs,anonymous
subs,closures} and returns (an object that behaves like) another anonymous
sub, precisely the one that acts like the former followed by the latter
(or vice versa!).
Do you mean like the mathematical 'f o g'?
Indeed.
Michele
--
Have you noticed that people whose parents did not have children, also 
tend not to have children.
- Robert J. Kolker in sci.math, Re: Genetics and Math-Ability


Re: stdio

2005-05-05 Thread Gaal Yahas
On Thu, May 05, 2005 at 01:32:56AM -0600, Luke Palmer wrote:
 On 5/5/05, Gaal Yahas [EMAIL PROTECTED] wrote: 
  getopt(...);
  $fh = open $in, :allowstdio;
 
 Maybe the opposite:
 
 $fh = open $in, :literal;
 
 One of the nice things about the magical - behavior is that people
 are writing more versatile, accepting scripts without realizing it. 
 That was one of the things that made me really like Perl when I first
 started learning it.  A few of the little utility / filter scripts
 that I wrote already accepted - on the command line, and I didn't
 even know it (and they still worked perfectly when you used -).

Yeah, you and me both.

 And I don't think arguing in the name of security for the default
 case is going to buy us anything.  Security doesn't come in scripts in
 any language for free; you have to walk through every line that sees
 the outside world and ask is there any way somebody could exploit
 this?.  And a - handler would be one of the things you'd have to
 routinely write, just like making sure they're not opening ; rm -rf
 /.

Why are you scare-quoting something I never said? I wasn't talking about
security, I was talking about basic least-surprise. Opening ; rm -rf /
with my perl5 does not do anything bad. Opening - potentially causes a
script to hang.

 But I don't think a :literal flag or whatever will be a problem.

Yes, I like your proposal, though I don't know which way should be the
default. I'm not looking for sysopen (I know where to find it), I'm
looking for an easy way to control magic.

 You can also open a file named -, in the absence of a literal
 option, like this:
 
 my $fh = open ./-;

I'd say fine, except that this isn't portable.

 I think he misunderstood you (and if not, then I misunderstood you
 :-).  You're asking about how to get a filehandle to stdout, he's
 telling you how to redirect stdout to a file.
 
 I think - will do the trick.

Ah, yes, then again the question is how to conveniently choose whether
to do e.g. log-to-stdout or write to a file named -.

-- 
Gaal Yahas [EMAIL PROTECTED]
http://gaal.livejournal.com/


Re: stdio

2005-05-05 Thread Luke Palmer
On 5/5/05, Gaal Yahas [EMAIL PROTECTED] wrote:
 On Thu, May 05, 2005 at 01:32:56AM -0600, Luke Palmer wrote:
  And I don't think arguing in the name of security for the default
  case is going to buy us anything.  Security doesn't come in scripts in
  any language for free; you have to walk through every line that sees
  the outside world and ask is there any way somebody could exploit
  this?.  And a - handler would be one of the things you'd have to
  routinely write, just like making sure they're not opening ; rm -rf
  /.

 Why are you scare-quoting something I never said?

I'm scare-quoting everything today for some reason.  Sorry.

The issue has come up before, and one of the main arguments was it's
more secure that way, which made so little sense, I thought that I'd
argue against it again.  Or something.

Luke


Re: reduce metaoperator

2005-05-05 Thread Leopold Toetsch
Larry Wall [EMAIL PROTECTED] wrote:

 It would be nice to have an easy-to-access What's this? interface
 that could be stitched into your favorite editor to identify what's
 under the cursor, or at least a command like:

 p6explain '[+]'

s:p5/nice to have/absolutely necessary/ unless $self ~~ @larry;

Could $EDITOR-p6explain use life information from the parser with the
current context of the requested token?

leo


Re: stdio

2005-05-05 Thread Larry Wall
On Thu, May 05, 2005 at 10:14:34AM +0300, Gaal Yahas wrote:
: On Wed, May 04, 2005 at 11:44:58PM -0700, Larry Wall wrote:
:  : How do I open a file named -?
:  
:  Um, depending on what you mean, and whether we continue to support
:  the '=' pseudofile, maybe:
:  
:  $fh = io(-);
:  $fh = open -;
:  $fh = $name eq '-' ?? $*IN :: open $name;
: 
: My concern is again with magic control. I've no gripes with the first
: or last of those, but I think the second should not be allowed by
: default. There has to be a safe mode for opening a file and knowing
: that's what you're opening: not a pipe, not stdio (hence there are places
: I can't permit myself to use #1). But as your third example suggests,
: never allowing open - will make unixish tools tedious to write, so
: maybe we need something like
: 
: getopt(...);
: $fh = open $in, :allowstdio;
: 
: (only named more eloquently).

I think that, as with various other parts of Perl 6, we can try
to sweep all the dwimmery into one spot so that it can be easily
recognized and/or avoided.  And the default open is not the place
for dwimmery.  It should just open an ordinary file by default.
The place for all that dwimmery is probably io().  In contrast, open
should be a multisub/method that gives you exact semantics depending
on the invocant.  In fact, io() might just be short for IO.open(),
which specifically requests dwimmery, just as URI.open() specifically
requests URI interpretation.  And bare open() is probably short for
File.open().  (Though for io(), it's probable that it actually does the
open lazily depending on usage, since that's part of its dwimmery.)

Larry


Re: When scoping

2005-05-05 Thread David Wheeler
On May 4, 2005, at 23:19 , Larry Wall wrote:
You must have missed the implied ... at the end of my list of  
other WTDI.
You can also do any of:

say Two if /hello/;
/hello/  say Two;
/hello/ and say Two;
/hello/ ?? say Two :: leave;
infix:and(/hello/, { say Two })
continue unless /hello/; say Two;
/hello { say Two }/;
s/hello/{ say Two }$0/;
({}, { say Two })[?/hello/]();
and probably a few more I can't think of off the top of my head.
Okay then, pay no attention to my piddling contribution of a single  
example. :-)

Best,
David

smime.p7s
Description: S/MIME cryptographic signature


Declaration and definition of state() vars

2005-05-05 Thread Ingo Blechschmidt
Hi,

  sub gen() {
state $svar = 42;
# Only initialized once, as it is (per S04) equivalent to
#   state $svar will first{ 42 };
return { $svar++ };
  }

  my $a = gen();# $svar == 42
  $a(); $a();   # $svar == 44
  my $b = gen();# $svar == 44
  say $b(); # 44
# $svar == 45

I presume that's correct. Is the following correct, too?

  sub gen() {
(state $svar) = 42;
# Initialized on each invocation of gen, as it is equivalent to
#   (state $svar will first{ undef }) = 42;
# I.e. $svar is only set to undef once (as $svar is a state
# variable), but it is set to 42 each time gen is called. Correct?
return { $svar++ };
  }

  my $a = gen();# $svar == 42
  $a(); $a();   # $svar == 44
  my $b = gen();# $svar == 42
  say $b(); # 42
# $svar == 43


--Ingo

-- 
Linux, the choice of a GNU | Mathematicians practice absolute freedom.
generation on a dual AMD   | -- Henry Adams  
Athlon!|



Re: Declaration and definition of state() vars

2005-05-05 Thread Larry Wall
On Thu, May 05, 2005 at 07:50:31PM +0200, Ingo Blechschmidt wrote:
: Hi,
: 
:   sub gen() {
: state $svar = 42;
: # Only initialized once, as it is (per S04) equivalent to
: #   state $svar will first{ 42 };
: return { $svar++ };
:   }
: 
:   my $a = gen();# $svar == 42
:   $a(); $a();   # $svar == 44
:   my $b = gen();# $svar == 44
:   say $b(); # 44
: # $svar == 45
: 
: I presume that's correct.

Yes.  Though I'm not quite sure if we've nailed down whether the will
form will auto-assign or would instead have to be written

state $svar will first { $_ = 42 }

I think the latter is probably correct.  However, you should be able
to write the non-closure form to auto-assign in any event:

state $svar is first(42)

: Is the following correct, too?
: 
:   sub gen() {
: (state $svar) = 42;
: # Initialized on each invocation of gen, as it is equivalent to
: #   (state $svar will first{ undef }) = 42;
: # I.e. $svar is only set to undef once (as $svar is a state
: # variable), but it is set to 42 each time gen is called. Correct?
: return { $svar++ };
:   }
: 
:   my $a = gen();# $svar == 42
:   $a(); $a();   # $svar == 44
:   my $b = gen();# $svar == 42
:   say $b(); # 42
: # $svar == 43

Depends on whether assignment to a state variable is recognized in
syntactic analysis (where parens count) or semantic analysis (where they
don't).  You're taking the syntactic approach.  It can be argued that
the semantic approach is more robust, insofar as it makes all of
these equivalent:

state $a = 1; state $b = 2;
state ($a,$b) = (1,2);
(state $a, state $b) = (1,2);

just as

my $a = 1; my $b = 2;
my ($a,$b) = (1,2);
(my $a, my $b) = (1,2);

should all be equivalent.  On the other hand, don't ask me when

(my $a, state $b) = (1,2);

should evaluate its RHS.  The semantic analyzer should probably throw
up its hands in disgust if it sees conflicting requirements for =.

Or we could make assignment policy depend on the outside of the parens
as you're doing.  In that case

my ($a, state $b) = (1,2);

might initialize $b every time, while

state ($a, my $b) = (1,2);

would only initialize $b the first time.  Hmm, then you could write

state (my $first) = 1;

and $first would be true only the first time though.  Not sure if that's
terribly useful.  On the other hand,

state (our $x) = 1;

would have the same effect as

our $x is first(1);

That isn't terribly useful, but I think, for simplicity of analysis,
let's go ahead with your approach and just make the assignment timing
depend only on the declarator outside the parens.

So, yes.

Larry


Re: reduce metaoperator

2005-05-05 Thread John Williams
On Wed, 4 May 2005, Larry Wall wrote:
 It would be nice to have an easy-to-access What's this? interface
 that could be stitched into your favorite editor to identify what's
 under the cursor, or at least a command like:

 p6explain '[+]'

That would make me extremely happy.

 :$sum = [+] @array;   # meta operator

Another random thought which came to me (right after \\+ could be
mnemonic for return a function ref for this operator) was this:

How does [+] know you mean

   reduce infix:+, @array;

instead of

   reduce prefix:+, @array;

which is nonsense, but the [+] is in a prefix position.

With the hyper metaoperator, the real operator is always in the place
where it would normally be parsed.  But this metaoperator pulls the real
operator out of its usual pre/in/post position.

I suppose users will need to know the answer when they start trying to
write their own metaoperators.

Maybe the metaoperator's function signature resolves that somehow?
But I haven't been following the function signature thread closely.

I can see how to ask for a binary (hence infix) operator, but how do I ask
for a prefix or postfix operator specifically, which + and + do?
Maybe there are Operator::Prefix, etc, roles defined so you can ask for
them?

~ John Williams


A06 typo:

infix:+( prefix:-($a), $b)

 [Update: That's now

infix:+( prefix:-($a), $b)

 .]

The correction only corrected one of the errors:

   infix:+( prefix:-($a), $b)







Re: reduce metaoperator

2005-05-05 Thread David Wheeler
On May 5, 2005, at 11:28 , John Williams wrote:
How does [+] know you mean
   reduce infix:+, @array;
instead of
   reduce prefix:+, @array;
which is nonsense, but the [+] is in a prefix position.
Because [] applies only to infix operators, as I understand it.
With the hyper metaoperator, the real operator is always in the place
where it would normally be parsed.  But this metaoperator pulls the  
real
operator out of its usual pre/in/post position.
Well, if it was in its place, you wouldn't need to reduce it, would you?
I suppose users will need to know the answer when they start trying to
write their own metaoperators.
They should write them only for infix operators.
I can see how to ask for a binary (hence infix) operator, but how  
do I ask
for a prefix or postfix operator specifically, which + and + do?
Maybe there are Operator::Prefix, etc, roles defined so you can ask  
for
them?
Ask for them for what?
Regards,
David

smime.p7s
Description: S/MIME cryptographic signature


Re: reduce metaoperator

2005-05-05 Thread John Williams
On Thu, 5 May 2005, David Wheeler wrote:

  I can see how to ask for a binary (hence infix) operator, but how
  do I ask
  for a prefix or postfix operator specifically, which + and + do?
  Maybe there are Operator::Prefix, etc, roles defined so you can ask
  for
  them?

 Ask for them for what?

For negating all elements of an array:

 @negatives = -« @positives;

 They should write them [metaoperators] only for infix operators.

The above example is in S03, so that is not an option.

 Because [] applies only to infix operators, as I understand it.

You understand it.  I understand it.  But how does the parser know the
difference between

@x = - @y;

and

@x = [+] @y;

or even

@x -= @y;

which shows that the position of metaoperator is not the distinguishing
factor.




Semi-related question: reduce metaoperator

2005-05-05 Thread Rob Kinyon
Can I put an operator in a variable and then use it in the []
reduce meta-operator? Something like:

$op = '+';
$x = [$op] @x;

Rob


Re: stdio

2005-05-05 Thread Aaron Sherman
On Thu, 2005-05-05 at 12:31, Larry Wall wrote:
 On Thu, May 05, 2005 at 10:14:34AM +0300, Gaal Yahas wrote:
 : On Wed, May 04, 2005 at 11:44:58PM -0700, Larry Wall wrote:
 :  : How do I open a file named -?
[...]
 :  $fh = io(-);
 :  $fh = open -;

 : My concern is again with magic control. I've no gripes with the first
 : or last of those, but I think the second should not be allowed by
 : default.

 I think that, as with various other parts of Perl 6, we can try
 to sweep all the dwimmery into one spot so that it can be easily
 recognized and/or avoided.  And the default open is not the place
 for dwimmery.

I've been thinking about this particular thing ever since I wrote
File::Copy, and wanted it to accept filenames, magical file-like strings
or filehandles. Of course, that problem is easy in P6, but as I've been
thinking about my dream IO type system in Perl for so long, I have a few
opinions on it ;-)

Dash this all on the rocks if you want, but understand that this is not
an off-the-cuff reply, but something that I've spent a lot of time
mulling over, and I really think Perl 6 programmers everywhere would
enjoy such functionality. I'll even go so far as to offer to write it
once Pugs is in a state that allows for such.

First off, IMHO, open should be an alias for a closure-wrapped
constructor, like so:

sub open := IO.new;

Pardon me if sub isn't the right tool there, I'm really not sure. The
point there is to make open have the same signature(s) as the
constructor(s) for IO. This allows you to instantly introduce every
variant of open you'll ever want. This makes open the maximally
dwimish operator. You can always introduce a sysopen and stdiopen
and sockopen, etc. if you want domain-specific behavior exclusively
(e.g. treat everything as a filename only, or as a host:port only, etc).

Next, we need IO to be capable of understanding not only polymorphism:

sub File::Copy::copy(IO $file1, IO $file2) {...}
File::Copy::copy(IO::File.new($path1,:moderead),
IO::File.new($path2,:modewrite));

but we also wish to be able to say:

File::Copy::copy(IO.new(-),IO.new(-));

and perhaps even

File::Copy::copy(-,-);

and have the right thing happen (right thing not always being a
universal for every program). How can we do this? Well, first IO has to
accept a string for the constructor:

class IO is ParrotIO { # ParrotIO? not sure ...
method new(Str $string) {...}
}

I will assume that we upgrade types based on constructor signatures by
constructing a temporary, though I honestly don't recall that being said
explicitly in A12.

That's all well and good, but how does IO know about its children? They
might not even be loaded yet. You could just assume that any string
constructor is either an IO::Handle (if it's -), an IO::Pipe (if it's
|), or an IO::File otherwise, but that's a bit restrictive. What if we
decide we want URIs to be readable things? It would be nice to be able
to mix that in.

Sure enough, there's an easy way:

class IO is ParrotIO does RegisteredStringConstructor {...}
role RegisteredStringConstructor {
has %:registry;
sub register(Any $pattern, Type $type) {
%:registry{$pattern} = $type;
}
multi method new(Str $string,*%rest) {
for %:registry.keys - $pat {
if $string ~~ $pat {
return 
%:registry{$pat}.bless(:string($string),*%rest);
}
}
}
}

Now, IO::URI can say:

class IO::URI is IO {
use URI;
IO.register(rx{^ URI::ProtocolScheme :}, ::IO::URI);
...
}

and then you can:

my $fh = open(gnomevfs:spreadsheet:/home/me/sheet.gnumeric,:r);
while =$fh - $row {
say $row[0];
}

Of course, my example URI brings up a host of questions, and probably is
incorrect gnomevfs syntax, but you get the idea.

Optional export features of IO::* could allow:

  * pipeline command execution
  * thread and/or process coupling
  * handle duping
  * much more

Thus, you would control these features like so:

use IO;
use IO::Funky :register_string_open_funkiness;
open(funk,:w);

Now, if someone can just figure out how to re-write the string
registration so that it behaves itself (that is, unregisters when the
use goes out of scope), I think it would be perfect.

-- 
Aaron Sherman [EMAIL PROTECTED]
Senior Systems Engineer and Toolsmith
It's the sound of a satellite saying, 'get me down!' -Shriekback




Re: reduce metaoperator

2005-05-05 Thread John Williams
On Thu, 5 May 2005, John Williams wrote:
 or even

 @x -= @y;

Doh!  That should be C $x -= $y;  of course.



adverbial blocks: description and examples requested

2005-05-05 Thread Terrence Brannon
I was looking at a line in the hangman program:

  @letters == @solution.grep:{ $_ ne '' }; 

and was told that I was looking at an adverbial block.

But I don't understand what that is and could not find a description
and examples in a reverse search on dev and nntp.perl.org.

I would appreciate any information on this topic.

Thanks




Re: adverbial blocks: description and examples requested

2005-05-05 Thread Luke Palmer
Ugh, hit a in gmail when replying!

On 5/5/05, Terrence Brannon [EMAIL PROTECTED] wrote:
 I was looking at a line in the hangman program:

   @letters == @solution.grep:{ $_ ne '' };

 and was told that I was looking at an adverbial block.

The adverbial block is what you're giving to `if` when you say:

if $foo { ... }

On the statement level, it looks like a block in operator position.
However, on the expression level, it is preceded by a colon, and goes
into the * argument of the sub.

sub grep (*block, [EMAIL PROTECTED]) {...}

(I don't know about the ordering of those arguments)

It was invented to avert the annoying ({ }) construct, especially when
used in a series:

@result = @input.grep:{...}.map:{...}

Did that answer your question?

Luke


Re: adverbial blocks: description and examples requested

2005-05-05 Thread Terrence Brannon
Luke Palmer [EMAIL PROTECTED] writes:

 Ugh, hit a in gmail when replying!

 On 5/5/05, Terrence Brannon [EMAIL PROTECTED] wrote:
 I was looking at a line in the hangman program:

   @letters == @solution.grep:{ $_ ne '' };

 and was told that I was looking at an adverbial block.

 The adverbial block is what you're giving to `if` when you say:

 if $foo { ... }

It is? An adverb describes a verb. What is the verb here?

 On the statement level, it looks like a block in operator position.

On statement level... hmmm. Statement I think I understand: a complete
sentence made up of expressions. operator position - how am I to
know where operator position is?

I'm really just asking these two questions about statement level and
operator position so that you will be aware that not everyone will
understand what you mean by these terms and you might want to explain
them fully before using them when you write a Perl 6 tutorial/book/
etc.

Don't bother explaining them to me. I can figure out what I need
without knowing what you meant here.

  However, on the expression level, it is preceded by a colon, and goes
 into the * argument of the sub.

 sub grep (*block, [EMAIL PROTECTED]) {...}

why must block be slurpy? can't it be specified as a required
parameter like so:

sub grep (block, [EMAIL PROTECTED]) {...}


 (I don't know about the ordering of those arguments)

 It was invented to avert the annoying ({ }) construct, especially when
 used in a series:

 @result = @input.grep:{...}.map:{...}

So the annoying way to write this would be this?

@result = map {   } (grep { } @input) ;

where the parentheses are required?

So what are the colon-free ways to write this, which is not in series:

sub has_won returns Bool { 
@letters == @solution.grep:{ $_ ne '' }; 
} 



 Did that answer your question?

yes, to a large extent and way way faster than anticipated!

 
 Luke

-- 
Carter's Compass: I know I'm on the right track when,
   by deleting something, I'm adding functionality.



Re: reduce metaoperator

2005-05-05 Thread Stuart Cook
If I understand correctly, so far we have the following meta-operators:

[ ]
circumfix meta-operator on infix operator which produces a prefix operator

 
circumfix meta-operator on infix operator which produces an infix operator

=
postfix meta-operator on infix operator which produces an infix operator


prefix meta-operator on postfix operator which produces a postfix operator


postfix meta-operator on prefix operator which produces a prefix operator

In other words:
+-+---+-++
| Meta-op | is| operates on | to produce |
+-+---+-++
| [ ] | circumfix | infix   | prefix |
+-+---+-++
| | circumfix | infix   | infix  |
+-+---+-++
| =   | postfix   | infix   | infix  |
+-+---+-++
|   | prefix| postfix | postfix|
+-+---+-++
|   | postfix   | prefix  | prefix |
+-+---+-++

From this table, we can see that [ ] is the only meta-operator that
produces a different 'type' of operator from that which it accepts,
which might be where the confusion lies. As long as each meta-operator
explicitly knows what type of regular operator it accepts (and
produces), there shouldn't be any problems with ambiguity.


Re: reduce metaoperator

2005-05-05 Thread Brent 'Dax' Royal-Gordon
On 5/5/05, Stuart Cook [EMAIL PROTECTED] wrote:
 +-+---+-++
 | Meta-op | is| operates on | to produce |
 +-+---+-++
 | [ ] | circumfix | infix   | prefix |
 +-+---+-++
 | | circumfix | infix   | infix  |
 +-+---+-++
 | =   | postfix   | infix   | infix  |
 +-+---+-++
 |   | prefix| postfix | postfix|
 +-+---+-++
 |   | postfix   | prefix  | prefix |
 +-+---+-++

I find this table very interesting, in that it shows the fundamental
difference between reduce and the existing meta-ops.

The existing meta-operators alter the semantics of the opoerator, but
don't really change its syntax; a unary operator is still unary, a
binary operator is still binary, and so on.  Reduce is irreducibly
(pardon the pun) different, in that it alters the syntax as well as
the semantics.

My suggestion is simple:

multi *reduce(block, [EMAIL PROTECTED] is copy) {
my [EMAIL PROTECTED];
while(@list) {
$r = block($r, [EMAIL PROTECTED]( :elems(block.arity - 1) );
}
return $r;
}
macro *reduce ($op, $expr) is parsed( / \[ (infix_operator) \] 
(expr)/ ) {
# Would be reworked to produce a parse tree
return reduce(infix:$op, $expr);
}

That would result in the following syntaxes:

reduce { $^a / $^b } @foo;
reduce [/] @foo;

   $sum = reduce[+] @array;
   $fact = reduce[*] 1..$num;
   $firsttrue = reduce[||] @args;
   $firstdef = reduce[//] @args;
   @sumrows := reduce[+«] @rows;
   @foo[0..9; reduce[;](@dims); 0..9]

Clearly we could squabble about the exact bracketing operators to use
(I chose square brackets because I thought they'd be less ambiguous
than parentheses or curlies), but I trust you get the idea.

I agree that reduce is very useful, and I even agree that it should be
in core, but it's not *so* useful that it needs to be invokable
without a keyword.  Summing a list--which, let's face it, is likely to
be the most common use for this--isn't common enough an operation to
need such a compact syntax; I can think of more useful meta-ops, like
one that tags each result with the operands that created it, allowing
junctions to be used for the stuff people currently complain they
can't be.

multi sub *infixmetaop:[ ] ( $lhs, $rhs ) {
return call but operands($lhs, $rhs);
}

-- 
Brent 'Dax' Royal-Gordon [EMAIL PROTECTED]
Perl and Parrot hacker


Re: reduce metaoperator

2005-05-05 Thread Stuart Cook
On 5/6/05, Brent 'Dax' Royal-Gordon [EMAIL PROTECTED] wrote:
 I find this table very interesting, in that it shows the fundamental
 difference between reduce and the existing meta-ops.

Yep, that was basically the whole point of the table.

 The existing meta-operators alter the semantics of the opoerator, but
 don't really change its syntax; a unary operator is still unary, a
 binary operator is still binary, and so on.  Reduce is irreducibly
 (pardon the pun) different, in that it alters the syntax as well as
 the semantics.

I was thinking of restricting the ways in which meta-ops can alter the
syntax of an op, but now I think we're better off not letting it
happen at all. Meta-ops that redefine syntax would be very hairy for
the compiler (as I pointed out), and probably wouldn't buy us much
that you couldn't achieve with a macro anyway.

 That would result in the following syntaxes:
 
 reduce { $^a / $^b } @foo;
 reduce [/] @foo;
 
$sum = reduce[+] @array;
$fact = reduce[*] 1..$num;
$firsttrue = reduce[||] @args;
$firstdef = reduce[//] @args;
@sumrows := reduce[+«] @rows;
@foo[0..9; reduce[;](@dims); 0..9]

I personally like that, and it has the additional property of avoiding
the [+] @foo vs. [+1, -2] ambiguity I pointed out.

Furthermore, it makes it /much/ easier for newbies to figure out what
that code actually does (since they can just grep for 'reduce' in the
docs).


Stuart


Re: adverbial blocks: description and examples requested

2005-05-05 Thread Ashley Winters
On 5/5/05, Terrence Brannon [EMAIL PROTECTED] wrote:
 I was looking at a line in the hangman program:
 
   @letters == @solution.grep:{ $_ ne '' };
 
 and was told that I was looking at an adverbial block.
 
 But I don't understand what that is and could not find a description
 and examples in a reverse search on dev and nntp.perl.org.

Methods with arguments require parens. However, the block to grep
isn't Ireally an argument. It's describing the manner in which the
array will be grepped... that's an adverb to grep.

So, why are the parens required on methods? Take the following if statements:

if @foo.shift { ... }

if @foo.grep { ... }   # grep doesn't get the block

To make things clear, methods without parens are assumed to take no
arguments. In order to pass a block to the above grep, you either need
to use @foo.grep({ $^a = $^b}) or the adverbial colon:

if @foo.grep:{$^a = $^b} { ... }

Ashley Winters