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

'catch' statement modifier

5 views
Skip to first unread message

Luke Palmer

unread,
Nov 23, 2003, 1:55:20 PM11/23/03
to Language List
I was reading over some code that used the MIDI module, and saw the
C<write_to_file> method. I began wondering, how does one report the
error if he feels like it, but let the module report the error if not,
in a concise way.

What about something along the lines of a C<catch> statement modifier,
like:

$opus.write_to_file($file) catch die "Couldn't write to $file: $!\n";

Which would be equivalent to:

try {
$opus.write_to_file($file);
CATCH {
die "Couldn't write to $file: $!"
}
}

It doesn't read quite as nicely as I'd like, but I think it could be a
very useful notation. After all, if I have to type a lot when I'm
handling errors, I'll prefer not to handle them at all.

Which reminds me, if you throw an exception inside a CATCH block, does
it propogate outside to be caught by other CATCHes in the same block
that are lexically lower, or does it propogate outside of the enclosing
scope. That might be a little confusing... for example:

try {
try {
do_something(); # Throws
CATCH { die "Foo" }
CATCH { die "Bar" }
}
CATCH { print "$!" }
}

Does that print Foo or Bar?

Luke

Tony Olekshy

unread,
Nov 23, 2003, 2:19:10 PM11/23/03
to Luke Palmer, Language List
Luke ~

These matters are covered at some length in RFC 88 and Apocalypse 4.

http://www.avrasoft.com/perl6/rfc88.htm

http://www.perl.com/pub/a/2002/01/15/apo4.html

Yours, &c, Tony Olekshy

Damian Conway

unread,
Nov 23, 2003, 3:24:21 PM11/23/03
to Luke Palmer, perl6-l...@perl.org
> I was reading over some code that used the MIDI module, and saw the
> C<write_to_file> method. I began wondering, how does one report the
> error if he feels like it, but let the module report the error if not,
> in a concise way.
>
> What about something along the lines of a C<catch> statement modifier,
> like:
>
> $opus.write_to_file($file) catch die "Couldn't write to $file: $!\n";

Remember that a C<try> without a C<CATCH> catches all exceptions and returns
C<undef> (the same as a Perl 5 C<eval> block does).

So you just want:

try { $opus.write_to_file($file) }
err die "Couldn't write to $file: $!\n";

Damian

Austin Hastings

unread,
Nov 23, 2003, 3:53:00 PM11/23/03
to Damian Conway, perl6-l...@perl.org

> -----Original Message-----
> From: Damian Conway [mailto:dam...@conway.org]
>
> Remember that a C<try> without a C<CATCH> catches all exceptions
> and returns
> C<undef> (the same as a Perl 5 C<eval> block does).
>
> So you just want:
>
> try { $opus.write_to_file($file) }
> err die "Couldn't write to $file: $!\n";

Is that C<err die> or C<or die> ?

And if so, what's C<err> and where can I find more on it?

=Austin

Damian Conway

unread,
Nov 23, 2003, 3:59:50 PM11/23/03
to Austin_...@yahoo.com, perl6-l...@perl.org
Austin Hastings wrote:

>> try { $opus.write_to_file($file) }
>> err die "Couldn't write to $file: $!\n";
>
> Is that C<err die> or C<or die> ?

It's C<err>, which is low precedence C<//>.


> And if so, what's C<err> and where can I find more on it?

http://dev.perl.org/perl6/exegesis/E04.html#Read_or_Die

Damian

Damian Conway

unread,
Nov 23, 2003, 4:13:53 PM11/23/03
to perl6-l...@perl.org
Hmmmmmm. I think I may have missed Luke's point. Which was (presumably):
what if C<$opus.write_to_file($file);> validly returns C<undef>?

In which case I think we just fall back to:

try{$opus.write_to_file($file); CATCH {die "Couldn't write to $file: $!"}}

which is, after all, only 5 characters longer than:

$opus.write_to_file($file) catch die "Couldn't write to $file: $!\n";

;-)

Damian


Jonathan Scott Duff

unread,
Nov 23, 2003, 3:52:17 PM11/23/03
to Austin Hastings, Damian Conway, perl6-l...@perl.org

Exegesis 4 ...

In Apocalypse 3, Larry introduced the // operator, which is
like a || that tests its left operand for definedness rather
than truth.

What he didn't mention (but which you probably guessed) was that
there is also the low-precedence version of //. Its name is err:

Operation High Precedence Low Precedence

INCLUSIVE OR || or
EXCLUSIVE OR ~~ xor
DEFINED OR // err

This is in the "Read or Die" section of E4 if you want to read more.

-Scott
--
Jonathan Scott Duff
du...@lighthouse.tamucc.edu

Luke Palmer

unread,
Nov 24, 2003, 6:28:50 PM11/24/03
to Damian Conway, perl6-l...@perl.org

Fair enough :-)

No, I wasn't implying that C<write_to_file> could validly return undef.
I just failed to realize how short the "long" version was.

But you have to admit, the latter version makes the important part of
the expression stand out, and is more natural to write (IMHO, as
always).

But it's moduleable, so I won't worry about it.

Luke

> Damian
>
>

Michael Lazzaro

unread,
Nov 26, 2003, 2:39:41 PM11/26/03
to perl6-l...@perl.org
On Monday, November 24, 2003, at 03:28 PM, Luke Palmer wrote:

> Damian Conway writes:
>> In which case I think we just fall back to:
>>
>> try{$opus.write_to_file($file); CATCH {die "Couldn't write to
>> $file:
>> $!"}}
>>
>> which is, after all, only 5 characters longer than:
>>
>> $opus.write_to_file($file) catch die "Couldn't write to $file:
>> $!\n";
>>
>> ;-)
>
> Fair enough :-)
>
> No, I wasn't implying that C<write_to_file> could validly return undef.
> I just failed to realize how short the "long" version was.
>
> But you have to admit, the latter version makes the important part of
> the expression stand out, and is more natural to write (IMHO, as
> always).
>
> But it's moduleable, so I won't worry about it.


A small point of order, philosophically...

While there is a justifiable urge to deny entry into of the core
language of as much syntactic sugar as possible -- since merely looking
at the operator list proves P6 will be a behemoth of a language, when
you consider all of its nooks and crannies -- I think we also need to
be skeptical of the false economy of putting such sugar into CP6AN, if
a sizable portion of the community is going to download it anyway.

In my mind, Luke's proposed C<catch> modifier quite easily fits the
qualifications of something that should be in core, for the following
reasons:

- It serves a common purpose, for which there is Only One (Good) Way To
Do It. While you perhaps _can_ say

try {
$opus.write_to_file($file);
CATCH {
die "Couldn't write to $file: $!"
}
}

in other golfish ways, the above is clearly (ignoring preferences in
whitespace formatting) the Obvious and Recommended way to do it, and so
the above phrase will appear _wherever_ a single statement needs to be
wrapped with a try/CATCH.

- It has one, and only one, obvious meaning. Nobody should be making
their own 'catch' modifiers that do different things -- that would be
far more annoying, for shared code, than reserving the keyword in
advance to do the One Obvious Thing.

- It is consistent with the philosophy of similar syntax.

- It poses no significant harm to novice users. They can program in P6
effectively without ever using it, but if they do see it in someone
else's code, it will be reasonably obvious what it is doing. And
whether it is core or commonly used CP6AN, they _will_ see it in other
people's code.


It is true, the difference between the two constructs:

try { $opus.write_to_file($file); CATCH {die "Couldn't write to
$file: $!"} }

$opus.write_to_file($file) catch die "Couldn't write to $file: $!";

is only 7 characters. But four of those characters are curly brackets,
visually introducing two blocks. That's kind of a yuck.

MikeL

Chromatic

unread,
Nov 26, 2003, 3:13:39 PM11/26/03
to perl6-l...@perl.org
On Wed, 2003-11-26 at 11:39, Michael Lazzaro wrote:

> I think we also need to be skeptical of the false economy of putting
> such sugar into CP6AN, if a sizable portion of the community is going
> to download it anyway.

A more interesting question is *when* to put something into the core
language or libraries.

Consider Perl 5, where File::Find is a core module. While the interface
may have been nice in 1995 (though I doubt even that), it's been widely
regarded as awful for at least three years. It's likely never to be
removed from the core. File::Find::Rule is immensely nicer.

Good luck convincing a pumpking to replace File::Find with
File::Find::Rule. For that even to be considered, File::Find::Rule will
likely need a backwards compatible interface. Good luck convincing
someone to write it.

Every module or idiom entrenched in the core in Perl 6 will likely stay
there until Perl 7, unless it's an exceedingly bad idea such as 5.005
threads or pseudohashes. Unfortunately, there are a lot of quite bad
ideas entrenched in Perl 5 that cannot be removed.

While it may be true that this or that construct is clearly the best way
to do something, it's worth asking that the idea prove itself in the
wild world outside the core for a while *unless it absolutely positively
cannot be done without core support*. Good ideas can be added in future
versions.

Improving module and code installation is one part of that puzzle.
Allowing local grammar redefinitions and macro support is another. In
my mind, that relieves a lot of the pressure to ship the entire workshop
by default.

Again, once something goes in the core language, it has to be amazingly
positively unquestionably broken to be removed. Merely bad things have
too much staying power.

-- c

Larry Wall

unread,
Nov 26, 2003, 3:29:22 PM11/26/03
to perl6-l...@perl.org
On Wed, Nov 26, 2003 at 11:39:41AM -0800, Michael Lazzaro wrote:

: On Monday, November 24, 2003, at 03:28 PM, Luke Palmer wrote:
: >Damian Conway writes:
: >>In which case I think we just fall back to:
: >>
: >> try{$opus.write_to_file($file); CATCH {die "Couldn't write to
: >>$file:
: >> $!"}}
: >>
: >>which is, after all, only 5 characters longer than:
: >>
: >> $opus.write_to_file($file) catch die "Couldn't write to $file:
: >>$!\n";
: >>
: >>;-)
: >
: >Fair enough :-)
: >
: >No, I wasn't implying that C<write_to_file> could validly return undef.
: >I just failed to realize how short the "long" version was.
: >
: >But you have to admit, the latter version makes the important part of
: >the expression stand out, and is more natural to write (IMHO, as
: >always).
: >
: >But it's moduleable, so I won't worry about it.
:
:
: A small point of order, philosophically...
:
: While there is a justifiable urge to deny entry into of the core
: language of as much syntactic sugar as possible -- since merely looking
: at the operator list proves P6 will be a behemoth of a language, when

Only if you "unroll" all the composite operators formed of a base operator
and a modifier...

: you consider all of its nooks and crannies -- I think we also need to

: be skeptical of the false economy of putting such sugar into CP6AN, if
: a sizable portion of the community is going to download it anyway.
:
: In my mind, Luke's proposed C<catch> modifier quite easily fits the
: qualifications of something that should be in core, for the following
: reasons:
:
: - It serves a common purpose, for which there is Only One (Good) Way To
: Do It. While you perhaps _can_ say
:
: try {
: $opus.write_to_file($file);
: CATCH {
: die "Couldn't write to $file: $!"
: }
: }
:
: in other golfish ways, the above is clearly (ignoring preferences in
: whitespace formatting) the Obvious and Recommended way to do it, and so
: the above phrase will appear _wherever_ a single statement needs to be
: wrapped with a try/CATCH.

Well, ignoring the fact that the routine should really be returning undef
for an anticipated failure...

: - It has one, and only one, obvious meaning. Nobody should be making

: their own 'catch' modifiers that do different things -- that would be
: far more annoying, for shared code, than reserving the keyword in
: advance to do the One Obvious Thing.

By that argument we end up with 1000 keywords.

: - It is consistent with the philosophy of similar syntax.

I don't see how.

: - It poses no significant harm to novice users. They can program in P6

: effectively without ever using it, but if they do see it in someone
: else's code, it will be reasonably obvious what it is doing. And
: whether it is core or commonly used CP6AN, they _will_ see it in other
: people's code.

I don't think so. See below.

: It is true, the difference between the two constructs:


:
: try { $opus.write_to_file($file); CATCH {die "Couldn't write to
: $file: $!"} }
:
: $opus.write_to_file($file) catch die "Couldn't write to $file: $!";
:
: is only 7 characters. But four of those characters are curly brackets,
: visually introducing two blocks. That's kind of a yuck.

If you contrast it with an explicit try block, sure, it looks better. But
that's not what I compare it with. I compare it with Perl 5's:

$opus.write_to_file($file) or die "Couldn't write to $file: $!";

That has some known problems with false positives, er, negatives,
which Perl 6 addresses with things like:

$opus.write_to_file($file) err fail "Couldn't write to $file: $!";

But if we're going to talk about philosophy, we should talk about
Perl's notion of not forcing people to escalate all the way to
exceptions when a lesser form of undefinedness or falseness will do.
Perl 6 doesn't back off from this. In fact, it takes it further
by allowing you to return unthrown exceptions as "undef". And by
providing a "fail" that either returns or throws the exception
depending on the preferences of the caller.

If you want to promote a catch modifier to me, you'd better market it
as a form of "or" rather than a form of "try". I could see a form
of "err" that implies a try around its left argument and coerces
any caught exception to an undef exception. But that sounds like
a philosophical decision to be made consistently by the calling
module. like "use fatal" in reverse. So I think I'd rather see a
pragma that does that to "err" instead of adding yet another keyword.

Larry

Mark J. Reed

unread,
Nov 26, 2003, 3:56:28 PM11/26/03
to perl6-l...@perl.org
On 2003-11-26 at 12:13:39, chromatic wrote:
> Consider Perl 5, where File::Find is a core module. While the interface
> may have been nice in 1995 (though I doubt even that), it's been widely
> regarded as awful for at least three years. It's likely never to be
> removed from the core. File::Find::Rule is immensely nicer.

Nicer it may be, But I use File::Find *because* it's in the core,
so I don't have to worry about my programs being non-portable because I
use a module that may not be installed.

Which just proves your point, of course. File::Find::Rule may be nice
indeed, but I and many others would be highly annoyed if File::Find
were to go away, no matter how nice its interface isn't.

> Again, once something goes in the core language, it has to be amazingly
> positively unquestionably broken to be removed. Merely bad things have
> too much staying power.

Perhaps true. But I still agree with Michael that the "catch" keyword
is a logical addition to the core.

-Mark

Michael Lazzaro

unread,
Nov 26, 2003, 4:50:54 PM11/26/03
to perl6-l...@perl.org

On Wednesday, November 26, 2003, at 12:13 PM, chromatic wrote:

> On Wed, 2003-11-26 at 11:39, Michael Lazzaro wrote:
>
>> I think we also need to be skeptical of the false economy of putting
>> such sugar into CP6AN, if a sizable portion of the community is going
>> to download it anyway.
>
> A more interesting question is *when* to put something into the core
> language or libraries.
>
> Consider Perl 5, where File::Find is a core module. While the
> interface
> may have been nice in 1995 (though I doubt even that), it's been widely
> regarded as awful for at least three years. It's likely never to be
> removed from the core. File::Find::Rule is immensely nicer.

Agreed, but I hope I made it clear I was talking about a different
level of beast -- a bit of pure syntactic/semantic sugar that rests
solely upon other core things, not a bit of extended functionality.
File::Find is an excellent example of something that wouldn't belong in
core because it does not represent the Only Good Way To Do It. You can
think of plenty of valid interfaces to something as complex as a
File::Find-like module, and each would have vigorous supporters.

I'm talking about things on the level of, for example, C<unless>. I
can say:

foo() if not $a;
or
foo() unless $a;

The presence of C<unless> in the language, functionality-wise, is
utterly meaningless; it adds nothing aside from a very slight but
useful linguistic nuance. I wager most of us regularly use both C<if
not> and C<unless> now, interspersed liberally, depending on what
precisely we are trying to convey. We could be trained to always say
C<if not>, however, and eliminating it from P6 would save a keyword.

But it would be a hollow savings; nobody would realistically then use a
func/method/op/whatever called 'unless' in their code -- and if they
did use it, it would almost certainly be to produce a behavior
identical to the existing functionality.


Similarly, the much-needed new C<//> operator:

my $c = $a // $b;
or
my $c = (defined($a) ? $a : $b);

Again, a functionally meaningless bit of fluff which exists solely to
provide a simpler visual reading of a ridiculously common construct.
It could be eliminated easily; to do so would be an overall loss.
Ditto ==>, or even C<map>/C<grep>.

When I use the term 'sugar', it is things of this level of
primitiveness that I mean to convey.

MikeL

Simon Cozens

unread,
Nov 26, 2003, 6:22:04 PM11/26/03
to perl6-l...@perl.org
mlaz...@cognitivity.com (Michael Lazzaro) writes:
> I think we also need to be skeptical of the false economy of putting such
> sugar into CP6AN, if a sizable portion of the community is going to
> download it anyway.

"The standard Perl library will be almost entirely removed. The point of this
is to force ISPs to believe that Perl is essentially useless on its own, and
hence they will need to install additional modlues. Pragmatic modules will
have more freedom to warp Perl's syntax and semantics, and will also provide
real optimization hints.

Larry suggested that the standard module library could be downloaded basically
on demand; there will be a few modules which support basic built-in
functionality and their documentation. "

--
Ermine? NO thanks. I take MINE black.
- Henry Braun is Oxford Zippy

Michael Lazzaro

unread,
Nov 26, 2003, 8:18:51 PM11/26/03
to perl6-l...@perl.org

On Wednesday, November 26, 2003, at 01:50 PM, Michael Lazzaro wrote:
> my $c = (defined($a) ? $a : $b);

Sorry, P5.
Before the grammar police attack...

my $c = (defined($a) ?? $a :: $b);

Parens for clarity.

MikeL

Michael Lazzaro

unread,
Nov 26, 2003, 8:59:58 PM11/26/03
to perl6-l...@perl.org

On Wednesday, November 26, 2003, at 12:29 PM, Larry Wall wrote:
> If you contrast it with an explicit try block, sure, it looks better.
> But
> that's not what I compare it with. I compare it with Perl 5's:
>
> $opus.write_to_file($file) or die "Couldn't write to $file: $!";
>
> That has some known problems with false positives, er, negatives,
> which Perl 6 addresses with things like:
>
> $opus.write_to_file($file) err fail "Couldn't write to $file: $!";
>
> But if we're going to talk about philosophy, we should talk about
> Perl's notion of not forcing people to escalate all the way to
> exceptions when a lesser form of undefinedness or falseness will do.
> Perl 6 doesn't back off from this. In fact, it takes it further
> by allowing you to return unthrown exceptions as "undef". And by
> providing a "fail" that either returns or throws the exception
> depending on the preferences of the caller.

Well, yes, hmm, har, but...

Speaking only for myself, my own (database-heavy) code already makes
pretty extensive use of the differences between "false",
"unknown/undefined/NULL", and "worthy of exception" -- all three of
those conditions may exist at various times, and no two of them can
reasonably be lumped together as being logically identical.

There are plenty of cases where a piece of data being "undefined" or
"NULL" means something different from it being zero, for example -- and
neither case represents an actual error condition. Just undefinedness.
So, for those cases, I'm forced into using full-fledged exception
handling.

So as an abstract example, I would consider these to be entirely
different, but each of them to be useful:

foo(...) or blah(...);
foo(...) err blah(...);
foo(...) catch blah(...);

I read the first one as executing blah() if the result of foo() is a
false value; the second as executing blah() if the result is something
with an undefined or NULL value; the third as executing blah() if an
otherwise fatal condition arises during the execution of foo(). All
three can be considered constructs useful for quick-n-dirty recovery
from the corresponding -- but very different -- exceptional conditions.


> If you want to promote a catch modifier to me, you'd better market it
> as a form of "or" rather than a form of "try". I could see a form
> of "err" that implies a try around its left argument and coerces
> any caught exception to an undef exception.

Yes, precisely that.

> But that sounds like
> a philosophical decision to be made consistently by the calling
> module. like "use fatal" in reverse. So I think I'd rather see a
> pragma that does that to "err" instead of adding yet another keyword.

I would explicitly not want that, personally, for the above reasons;
there are many circumstances in which I'd rather use "undefined" to
mean "undefined", rather than "exceptional/error condition".

Again, tho, TMTOWTDI. It's hardly a crisis if it doesn't exist. It
just seems like an obvious simplification of try/CATCH when only one
statement is being wrapped.

MikeL

Michael G Schwern

unread,
Nov 27, 2003, 3:45:37 AM11/27/03
to Mark J. Reed, perl6-l...@perl.org
On Wed, Nov 26, 2003 at 03:56:28PM -0500, Mark J. Reed wrote:
> Nicer it may be, But I use File::Find *because* it's in the core,
> so I don't have to worry about my programs being non-portable because I
> use a module that may not be installed.

Of course with Perl 6 modules will be MUCH easier to install. :)


--
Michael G Schwern sch...@pobox.com http://www.pobox.com/~schwern/
Cottleston, Cottleston, Cottleston Pie.
A fly can't bird, but a bird can fly.
Ask me a riddle and I reply:
"Cottleston, Cottleston, Cottleston Pie."

Piers Cawley

unread,
Dec 2, 2003, 8:16:47 AM12/2/03
to Michael Lazzaro, perl6-l...@perl.org
Michael Lazzaro <mlaz...@cognitivity.com> writes:

> On Wednesday, November 26, 2003, at 12:29 PM, Larry Wall wrote:
>> If you contrast it with an explicit try block, sure, it looks
>> better. But
>> that's not what I compare it with. I compare it with Perl 5's:
>>
>> $opus.write_to_file($file) or die "Couldn't write to $file: $!";
>>
>> That has some known problems with false positives, er, negatives,
>> which Perl 6 addresses with things like:
>>
>> $opus.write_to_file($file) err fail "Couldn't write to $file: $!";
>>
>> But if we're going to talk about philosophy, we should talk about
>> Perl's notion of not forcing people to escalate all the way to
>> exceptions when a lesser form of undefinedness or falseness will do.
>> Perl 6 doesn't back off from this. In fact, it takes it further
>> by allowing you to return unthrown exceptions as "undef". And by
>> providing a "fail" that either returns or throws the exception
>> depending on the preferences of the caller.
>
> Well, yes, hmm, har, but...
>
> Speaking only for myself, my own (database-heavy) code already makes
> pretty extensive use of the differences between "false",
> "unknown/undefined/NULL", and "worthy of exception" -- all three of
> those conditions may exist at various times, and no two of them can
> reasonably be lumped together as being logically identical.

So implement a *real* NULL instead of trying to force 'undef'
somewhere it doesn't want to go.

0 new messages