Add compiler warning for checked exception

148 views
Skip to first unread message

zhaber

unread,
Feb 3, 2011, 10:48:30 PM2/3/11
to scala-debate
Sometimes forcing a developer to handle some checked exception is a
necessary feature, so I propose to add a compile time warning for
unhandled checked exceptions that occurs in method's @throws
annotation. It will still allow developers to not write unnecessary
code and at the same time make writing robuster applications easier.
To suppress the proposed warning I would also add @swallow MyException
annotation that will prevent from propagating the exception on upper
layers if a developer does not intend to handle this exception, the
@swallow annotation will not pollute the method body which will make
its usage quite smooth.

Ken Scambler

unread,
Feb 3, 2011, 11:08:55 PM2/3/11
to zhaber, scala-debate
I really think the programming world has voted with its feet on this one.  There's still some people that swear by checked exceptions, but not a single language that I can think of has adopted them since Java, despite its vast influence, and many (most?) popular Java frameworks choose to eschew them.

So I can't really see them as "necessary", and especially not if it's going to litter my beautiful clean Scala code with pointless annotations and warnings.

Ken

zhaber

unread,
Feb 3, 2011, 11:20:01 PM2/3/11
to scala-debate
It will not litter your code unless you turn on this warning

On Feb 3, 11:08 pm, Ken Scambler <ken.scamb...@gmail.com> wrote:
> I really think the programming world has voted with its feet on this one.
> There's still some people that swear by checked exceptions, but not a single
> language that I can think of has adopted them since Java, despite its vast
> influence, and many (most?) popular Java frameworks choose to eschew them.
>
> So I can't really see them as "necessary", and especially not if it's going
> to litter my beautiful clean Scala code with pointless annotations and
> warnings.
>
> Ken
>

Ken Scambler

unread,
Feb 3, 2011, 11:41:40 PM2/3/11
to zhaber, scala-debate
There's no distinction between checked/unchecked exceptions in the JVM; this is only enforced in the Java compiler, based on whether the class extends RuntimeException or not. 

Exceptions in existing Scala code would have been written without regard to this restriction, so if it were suddenly enforced, an unexpected "checked" nature would appear in already written code, which wouldn't have been designed to behave this way, and it would render a great deal of existing code uncompilable.

Still, I can't see why this couldn't be done in a compiler plugin, which I would encourage you to consider investigating, if you are keen enough on this. :)

Ken

Ken Scambler

unread,
Feb 4, 2011, 12:00:13 AM2/4/11
to zhaber, scala-debate
and it would render a great deal of existing code uncompilable.

Sorry I'm wrong -- it would compile of course, if we're only talking about warnings.  There could possibly be a lot of spurious ones though.

Ken

Michael Stal

unread,
Feb 4, 2011, 3:05:06 AM2/4/11
to Ken Scambler, zhaber, scala-debate
From my viewpoint the idea of checked exceptions, although meant to be a good feature, is more a bad idea. There have been numerous discussions on this (http://www.artima.com/intv/handcuffs.html, http://radio-weblogs.com/0122027/stories/2003/04/01/JavasCheckedExceptionsWereAMistake.html, http://www.c2.com/cgi/wiki?CheckedExceptionsAreOfDubiousValue). So I won't repeat the arguments.
There is good reason that checked exceptions are not found in most  languages except of Java.
I also wouldn't like a compiler plug-in.
Not catching an exception should be rather detected by code analysis tools. Sometimes there are good reasons not to catch an exception (see the let it crash strategy in Erlang).
And in Java (and also in other languages)  I have seen many (mis)uses of empty catch blocks (wich means the program will simply swallow the exception without handling it). Thesea re programmer errors a compiler would not detect which is worse than dealing with catched exceptions
 
 
Just my 2c

martin odersky

unread,
Feb 5, 2011, 7:39:33 AM2/5/11
to Michael Stal, Ken Scambler, zhaber, scala-debate, Rytz Lukas
The problem with checked exceptions is best demonstrated by the map
method on lists:

def map[B](f: A => B): List[B]

How to annotate map with @throws? If map does not get a @throws
annotation itself then presumably you cannot pass it any function that
has a @throws. That would introduce cumbersome restrictions and
distinctions for the ways in which map can be used. Things would be
better if we could state somehow that map throws all exceptions that
its function argument throws. There are some effect systems that can
express this, but so far every notation I have seen is too heavy.

Lukas Rytz is doing some research on lightweight effect systems that
could be used to express the type of map and other common functions in
a concise and precise way. It's research, so it's at present unclear
to what degree we will succeed and how much of that can be put into
Scala. Ideally, we'll be able to add it at some point as an optional
type system. But it's much too early to make concrete predictions.

Cheers

-- Martin

Chris Twiner

unread,
Feb 5, 2011, 8:58:55 AM2/5/11
to zhaber, scala-debate

When you really need this use Either and a decent error type.

Vitalii Fedorenko

unread,
Feb 5, 2011, 4:30:18 PM2/5/11
to scala-debate
Thanks for the example, Martin. You are right, a responsibility of
exceptions handling is a part of a business logic and enforcing a
developer to process them on each layer adds inevitable problems that
decredits their value.

So what if there will be a functionality that implicitly wraps a
return value for functions with "@checkedThrown Ex1, Ex2" annotation
in a new Exceptionable class. This class will implicitly set the value
upon return and allow to extract it only with try/catch structure that
checks catches for exhaustiveness. This approach moves an exception
handling from a time when the exception occurred to a point where we
need to extract the value, which unburdens unrelated intermediate
methods from dealing with an exception and make it possible to pass
such functions without any additional notations.

Vitalii Fedorenko

On Feb 5, 8:58 am, Chris Twiner <chris.twi...@gmail.com> wrote:
> When you really need this use Either and a decent error type.
>

Daniel Sobral

unread,
Feb 5, 2011, 5:38:58 PM2/5/11
to martin odersky, Michael Stal, Ken Scambler, zhaber, scala-debate, Rytz Lukas
I wish this text was somewhere I could link to and tweet about. So clear, simple and succinct!
--
Daniel C. Sobral

I travel to the future all the time.

Randall R Schulz

unread,
Feb 5, 2011, 7:13:50 PM2/5/11
to scala-...@googlegroups.com
On Saturday February 5 2011, Daniel Sobral wrote:
> I wish this text was somewhere I could link to and tweet about. So
> clear, simple and succinct!

Among the virtues of switching to Google Groups is the ability to link
to individual messages:

http://groups.google.com/group/scala-debate/msg/99369ca6c4959894


> On Sat, Feb 5, 2011 at 10:39, martin odersky wrote:
> > ...


Randall Schulz

Tony Morris

unread,
Feb 6, 2011, 3:59:59 PM2/6/11
to scala-...@googlegroups.com

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 05/02/11 22:39, martin odersky wrote:
> The problem with checked exceptions is best demonstrated by the
> map method on lists:
>
> def map[B](f: A => B): List[B]
>
> How to annotate map with @throws?

Quite easy really.

First, let's generalise the signature:

F[A] => (A => B) => F[B]

Now let's abstract it to a trait:

trait Functor[F[_]] {
def fmap[A, B](a: F[A], f: A => B): F[B]
}

Now let's recognise that this "throws" is just another data type (like
Either):

sealed trait Throws[A]
case class Thrown[A](t: Throwable) extends Throws[A]
case class NoThrow[A](value: A) extends Throws[A]

Now observe that Throws satisfies the Functor trait:

def ThrowsFunctor: Functor[Throws] = new Functor[Throws] {
def fmap[A, B](a: Throws[A], f: A => B) = a match {
case Thrown(t) => Thrown(t)
case NoThrow(a) => NoThrow(f(a))
}
}

Now the question is, how do we map to a value T, that might throw, as
in Throws[T]?

We use the Throws transformer:

case class ThrowsT[F[_], A](th: F[Throws[A]])

Now observe that ThrowsT[F, _] satisfies the Functor trait, so long as
F satisfies the Functor trait. That is to say, ThrowsT type
constructor, partially-applied gives us a functor. This is going to
require some scala gymnastics, but it's perfectly viable:

def ThrowsTFunctor[F[_]](ftr: Functor[F]): Functor[({type
?[?]=ThrowsT[F, ?]})#?] =
new Functor[({type ?[?]=ThrowsT[F, ?]})#?] {
def fmap[A, B](a: ThrowsT[F, A], f: A => B) = a match {
case ThrowsT(th) =>
ThrowsT(ftr.fmap(th, (a: Throws[A]) => ThrowsFunctor.fmap(a,
f)))
}
}

By adding some convenience functions (such as A => ThrowsT[F, A]) and
abstractions, this ThrowsT data type allows us to treat regular values
as well as those that may throw in their computation all within the
same abstraction ("the ability to map").


- --
Tony Morris
http://tmorris.net/

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk1PC84ACgkQmnpgrYe6r62qCgCgz1/icLutT9RyiR7U6xgeXfNZ
X4gAnjR8rDNljqndoRbT5JnvgIpET3B2
=Vz01
-----END PGP SIGNATURE-----

Reply all
Reply to author
Forward
0 new messages