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

could 'given' blocks have a return value?

5 views
Skip to first unread message

Mark Stosberg

unread,
Aug 30, 2006, 12:18:52 AM8/30/06
to perl6-l...@perl.org

Sometimes I use 'given' blocks to set a value. To save repeating myself
on the right hand side of the given block, I found I kept want to do this:

my $foo = given { }

...and have whatever value that was returned from when {} or default {}
populate $foo.

It turns out pugs already allow this, through the trick of wrapping the
given block in an anonymoose sub...which is then immediately executed:

my $rm = sub { given $rm_param {
when Code { $rm_param(self) }
when Hash { %rm_param<run_mode> }
default { self.query.param($rm_param) }
}}();

Not only do you get implicit matching on the left side, you get implicit
return values on the right!

I'd just like to be able to clean that up a little to:

my $rm = given $rm_param {
when Code { $rm_param(self) }
when Hash { %rm_param<run_mode> }
default { self.query.param($rm_param) }
};

Mark

Jonathan Lang

unread,
Aug 30, 2006, 1:04:56 AM8/30/06
to Mark Stosberg, perl6-l...@perl.org
Mark Stosberg wrote:
>
> Sometimes I use 'given' blocks to set a value. To save repeating myself
> on the right hand side of the given block, I found I kept want to do this:
>
> my $foo = given { }
>
> ...and have whatever value that was returned from when {} or default {}
> populate $foo.

Isn't it still the case that the last expression evaluated within a
closure is returned by the closure? And isn't a given block just a
fancy kind of closure?

The question is whether or not a code block can be used where the
parser expects an expression; for instance, could one say:

my $foo = if condition {"BAR"} else {"BAZ"};

?

I'm no expert, but it occurs to me that allowing this could be a
parsing nightmare.

ISTR a programming construct along the lines of "eval" that is
effectively shorthand for "sub { ... }()".

> It turns out pugs already allow this, through the trick of wrapping the
> given block in an anonymoose sub...which is then immediately executed:
>
> my $rm = sub { given $rm_param {
> when Code { $rm_param(self) }
> when Hash { %rm_param<run_mode> }
> default { self.query.param($rm_param) }
> }}();
>
> Not only do you get implicit matching on the left side, you get implicit
> return values on the right!
>
> I'd just like to be able to clean that up a little to:
>
> my $rm = given $rm_param {
> when Code { $rm_param(self) }
> when Hash { %rm_param<run_mode> }
> default { self.query.param($rm_param) }
> };

So what happens if you forget to include a default in the given?

--
Jonathan "Dataweaver" Lang

Agent Zhang

unread,
Aug 30, 2006, 1:17:11 AM8/30/06
to Mark Stosberg, perl6-l...@perl.org
On 8/30/06, Mark Stosberg <ma...@summersault.com> wrote:
>
> Sometimes I use 'given' blocks to set a value. To save repeating myself
> on the right hand side of the given block, I found I kept want to do this:
>
> my $foo = given { }
>

According to S04, given {} is at statement level, so you can't use it
directly as an expression. But Perl 6 always allow you to say

my $foo = do given {...}

As well as

my $foo = do if foo {...} else {...}

>
> my $rm = sub { given $rm_param {
> when Code { $rm_param(self) }
> when Hash { %rm_param<run_mode> }
> default { self.query.param($rm_param) }
> }}();
>

Apparently ``do'' is a simplified version for this. :)

Cheers,
Agent

Trey Harris

unread,
Aug 30, 2006, 7:11:27 AM8/30/06
to Mark Stosberg, perl6-l...@perl.org
In a message dated Tue, 29 Aug 2006, Mark Stosberg writes:
> my $rm = sub { given $rm_param {
> when Code { $rm_param(self) }
> when Hash { %rm_param<run_mode> }
> default { self.query.param($rm_param) }
> }}();

This is eerily like Contextual::Return, which made me wonder if it's even
required in Perl 6.

Obviously we can do

return do given want {
when :($) { ... }
...
};

But "return do given want" flows so badly, I desperately want some sugar
for this. Is there some and I missed it?

Trey

Mark Stosberg

unread,
Aug 30, 2006, 9:27:39 AM8/30/06
to perl6-l...@perl.org
Agent Zhang wrote:

>
> According to S04, given {} is at statement level, so you can't use it
> directly as an expression. But Perl 6 always allow you to say
>
> my $foo = do given {...}
>
> As well as
>
> my $foo = do if foo {...} else {...}

I confirmed this both work now with pugs!

I think the 'do given' case is useful enough to document
more officially along with 'given'.

If you are thinking about the if/else case, ?? ... !! would be a
simpler way to write it.

Mark

Damian Conway

unread,
Aug 30, 2006, 7:08:06 PM8/30/06
to perl6-l...@perl.org
Trey Harris asked:


> This is eerily like Contextual::Return, which made me wonder if it's
> even required in Perl 6.
>
> Obviously we can do
>
> return do given want {
> when :($) { ... }
> ...
> };
>
> But "return do given want" flows so badly, I desperately want some sugar
> for this. Is there some and I missed it?

No, the sugariest you'll find at the moment is probably:

return want.rw ?? $lvalue
:: want.count == 2 ?? (7,11)
:: want.item ?? 42
:: want.list ?? 1..10
:: die "Bad context;


but that still doesn't have the Awesome Power of C::R. ;-)

The simple answer is that C::R is probably the first module I will port to
Perl 6 (since it's the module I find myself using the most nowadays). The Perl
6 version will be cleaner and more efficient that the Perl 5 version, since
I'll be able to take advantage of macros.

Damian

Juerd

unread,
Aug 31, 2006, 4:33:21 AM8/31/06
to perl6-l...@perl.org
Damian Conway skribis 2006-08-31 9:08 (+1000):

> return want.rw ?? $lvalue
> :: want.count == 2 ?? (7,11)
> :: want.item ?? 42
> :: want.list ?? 1..10
> :: die "Bad context;

s:g/::/!!/ # :)


Juerd
--
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html
http://convolution.nl/gajigu_juerd_n.html

0 new messages