This page is no longer maintained — Please continue to the home page at www.scala-lang.org

try/catch syntax

17 replies
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.

In the middle of a rant about the vertical space forced upon me by
try/catch in code which otherwise has a nice smooth information density,
it occurred to me that try/catch could be parsed like for() and allow
for an expression in parens as well as a block in braces. I implemented
this and it looks to work nicely.

scala> try (throw new Exception("bloop")) finally println("fin")
fin
java.lang.Exception: bloop
at .liftedTree1$1(:5)
at .(:5)
at .()

Martin, how do you feel about this? It would make me very happy, and I
would argue that although the paren/braces distinction is probably
confusing to people, this change represents a consistency improvement
and thus lowers total confusion.

DRMacIver
Joined: 2008-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: try/catch syntax

On Fri, 13 Mar 2009, Paul Phillips wrote:

> In the middle of a rant about the vertical space forced upon me by
> try/catch in code which otherwise has a nice smooth information density,
> it occurred to me that try/catch could be parsed like for() and allow
> for an expression in parens as well as a block in braces. I implemented
> this and it looks to work nicely.
>
> scala> try (throw new Exception("bloop")) finally println("fin")
> fin
> java.lang.Exception: bloop
> at .liftedTree1$1(:5)
> at .(:5)
> at .()
>
> Martin, how do you feel about this? It would make me very happy, and I
> would argue that although the paren/braces distinction is probably
> confusing to people, this change represents a consistency improvement
> and thus lowers total confusion.

To clarify, the following is not legal under your change?

try error("bloop") finally println("fin")

i.e. one of brackets or braces are required there?

It's been suggested before that a design goal for Scala is that braces
should be allowed wherever brackets are. Where convenient it seems
sensible to reverse this as well, so this seems an entirely reasonable
change to me. Allowing it without either would be even nicer, as that
achieves a degree of consistency with how finally works and the ability to
do

if (kittens) stuff else otherstuff

i.e. making it so that the body of the try is just some expression would
be pleasant.

David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: try/catch syntax
Personally, I like it.

On Fri, Mar 13, 2009 at 2:40 PM, Paul Phillips <paulp@improving.org> wrote:
In the middle of a rant about the vertical space forced upon me by
try/catch in code which otherwise has a nice smooth information density,
it occurred to me that try/catch could be parsed like for() and allow
for an expression in parens as well as a block in braces.  I implemented
this and it looks to work nicely.

scala> try (throw new Exception("bloop")) finally println("fin")
fin
java.lang.Exception: bloop
       at .liftedTree1$1(<console>:5)
       at .<init>(<console>:5)
       at .<clinit>(<console>)

Martin, how do you feel about this? It would make me very happy, and I
would argue that although the paren/braces distinction is probably
confusing to people, this change represents a consistency improvement
and thus lowers total confusion.

--
Paul Phillips      | Eschew mastication.
Apatheist          |
Empiricist         |
i'll ship a pulp   |----------* http://www.improving.org/paulp/ *----------



--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: try/catch syntax

On Fri, Mar 13, 2009 at 03:01:42PM +0000, David R. MacIver wrote:
> To clarify, the following is not legal under your change?
>
> try error("bloop") finally println("fin")

Correct, not legal as proposed, but I just tried implementing it with
parens optional and that's no (obvious) problem either. Yum yum.

scala> val x = try Integer.parseInt("5") catch { case e => 10 }
x: Int = 5

scala> val x = try Integer.parseInt("bob") catch { case e => 10 }
x: Int = 10

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: try/catch syntax

On Fri, Mar 13, 2009 at 4:33 PM, Paul Phillips wrote:
> On Fri, Mar 13, 2009 at 03:01:42PM +0000, David R. MacIver wrote:
>> To clarify, the following is not legal under your change?
>>
>> try error("bloop") finally println("fin")
>
> Correct, not legal as proposed, but I just tried implementing it with
> parens optional and that's no (obvious) problem either.  Yum yum.
>
> scala> val x = try Integer.parseInt("5") catch { case e => 10 }
> x: Int = 5
>
> scala> val x = try Integer.parseInt("bob") catch { case e => 10 }
> x: Int = 10
>
I think the change is good, with one modification: Currently, both
catch and finally are optional. Together with the proposed
modification, this would lead to a `dangling else' problem:

try
try something
catch { ... }
finally { ... }

Currently, this would be parsed:

try {
try something
catch { ... }
finally { ... }
}

No parse error results because try without catch or finally is legal.
I think this could be improved by demanding either a catch or a
finally after a try. Then we still have a misinterpretation for the
inner try, but at least the outer try would give an error.

Cheers

milessabin
Joined: 2008-08-11,
User offline. Last seen 33 weeks 3 days ago.
Re: try/catch syntax

On Fri, Mar 13, 2009 at 3:54 PM, martin odersky wrote:
> I think the change is good, with one modification: Currently, both
> catch and finally are optional. Together with the proposed
> modification, this would lead to a `dangling else' problem:

Initially I thought that might be a problem, but actually I don't
think it is, because regardless of grouping,

* All finally clauses are executed in textual order.

* On an exception, the innermost matching catch case is executed.

Cheers,

Miles

DRMacIver
Joined: 2008-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: try/catch syntax

On Fri, 13 Mar 2009, martin odersky wrote:

> On Fri, Mar 13, 2009 at 4:33 PM, Paul Phillips wrote:
>> On Fri, Mar 13, 2009 at 03:01:42PM +0000, David R. MacIver wrote:
>>> To clarify, the following is not legal under your change?
>>>
>>> try error("bloop") finally println("fin")
>>
>> Correct, not legal as proposed, but I just tried implementing it with
>> parens optional and that's no (obvious) problem either.  Yum yum.
>>
>> scala> val x = try Integer.parseInt("5") catch { case e => 10 }
>> x: Int = 5
>>
>> scala> val x = try Integer.parseInt("bob") catch { case e => 10 }
>> x: Int = 10
>>
> I think the change is good, with one modification: Currently, both
> catch and finally are optional. Together with the proposed
> modification, this would lead to a `dangling else' problem:
>
> try
> try something
> catch { ... }
> finally { ... }
>
> Currently, this would be parsed:
>
> try {
> try something
> catch { ... }
> finally { ... }
> }
>
> No parse error results because try without catch or finally is legal.
> I think this could be improved by demanding either a catch or a
> finally after a try. Then we still have a misinterpretation for the
> inner try, but at least the outer try would give an error.

This seems like an eminently sensible modification. I don't see any
compelling motivation for keeping the ability to have tries without a
catch or finally.

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: try/catch syntax

On Fri, Mar 13, 2009 at 4:58 PM, Miles Sabin wrote:
> On Fri, Mar 13, 2009 at 3:54 PM, martin odersky wrote:
>> I think the change is good, with one modification: Currently, both
>> catch and finally are optional. Together with the proposed
>> modification, this would lead to a `dangling else' problem:
>
> Initially I thought that might be a problem, but actually I don't
> think it is, because regardless of grouping,
>
> * All finally clauses are executed in textual order.
>
> * On an exception, the innermost matching catch case is executed.
>
I think you are right. So maybe it's even better to leave both catch
and try optional, because then we cannot manoever ourselves into a
dead-end, as in my example:

try
try something
catch { ... }
finally { ... }

Cheers

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: try/catch syntax

On Fri, Mar 13, 2009 at 04:54:01PM +0100, martin odersky wrote:
> No parse error results because try without catch or finally is legal.
> I think this could be improved by demanding either a catch or a
> finally after a try.

I think this is a good idea regardless of ambiguity problems - try with
no followups makes no sense.

scala> val x = try Integer.parseInt("5");
:1: error: try requires at least one of catch or finally
val x = try Integer.parseInt("5");
^

The interpreter even does the right thing.

scala> val x = try Integer.parseInt("5")
| finally 10
x: Int = 5

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: try/catch syntax

On Fri, Mar 13, 2009 at 5:11 PM, Paul Phillips wrote:
> On Fri, Mar 13, 2009 at 04:54:01PM +0100, martin odersky wrote:
>> No parse error results because try without catch or finally is legal.
>> I think this could be improved by demanding either a catch or a
>> finally after a try.
>
> I think this is a good idea regardless of ambiguity problems - try with
> no followups makes no sense.
>
In a sense it does make sense. It's just a try where nothing is
caught. Sort of like zero or the identity function make sense. Given
Miles discovery, I would leave it as it is, and just an accept
arbitrary expression after try.

Cheers

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: try/catch syntax

On Fri, Mar 13, 2009 at 05:16:37PM +0100, martin odersky wrote:
> In a sense it does make sense. It's just a try where nothing is
> caught. Sort of like zero or the identity function make sense. Given
> Miles discovery, I would leave it as it is, and just an accept
> arbitrary expression after try.

We have a new winner in the zen programming contest!

scala> println ( try Nil foreach identity )
()

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: try/catch syntax

On Fri, Mar 13, 2009 at 05:01:44PM +0100, martin odersky wrote:
> I think you are right. So maybe it's even better to leave both catch
> and try optional, because then we cannot manoever ourselves into a
> dead-end, as in my example:
>
> try
> try something
> catch { ... }
> finally { ... }

So someone writes this wanting it to be parsed how it isn't:

try { try something catch { ... } } finally { ... }

This seems comparable in sensibility to writing:

if (x) if (y) a1 else if (z) a2 else a3

...which seems firmly in the category of "even if you can instantly see
what this does, the next guy can't."

I'm happy to implement it either way though.

Antonio Cunei
Joined: 2008-12-16,
User offline. Last seen 3 years 22 weeks ago.
Re: try/catch syntax

Miles Sabin wrote:
> On Fri, Mar 13, 2009 at 3:54 PM, martin odersky wrote:
>> I think the change is good, with one modification: Currently, both
>> catch and finally are optional. Together with the proposed
>> modification, this would lead to a `dangling else' problem:
>
> Initially I thought that might be a problem, but actually I don't
> think it is, because regardless of grouping,
>
> * All finally clauses are executed in textual order.
>

Consider what happens if a programmer writes the following, meaning to
associate the "finally" with the first try:

try
for (i <- 1 to 2)
try something
catch {...}
finally {...}

If the "finally" is parsed as part of the nested try instead, the final
clause is certainly executed, but twice rather than once :)
Toni

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: try/catch syntax

On Fri, Mar 13, 2009 at 5:49 PM, Antonio Cunei wrote:
> Miles Sabin wrote:
>>
>> On Fri, Mar 13, 2009 at 3:54 PM, martin odersky
>> wrote:
>>>
>>> I think the change is good, with one modification: Currently, both
>>> catch and finally are optional. Together with the proposed
>>> modification, this would lead to a `dangling else' problem:
>>
>> Initially I thought that might be a problem, but actually I don't
>> think it is, because regardless of grouping,
>>
>> * All finally clauses are executed in textual order.
>>
>
> Consider what happens if a programmer writes the following, meaning to
> associate the "finally" with the first try:
>
> try
>  for (i <- 1 to 2)
>    try something
>    catch {...}
> finally {...}
>
> If the "finally" is parsed as part of the nested try instead, the final
> clause is certainly executed, but twice rather than once :)

Yes, good catch! So it looks like we need to insist or braces or
parens after the try.

Cheers

DRMacIver
Joined: 2008-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: try/catch syntax

On Fri, Mar 13, 2009 at 5:03 PM, martin odersky wrote:
> On Fri, Mar 13, 2009 at 5:49 PM, Antonio Cunei wrote:
>> Miles Sabin wrote:
>>>
>>> On Fri, Mar 13, 2009 at 3:54 PM, martin odersky
>>> wrote:
>>>>
>>>> I think the change is good, with one modification: Currently, both
>>>> catch and finally are optional. Together with the proposed
>>>> modification, this would lead to a `dangling else' problem:
>>>
>>> Initially I thought that might be a problem, but actually I don't
>>> think it is, because regardless of grouping,
>>>
>>> * All finally clauses are executed in textual order.
>>>
>>
>> Consider what happens if a programmer writes the following, meaning to
>> associate the "finally" with the first try:
>>
>> try
>>  for (i <- 1 to 2)
>>    try something
>>    catch {...}
>> finally {...}
>>
>> If the "finally" is parsed as part of the nested try instead, the final
>> clause is certainly executed, but twice rather than once :)
>
> Yes, good catch! So it looks like we need to insist or braces or
> parens after the try.

Isn't this identical to problems we already have with if statements?

if(kittens)
for(i <- 1 to 2)
if(puppies) iHavePuppies;
else iHaveNoKittens; // actually I have no puppies

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: try/catch syntax

On Fri, Mar 13, 2009 at 05:12:03PM +0000, David MacIver wrote:
> Isn't this identical to problems we already have with if statements?
>
> if(kittens)
> for(i <- 1 to 2)
> if(puppies) iHavePuppies;
> else iHaveNoKittens; // actually I have no puppies

I'm not sure how we left this, but I agree this is exactly as bad as the
dangling else problem - which is to say - a problem optional braces were
invented to solve. So since I'd already checked in a version that
allowed naked try expressions, I'm waiting on a definitive verdict
before hamstringing the current syntax which, in my opinion, verges on
the transcendent.

scala> def again(): Function0[_] = again
again: ()Function0[_]

scala> def advice(succeed: List[Boolean]) = if (!succeed.head) try try again
advice: (List[Boolean])Any

scala> advice(List(true))
res0: Any = ()

scala> advice(List(false))
[... I'm sure we'll have an answer any day now ...]

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: try/catch syntax

On Fri, Mar 13, 2009 at 11:48 PM, Paul Phillips wrote:
> On Fri, Mar 13, 2009 at 05:12:03PM +0000, David MacIver wrote:
>> Isn't this identical to problems we already have with if statements?
>>
>> if(kittens)
>>   for(i <- 1 to 2)
>>     if(puppies) iHavePuppies;
>> else iHaveNoKittens; // actually I have no puppies
>
> I'm not sure how we left this, but I agree this is exactly as bad as the
> dangling else problem - which is to say - a problem optional braces were
> invented to solve.  So since I'd already checked in a version that
> allowed naked try expressions, I'm waiting on a definitive verdict
> before hamstringing the current syntax which, in my opinion, verges on
> the transcendent.
>
> scala> def again(): Function0[_] = again
> again: ()Function0[_]
>
> scala> def advice(succeed: List[Boolean]) = if (!succeed.head) try try again
> advice: (List[Boolean])Any
>
> scala> advice(List(true))
> res0: Any = ()
>
> scala> advice(List(false))
> [... I'm sure we'll have an answer any day now ...]
>
I'm not really worried either way. When in doubt, leave things as they
are, or do the thing that's simplest and backwards compatible. But I
am open to other arguments.

Cheers

DRMacIver
Joined: 2008-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: try/catch syntax

On Sat, Mar 14, 2009 at 11:21 AM, martin odersky wrote:
> On Fri, Mar 13, 2009 at 11:48 PM, Paul Phillips wrote:
>> On Fri, Mar 13, 2009 at 05:12:03PM +0000, David MacIver wrote:
>>> Isn't this identical to problems we already have with if statements?
>>>
>>> if(kittens)
>>>   for(i <- 1 to 2)
>>>     if(puppies) iHavePuppies;
>>> else iHaveNoKittens; // actually I have no puppies
>>
>> I'm not sure how we left this, but I agree this is exactly as bad as the
>> dangling else problem - which is to say - a problem optional braces were
>> invented to solve.  So since I'd already checked in a version that
>> allowed naked try expressions, I'm waiting on a definitive verdict
>> before hamstringing the current syntax which, in my opinion, verges on
>> the transcendent.
>>
>> scala> def again(): Function0[_] = again
>> again: ()Function0[_]
>>
>> scala> def advice(succeed: List[Boolean]) = if (!succeed.head) try try again
>> advice: (List[Boolean])Any
>>
>> scala> advice(List(true))
>> res0: Any = ()
>>
>> scala> advice(List(false))
>> [... I'm sure we'll have an answer any day now ...]
>>
> I'm not really worried either way. When in doubt, leave things as they
> are, or do the thing that's simplest and backwards compatible. But I
> am open to other arguments.

My inclination is what when a minor change can improve consistency
between different constructs without introducing any new problems then
it should. I'm not sure whether this constitutes a new problem - it's
something people are already familiar with from other similar
constructs - but the inability to use an expression with try has
certainly annoyed me in the past, and the change is certainly
backwards compatible - all existing code works, and the meaning of it
doesn't change, it's just that a new syntax to do the same thing is
also possible in some cases.

So, I'm mildly in favour of the new syntax. I don't think it's
crucial, but it would be nice.

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland