Piers Cawley writes:
: Also known as constructs you wish you hadn't discovered.
:
: So, I'm reading through Finkel and I came across the following, which
: computes the greatest common divisor of a and b (recast into perl6ish
: syntax)
:
: while {
: when $a < $b { $b -= $a }
: when $b < $a { $a -= $b }
: }
:
: The idea is that the loop keeps on looping until none of the guard
: conditions match. This can be redone in 'real' Perl 6 as
:
: while 1 {
: given 1 {
: when $a < $b { $b -= $a }
: when $b < $a { $a -= $b }
: else { last }
: }
: }
Well, it's "default", not "else", but it's redundant in any case, since
the C<when>s would fall through.
: I'm not sure about the 'break'ing behaviour of a C<when> that isn't in
: a C<given> block so I've introduced a 'dummy' one here. Maybe Larry
: can clarify.
Could be written:
loop {
when $a < $b { $b -= $a; next }
when $b < $a { $a -= $b; next }
last;
}
A C<when> that is a boolean doesn't reference a given. It'd be nice to
get rid of the C<next>, but C<loop> isn't naturally a topicalizer.
Could say:
for 0..Inf {
when $a < $b { $b -= $a }
when $b < $a { $a -= $b }
last;
}
The optimizer might well pick up that $_ is unreferenced and optimize
the 0..Inf away. Still, the first way looks cleaner to me.
: So, do we want this monstrosity? I confess that I did find myself
: using something like it occasionally when I was working on the scheme
: evaluator, but it looks very weird indeed.
Depending on whether we define -> as the "topicalizing arrow", we might
be able to go as far as
loop -> {
when $a < $b { $b -= $a }
when $b < $a { $a -= $b }
last;
}
That makes C<given> and C<for> special cases, in that they default to
C<< -> $_ >> when you don't supply the topic arrow. Defining ->
this way has the additional advantage of providing a clean way
to say "there is no topic for this closure". I believe the apo had
given () { ... }
but this way we could have
given -> { ... }
and guarantee that all the tests are boolean. Plus -> could be used
anywhere else that made sense to hang an argumentless block.
It could be argued that bare
-> { ... }
should default to
-> $_ { ... }
but I think the fact that C<for> and C<given> already default to $_
makes that not so important. Plus we'd have to write something like
-> () { ... }
to mean argumentless, and that's not so nice. So I think a bare topic
arrow means topicless. (Careful how you say that.)
Anyway, much of the time you want a topic, you'd want to write
-> $_ is rw { ... }
In fact, that's what C<for> and C<given> actually default to, I think.
Larry