RE: [Haskell-cafe] Exceptions during exception unwinding

2009-10-01 Thread Brian Bloniarz

 1254389201.7656.3.ca...@localhost
Content-Type: text/plain; charset=Windows-1252
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0


 On Thu=2C 2009-10-01 at 03:29 +=2C Brian Bloniarz wrote:
 I.e. why does an exception raised during exception handling get
 propagated past the exception that triggered the handler?

 Because it's the obvious and sensible thing to do and it what every
 other mainstream language with exceptions does.

Good to know ... C++ (the mainstream language I'm most familiar
with) treats throwing from a destructor during unwinding as a fatal
error.

 bracket openSomeHandle closeSomeHandle doAction
 Then catch and ignore the exception from closeSomeHandle (though not all
 exceptions or you'd block ^C etc). That said=2C how will you know that
 closeSomeHandle ever works if you always ignore any exceptions it
 raises?

I was suggesting having bracket ignore exceptions from closeSomeHandle
when doAction threw=2C not that it'd ignore any exceptions from
closeSomeHandle.

It's only the case where bracket has 2 exceptions to choose from that's
ambiguous=2C and I'm saying that there's a fair amount of code
out there that'd prefer to see the first one. Your point about ^C gets us i=
nto
an even grayer area -- maybe code would prefer to propagate whichever of
the 2 exceptions is asynchronous=2C or define a criterion to choose which
exception is more serious=2C who knows.

All these behaviors are easy to implement using the building blocks that
Control.Exception exports right now=2C you're right. So I'm free to build
my own bracket variants with different behavior and that's what I'll do.
I was just wondering if the default behavior that bracket/onException
provide (which are themselves built from catch/block/unblock) is the one
that most people want.

Thanks=2C
-Brian
  =0A=
_=0A=
Microsoft brings you a new way to search the web.  Try  Bing=99 now=0A=
http://www.bing.com?form=3DMFEHPGpubl=3DWLHMTAGcrea=3DTEXT_MFEHPG_Core_ta=
gline_try bing_1x1=
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Exceptions during exception unwinding

2009-10-01 Thread Brian Bloniarz

Sorry for the garbled post, this should hopefully be plain text:

 On Thu, 2009-10-01 at 03:29 +, Brian Bloniarz wrote:
 I.e. why does an exception raised during exception handling get
 propagated past the exception that triggered the handler?

 Because it's the obvious and sensible thing to do and it what every
 other mainstream language with exceptions does. The behaviour you want,
 to automatically discard any exceptions raised in the handler and to
 always re-raise the original exception can be implemented using the
 current semantics, but the reverse is not true.

Good to know ... C++ (the mainstream language I'm most familiar
with) treats throwing from a destructor during unwinding as a fatal
error.

I was suggesting having bracket ignore exceptions from closeSomeHandle
when doAction threw, not that it'd ignore any exceptions from
closeSomeHandle.
 
It's only the case where bracket has 2 exceptions to choose from that's
ambiguous, and I'm saying that there's a fair amount of code
out there that'd prefer to see the first one. Your point about ^C gets us
into an even grayer area -- maybe code would prefer to propagate whichever
of the 2 exceptions is asynchronous, or define a criterion to choose which
exception is more serious, who knows.
 
All these behaviors are easy to implement using the building blocks that
Control.Exception exports right now, you're right. So I'm free to build
my own bracket variants with different behavior and that's what I'll do.
I was just wondering if the default behavior that bracket/onException
provide (which are themselves built from catch/block/unblock) is the one
that most people want.
 
Thanks,
-Brian

  
_
Microsoft brings you a new way to search the web.  Try  Bing™ now
http://www.bing.com?form=MFEHPGpubl=WLHMTAGcrea=TEXT_MFEHPG_Core_tagline_try 
bing_1x1___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Exceptions during exception unwinding

2009-10-01 Thread Lyndon Maydwell
Exception handling code should generally be assumed to work, so if
something goes wrong there you would normally like to know about it.
Also, there is nothing preventing you from wrapping the rescue code in
further exception handling, however, if the initial error were raised
upon encountering a second error, you would not be able to choose to
handle the second error.

This is how I see it anyway.

On Thu, Oct 1, 2009 at 11:29 AM, Brian Bloniarz phun...@hotmail.com wrote:

 I had a question about onException  friends: what's the rationale
 for having:
 (error foo) `onException` (error bar)

 give bar and not foo? I.e. why does an exception raised during
 exception handling get propagated past the exception that triggered
 the handler?

 Most examples I can think for exception unwinding code would prefer the
 original exception be propagated -- for example, HDBC has a function which
 rolls back a DB transaction on exception; it implements it like so:
 withTransaction conn func =
   do r - onException (func conn) doRollback
  commit conn
  return r
   where doRollback =
 -- Discard any exception from (rollback conn) so original
 -- exception can be re-raised
 Control.Exception.catch (rollback conn) doRollbackHandler
 doRollbackHandler :: SomeException - IO ()
 doRollbackHandler _ = return ()
 IMHO, it'd be easier to just write:
 withTransaction conn func =
   do r - onException (func conn) (rollback conn)
  commit conn
  return r

 This same argument applies to bracket, bracket_, bracketOnError  finally;
 even the common:
 bracket openSomeHandle closeSomeHandle doAction
 If some error arises during doAction, there's a chance closeSomeHandle might 
 fail
 (even a good chance, given that exception unwinding paths are usually poorly
 tested), and probably doAction has more accurate information about what went
 wrong than closeSomeHandle.

 This is just a thought; I hadn't seen this discussed somewhere. I know for
 example that Java has the same approach as the current Control.Exception, so
 there must be good arguments for that too. One that I can think of: using
 onException to rethrow an exception as a different type, though that's what
 mapException is for, correct?

 Thanks,
 -Brian
 _
 Microsoft brings you a new way to search the web.  Try  Bing™ now
 http://www.bing.com?form=MFEHPGpubl=WLHMTAGcrea=TEXT_MFEHPG_Core_tagline_try
  bing_1x1___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Exceptions during exception unwinding

2009-10-01 Thread Duncan Coutts
On Thu, 2009-10-01 at 03:29 +, Brian Bloniarz wrote: 
 I had a question about onException  friends: what's the rationale
 for having:
 (error foo) `onException` (error bar)
 
 give bar and not foo?

 I.e. why does an exception raised during exception handling get
 propagated past the exception that triggered the handler?

Because it's the obvious and sensible thing to do and it what every
other mainstream language with exceptions does. The behaviour you want,
to automatically discard any exceptions raised in the handler and to
always re-raise the original exception can be implemented using the
current semantics, but the reverse is not true.

 Most examples I can think for exception unwinding code would prefer the
 original exception be propagated

Then do not rethrow a different exception.

 This same argument applies to bracket, bracket_, bracketOnError  finally;
 even the common:
  bracket openSomeHandle closeSomeHandle doAction
 If some error arises during doAction, there's a chance closeSomeHandle might 
 fail
 (even a good chance, given that exception unwinding paths are usually poorly
 tested), and probably doAction has more accurate information about what went
 wrong than closeSomeHandle.

Then catch and ignore the exception from closeSomeHandle (though not all
exceptions or you'd block ^C etc). That said, how will you know that
closeSomeHandle ever works if you always ignore any exceptions it
raises?

For example in the case of your database transaction, having the
transaction fail and roll back is something your application may be set
up to handle. But transation failing during the rollback may be much
more catastrophic and may want to be treated differently. If it fails in
the rollback it might be leaking resources and at the very least you may
want to log it differently from just a transaction that was successfully
rolled back.

 This is just a thought; I hadn't seen this discussed somewhere. I know for
 example that Java has the same approach as the current Control.Exception, so
 there must be good arguments for that too. One that I can think of: using
 onException to rethrow an exception as a different type, though that's what
 mapException is for, correct?

mapException is for the case of exceptions raised by pure code.

As you say, being able to rethrow a different kind of exception, or
simply handle the exception there and then are useful.

I think using onException is the best one for your use case. If you
really really want to ignore an exception raised by rollback then you
have the tools available to do so. As I mentioned earlier do not just
catch and discard all exceptions, see:
http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Exception.html#4

Duncan

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Exceptions during exception unwinding

2009-09-30 Thread Brian Bloniarz

I had a question about onException  friends: what's the rationale
for having:
(error foo) `onException` (error bar)

give bar and not foo? I.e. why does an exception raised during
exception handling get propagated past the exception that triggered
the handler?

Most examples I can think for exception unwinding code would prefer the
original exception be propagated -- for example, HDBC has a function which
rolls back a DB transaction on exception; it implements it like so:
 withTransaction conn func =
   do r - onException (func conn) doRollback
  commit conn
  return r
   where doRollback = 
 -- Discard any exception from (rollback conn) so original
 -- exception can be re-raised
 Control.Exception.catch (rollback conn) doRollbackHandler
 doRollbackHandler :: SomeException - IO ()
 doRollbackHandler _ = return ()
IMHO, it'd be easier to just write:
 withTransaction conn func =
   do r - onException (func conn) (rollback conn)
  commit conn
  return r

This same argument applies to bracket, bracket_, bracketOnError  finally;
even the common:
 bracket openSomeHandle closeSomeHandle doAction
If some error arises during doAction, there's a chance closeSomeHandle might 
fail
(even a good chance, given that exception unwinding paths are usually poorly
tested), and probably doAction has more accurate information about what went
wrong than closeSomeHandle.

This is just a thought; I hadn't seen this discussed somewhere. I know for
example that Java has the same approach as the current Control.Exception, so
there must be good arguments for that too. One that I can think of: using
onException to rethrow an exception as a different type, though that's what
mapException is for, correct?

Thanks,
-Brian
_
Microsoft brings you a new way to search the web.  Try  Bing™ now
http://www.bing.com?form=MFEHPGpubl=WLHMTAGcrea=TEXT_MFEHPG_Core_tagline_try 
bing_1x1___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Exceptions

2008-09-18 Thread Marc Weber
On Wed, Sep 17, 2008 at 09:54:13PM -0700, Ryan Ingram wrote:
 Better is this:
 
 data MalformedAddressException = MalformedAddressException String
 deriving (Show, Typeable)
 
 throwDynIO x = throwIO (DynException $ toDyn x)
You are right.
Anyway the DynException will not be needed in the future because you can
throw arbitrary types directly.. But if you change the code the type
checker won't fail, you'll keep catching the old user error while the
new dyn type is beeing thrown. That's the mess.

The only thing to do is whenever you start using inet_addr implement an
HUnit test to ensure it still throws a user exception.. That's the only
reliable way to get notified if the behaviour changes..
But the strength of haskell is that we don't have to write tests for
everything because the type checker will do most work for us..

Another solution would be telling the compiler that the exception beeing
caught must be thrown within this thread... But that's not possible with
the new SomeException either.
So my result is that Exceptions should not be used here (?) or there
should be an alternative function..

Is that feasable to have to functions so that you can choose?

inet_addr_ThrowEx ?
inet_addr_Maybe ?

Java would have recignized if the exception type changes from user error
to dyn type. Haskell can't :-(

Marc Weber
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Exceptions

2008-09-17 Thread Marc Weber
On Sun, Jul 27, 2008 at 07:23:14PM +0200, Adrian Neumann wrote:
  Hello,
 
  I think it'd be nice if the compiler could warn me if there are any 
  exceptions which I'm not catching, similar to checked exceptions in Java. 
  Does anyone know of a possibility to do that in Haskell?

He, I have found a use case for your request:
from network

inet_addr :: String - IO HostAddress
inet_addr ipstr = do
   withCString ipstr $ \str - do
   had - c_inet_addr str
   if had == -1
then ioError (userError (inet_addr: Malformed address:  ++ ipstr))
else return had  -- network byte order


from HAppS-Server:

host - Exception.catch (inet_addr uri)-- handles ascii IP numbers
   (\_ - getHostByName uri = \host -
case hostAddresses host of
[] - return (error no addresses in host entry)
(h:_) - return h)

Very bad because this catches Exceptions thrown by trowTo as well,
doesn't it?

On the other hand just catching the UserError can be useless if the
maintainers decide to throw a custom Exception in the future (which can
and should be done in the future when extensible exceptions are standard?)

In this case I would miss this update and miss to update the code. If we
could only catch exceptions.
Using Either would be another choice here. But it would lead to much
more code.

Anyway It think using Either is better because it can't lead to code as
shown above.

Another nice use case for Exceptions are timouts as implemented by HAppS
as well.
However I must conclude that a function call including the code above
can just absorb my exception and rethrow another one (or in a worse case
continue?) So maybe I have to change the TimOut code to do a
forever (throwTo threadId TimOutException) to make sure it quits as fast
as possible? This could lead to different trouble.

So I think using Either is the best option although there is some more
code to write.

Marc Weber
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Exceptions

2008-09-17 Thread Ryan Ingram
Better is this:

data MalformedAddressException = MalformedAddressException String
deriving (Show, Typeable)

throwDynIO x = throwIO (DynException $ toDyn x)

-- in inet_error
... throwDynIO (MalformedAddressException blah blah) ...

-- in HAppS-Server
... Exception.catchDyn (inet_addr uri) (\(MalformedAddressException s) - ...)

  -- ryan

On Wed, Sep 17, 2008 at 5:51 PM, Marc Weber [EMAIL PROTECTED] wrote:
 On Sun, Jul 27, 2008 at 07:23:14PM +0200, Adrian Neumann wrote:
  Hello,

  I think it'd be nice if the compiler could warn me if there are any
  exceptions which I'm not catching, similar to checked exceptions in Java.
  Does anyone know of a possibility to do that in Haskell?

 He, I have found a use case for your request:
 from network

 inet_addr :: String - IO HostAddress
 inet_addr ipstr = do
   withCString ipstr $ \str - do
   had - c_inet_addr str
   if had == -1
then ioError (userError (inet_addr: Malformed address:  ++ ipstr))
else return had  -- network byte order


 from HAppS-Server:

 host - Exception.catch (inet_addr uri)-- handles ascii IP numbers
   (\_ - getHostByName uri = \host -
case hostAddresses host of
[] - return (error no addresses in host entry)
(h:_) - return h)

 Very bad because this catches Exceptions thrown by trowTo as well,
 doesn't it?

 On the other hand just catching the UserError can be useless if the
 maintainers decide to throw a custom Exception in the future (which can
 and should be done in the future when extensible exceptions are standard?)

 In this case I would miss this update and miss to update the code. If we
 could only catch exceptions.
 Using Either would be another choice here. But it would lead to much
 more code.

 Anyway It think using Either is better because it can't lead to code as
 shown above.

 Another nice use case for Exceptions are timouts as implemented by HAppS
 as well.
 However I must conclude that a function call including the code above
 can just absorb my exception and rethrow another one (or in a worse case
 continue?) So maybe I have to change the TimOut code to do a
 forever (throwTo threadId TimOutException) to make sure it quits as fast
 as possible? This could lead to different trouble.

 So I think using Either is the best option although there is some more
 code to write.

 Marc Weber
 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Exceptions

2008-07-31 Thread Henning Thielemann

On Sun, 27 Jul 2008, Adrian Neumann wrote:

 Hello,

 I think it'd be nice if the compiler could warn me if there are any
 exceptions which I'm not catching, similar to checked exceptions in
 Java. Does anyone know of a possibility to do that in Haskell?

Please refer to the long extensible extension thread:
   http://www.haskell.org/pipermail/libraries/2008-July/010095.html
  In my posts I sketched possibilities to do that.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Exceptions

2008-07-27 Thread Adrian Neumann

Hello,

I think it'd be nice if the compiler could warn me if there are any  
exceptions which I'm not catching, similar to checked exceptions in  
Java. Does anyone know of a possibility to do that in Haskell?


Adrian


PGP.sig
Description: Signierter Teil der Nachricht
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Exceptions

2008-07-27 Thread Krzysztof Skrzętnicki
I don't really think this is possible: consider asynchronous
exceptions and throwTo.

http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Exception.html#v%3AthrowTo

Since it can throw just *any* exception into thread. And this thread
might not be aware that anyone can throw him anything. Therefore it is
not possible to catch it while compiling it's code.

But Maybe I'm Just wrong.

Christopher Skrzętnicki

2008/7/27 Adrian Neumann [EMAIL PROTECTED]:
 Hello,

 I think it'd be nice if the compiler could warn me if there are any
 exceptions which I'm not catching, similar to checked exceptions in Java.
 Does anyone know of a possibility to do that in Haskell?

 Adrian

 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Exceptions

2008-07-27 Thread Don Stewart
aneumann:
 Hello,
 
 I think it'd be nice if the compiler could warn me if there are any  
 exceptions which I'm not catching, similar to checked exceptions in  
 Java. Does anyone know of a possibility to do that in Haskell?
 
 Adrian

You could provide exception-safe wrappers for the functions you use,
that catch any exception and flatten it to an Either type (or something
similar). Then GHC's usual coverage checking will enforce the handling.


import qualified System.IO
import Control.Exception

maybeReadFile :: FilePath - IO (Maybe String)
maybeReadFile f = handle (\_ - return Nothing)
 (Just `fmap` System.IO.readFile f)

{-
*A maybeReadFile /tmp/DOESNOTEXIST
Nothing
-}

main = do
mf - maybeReadFile DOESNOTEXIST
case mf of
 Nothing - return ()
 Just s  - print s


The ability to control exceptions seems like something we should have more 
solutions for.

-- Don
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Exceptions

2004-10-05 Thread Keith Wansbrough
[+RTS -xc]
 A major problem with this that I notice is that it dumps the stack
 whenever any exception is raised, which is a big pain if your program
 does IO and regularly raises and catches exceptions as part of normal
 operation. A big improvement would be to only dump the backtrace if the
 exception was uncaught and caused the program to abort.

Agreed.  I wrote the -RTS +xc code several years ago, and thought that
what you describe would be much nicer.  But this would have involved
quite a bit more hacking of the RTS.  At the point the exception is
thrown, the backtrace is just sitting there waiting to be dumped.  But
once it's thrown this information is lost.

I imagined wrapping up the backtrace information into a data structure
and including that as an argument to the exception, so that the
primitive catch operation would receive a backtrace in addition to the
exception itself; then the backtrace could be dumped to stderr or
whatever by the default toplevel handler.

In the end I didn't have the motivation to implement this, and I don't
have the same contact with the GHC codebase any more.  I'd be happy to
help anyone who wanted to add this, though, or for someone just to go
ahead and do it...

--KW 8-)

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


RE: [Haskell-cafe] Exceptions

2004-10-04 Thread Simon Peyton-Jones
Actually GHC does exactly that when you compile with -prof -auto-all.
Then if you run with +RTS -xc, you get a backtrace of sorts.  (I have
not tested this recently!)  The backtrace is not yet reified into a data
structure that can be examined, but that'd be quite doable if someone
wanted to try.

The downside is that -prof makes many optimisations work less well, and
all modules must be compiled this way.  

Simon

| -Original Message-
| From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of MR
| K P SCHUPKE
| Sent: 01 October 2004 18:29
| To: [EMAIL PROTECTED]; [EMAIL PROTECTED]
| Cc: [EMAIL PROTECTED]; [EMAIL PROTECTED]
| Subject: Re: [Haskell-cafe] Exceptions
| 
| But, being able to see the context in which a thunk was constructed
would be
| extremely useful.
| 
| Yes of course... I was thinking along the lines of what is possible,
rather
| than what is desirable. If only ghc had a -g (debug) flag like gcc
that would
| force each funtion to push its entry onto some kind of call stack that
would
| be returned by exceptions...
| 
| Keean.
| ___
| Haskell-Cafe mailing list
| [EMAIL PROTECTED]
| http://www.haskell.org/mailman/listinfo/haskell-cafe
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Exceptions

2004-10-04 Thread John Meacham
On Mon, Oct 04, 2004 at 09:30:22AM +0100, Simon Peyton-Jones wrote:
 Actually GHC does exactly that when you compile with -prof -auto-all.
 Then if you run with +RTS -xc, you get a backtrace of sorts.  (I have
 not tested this recently!)  The backtrace is not yet reified into a data
 structure that can be examined, but that'd be quite doable if someone
 wanted to try.

A major problem with this that I notice is that it dumps the stack
whenever any exception is raised, which is a big pain if your program
does IO and regularly raises and catches exceptions as part of normal
operation. A big improvement would be to only dump the backtrace if the
exception was uncaught and caused the program to abort. 
John

-- 
John Meacham - repetae.netjohn 
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Exceptions

2004-10-02 Thread Dominic Steinitz
I'd be cautious about using exceptions too liberally. When I implemented 
a Haskell equivalent to traceroute, I wanted to stop sending packets 
when a certain condition occurred. It was very tempting to throw an 
exception and catch it at the top level. However, I think the code below 
is easier for the maintainer (me) to understand.

Dominic.
sequenceWhile_ :: Monad m = (a - Bool) - [m a] - m ()
sequenceWhile_ p [] =
  return ()
sequenceWhile_ p (x:xs) =
  x = \c - if (p c) then sequenceWhile_ p xs else return ()
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Exceptions

2004-10-01 Thread John Goerzen
One of the most important features of a modern language is, to me,
exceptions.  I have found very little coverage of exceptions in Haskell,
what what coverage there was seemed to be centered on I/O.

One reason I'm asking is this: what to do when pattern matching is
incomplete due to an error.  For instance, this is a common pattern in
my OCaml code:

let queuedir_of_type t = match t with
  foo - /data/queue5
| bar - /data/queue3
| _ - raise (Exception (Invalid type  ^ t));;

This is often useful when t is something that was originally read from
a user.

Python has an expressive exception mechanism, where one can catch
various different exceptions from a single block of code, etc.

So, I have some questions about exceptions in Haskell:

1. Can exceptions be used in pure functions (outside of monads?)

2. How are these exceptions caught and handled aside from using bracket?

3. Can I define my own exception types?

4. Can I write code that can catch and handle multiple different
exception types from a single block of code?

5. Is there anything different about working with exceptions in monads?

6. Can I get a stack trace from ghc or hugs if an exception is never
caught and thus causes the program to terminate?


Thanks!

-- John


___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Exceptions

2004-10-01 Thread MR K P SCHUPKE
1. Can exceptions be used in pure functions (outside of monads?)

Exceptions can be thrown from pure functions, and can be used exactly
like in the OCaml example (but in Haskell syntax)

Exceptions can only be caught in the IO monad.

2. How are these exceptions caught and handled aside from using bracket?

bracket, catch, catchIO 

3. Can I define my own exception types?

There is a User exception type, I don't think you can define your own
completely new exception type.

4. Can I write code that can catch and handle multiple different
exception types from a single block of code?

Yes but see (1) only in the IO monad

5. Is there anything different about working with exceptions in monads?

No.

6. Can I get a stack trace from ghc or hugs if an exception is never
caught and thus causes the program to terminate?

Stack traces in lazy laguages are not very useful. Best work-around is
to produce an explicit call trace by inserting prints into functions...
obviously this requires the functions to be in the IOMonad. Things are
still odd because of lazyness though.

Keean.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Exceptions

2004-10-01 Thread Philippa Cowderoy
On Fri, 1 Oct 2004, John Goerzen wrote:

 1. Can exceptions be used in pure functions (outside of monads?)


No. The Maybe and Either types may make for viable replacements though.

-- 
[EMAIL PROTECTED]
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Exceptions

2004-10-01 Thread John Goerzen
On Friday 01 October 2004 10:57 am, MR K P SCHUPKE wrote:
 1. Can exceptions be used in pure functions (outside of monads?)

 Exceptions can be thrown from pure functions, and can be used exactly
 like in the OCaml example (but in Haskell syntax)

Can you give me a quick example of how exactly I would do that?  I'm 
trying to understand the ghc docs and not quite making it.

Thanks!

-- John
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Exceptions

2004-10-01 Thread Marcin 'Qrczak' Kowalczyk
John Goerzen [EMAIL PROTECTED] writes:

 1. Can exceptions be used in pure functions (outside of monads?)

For the theoretical background of this, see A Semantics for Imprecise
Exceptions http://citeseer.ist.psu.edu/196569.html.

-- 
   __( Marcin Kowalczyk
   \__/   [EMAIL PROTECTED]
^^ http://qrnik.knm.org.pl/~qrczak/
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Exceptions

2004-10-01 Thread Alastair Reid

 6. Can I get a stack trace from ghc or hugs if an exception is never
 caught and thus causes the program to terminate?

 Stack traces in lazy laguages are not very useful. Best work-around is
 to produce an explicit call trace by inserting prints into functions...
 obviously this requires the functions to be in the IOMonad. Things are
 still odd because of lazyness though.

I don't think this is completely true.

What typical Haskell compilers have on their stack is not especially useful 
because it reveals the context in which something was being evaluated and 
will depend on details of the compiler, what optimizations it performs, etc.

But, being able to see the context in which a thunk was constructed would be 
extremely useful.  Such a context would be more or less equivalent to the 
context (or 'stack dump') printed when the same program is evaluated strictly 
- by a Caml compiler, say.  

I think the York folk have the best story on stack traces - I don't know if 
non-deterministic exceptions have been integrated into their system - 
probably so.

--
Alastair Reid

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Exceptions

2004-10-01 Thread Alastair Reid
On Friday 01 October 2004 16:43, John Goerzen wrote:
 One of the most important features of a modern language is, to me,
 exceptions.  I have found very little coverage of exceptions in Haskell,
 what what coverage there was seemed to be centered on I/O.

There's three things one might call exceptions in Haskell:

1) IOErrors result from IO operations and can be caught in the IO monad.

2) Exceptions result from pure or IO code and can be caught in the IO monad.
   They are raised by calling raise (in pure code) or raiseIO (in IO code).
   They are also raised by pattern match failure, calls to error and 
things like division by zero.
   They are non-deterministic in the following sense:

 The expression '(raise exn1) + (raise exn2) :: Int' may raise
 either exception 'exn1' or exception 'exn2' depending on 
 choice of compiler, optimization options, environment settings,
 current time of day, phase of moon, etc.

   It is because of this non-determinism that exceptions can _only_
   be caught in the IO monad.
   Another consequence is that exceptions are not very useful for
reporting errors in user input where determinism, reporting
errors before starting a long computation, being able
to report multiple errors, etc are useful.

3) Error values can be distinguished using the Maybe or Either types
   and/or using monads.  For example, parsing command line arguments
   might yield:

 Right 42

   or

 Left Error: can't parse '42.0' - integer expected

   The advantage of this approach is that the type system tracks where
   errors can propagate to so you can be confident that error checking
   is being performed _before_ spending 3 days computing a result and
   not when you go to write the answer.
   The disadvantage is that it is a bit tedious - but monads, lifting, etc.
   help a lot with this.

In the following, I'll tak exclusively about the 2nd type (since the other two 
are obvious).

 1. Can exceptions be used in pure functions (outside of monads?)

They can be raised in pure functions but can only be caught in IO functions.
(If you simply want to change what exception is reported, that can be done in 
pure code.)

 2. How are these exceptions caught and handled aside from using bracket?

There is a catch function with type:

  catch :: IO a - (Exception - IO a) - IO a

Built on top of this, are functions to do things like try-finally.  One of my 
favourites is 'bracket' which takes an initial action, a final action and a 
middle action (in that order) and makes sure that the final action is 
performed even if the middle action fails.  For example:

  bracket (open /etc/passwd) hClose $ \ h - do
cs - hGetContents h
mapM crack (lines cs)

The strange order of the arguments is to put the initial action (opening the 
file) next to the final action (closing the file) - which is often a good 
thing.

 3. Can I define my own exception types?

Sadly, no.  There is only one 'exception type'.

You can use dynamics and encode new kinds of exceptions as Strings
 but that isn't very satisfactory.

 4. Can I write code that can catch and handle multiple different
 exception types from a single block of code?

You use standard Haskell pattern matching so, yes, you can catch multiple 
kinds of exceptions.  They're not different types though.

 5. Is there anything different about working with exceptions in monads?

Use raiseIO instead of raise to raise exceptions.

 6. Can I get a stack trace from ghc or hugs if an exception is never
 caught and thus causes the program to terminate?

Sadly, no.

--
Alastair Reid
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Exceptions

2004-10-01 Thread MR K P SCHUPKE
But, being able to see the context in which a thunk was constructed would be
extremely useful.

Yes of course... I was thinking along the lines of what is possible, rather
than what is desirable. If only ghc had a -g (debug) flag like gcc that would
force each funtion to push its entry onto some kind of call stack that would
be returned by exceptions...

Keean.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Exceptions

2004-10-01 Thread Niklas Broberg
Alastair Reid wrote:
 3. Can I define my own exception types?
Sadly, no.  There is only one 'exception type'.
You can use dynamics and encode new kinds of exceptions as Strings
 but that isn't very satisfactory.
But not at all, allowing you to declare your own exception types is 
*exactly* what using dynamic exceptions is all about. No need for String 
encodings, we can do far better than that. =)

If I have my own type of exceptions, by making that type an instance of 
Typeable I can use the functions 'throwDyn' and 'catchDyn' instead of the 
normal 'throw' and 'catch'. That way I can declare exception handlers that 
only exceptions of a particular type, and just re-raises any other.

I could for instance write
main = do ... a bunch of computations ...
   `catchDyn` (\e :: MyExceptionType1 - ... handle exceptions of 
MyExceptionType1 ...)
   `catchDyn` (\e :: MyExceptionType2 - ... handle exceptions of 
MyExceptionType2 ...)
   `catch` (\e - ... handle exceptions of the built-in Exceptions type 
...)

(Note that the type annotations on the patterns are not needed if the types 
can be inferred properly from within the handler. Note also that the 
Typeable constraint can be automatically derived by ghc with -fglasgow-exts, 
so no difficulty there either)

Check the section about dynamic exceptions at
http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control.Exception.html
for more info.
 4. Can I write code that can catch and handle multiple different
 exception types from a single block of code?
You use standard Haskell pattern matching so, yes, you can catch multiple
kinds of exceptions.  They're not different types though.
But yes they are, see above. Or rather, they can be, or they can be 
constructors of a common user-defined type, combining common pattern 
matching with dynamic matching on types. =)

 5. Is there anything different about working with exceptions in monads?
Use raiseIO instead of raise to raise exceptions.
The functions for raising exceptions are called 'throw' and 'throwIO' (and 
'throwDyn'), not raise.

/Niklas
_
The new MSN 8: advanced junk mail protection and 2 months FREE* 
http://join.msn.com/?page=features/junkmail

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-04 Thread Ketil Malde
MR K P SCHUPKE [EMAIL PROTECTED] writes:

 As for head, I think it's fine that it throws an error because it is
 specified to be defined for only non-empty lists.

 But surely it is better to encode this fact in the type system by
 useing a separate type for non-empty lists.

Yes, in principle.  But that means you still need to write more and
tedious code to deal with it.  

And there's a question how far you can practically get with this
approach.  Are you going to discard lists in favor of tuples, just
because the type systems can't verify that the index passed to (!!) is
witin range?

 A mechanism for a function to report the caller site would obliviate
 the need for all this ugliness

 Unfortunately the cost of this is prohabative as the call stack
 would have to contain backtrace information. Also due to lazy
 evaluation the 'call site' may not be what you expect.

AFAICS, this disadvantage is shared by all other schemes of labeling
call sites.  The only difference is that I want to do it automatically
(perhaps when a debug option is passed to the compiler)

I don't want it for all functions or anything, just the annoying,
small, and commonly used leaf functions.

 Here's what John Meacham had to say:

 ---
 Note that pattern matching rather than deconstruction functions have a
 number of benefits, not just relating to error messages, consider two
 functions which use the head of their argument.

 f xs = ... head xs ...=20
 g (x:_) = ... x ...

 now, g is superior to f in several ways,=20

I agree with this.  How about constructs like

  mins = map (head.sort)

Is 

   mins = map ((\(x:_)-x).sort)

still so superior?  Is it really necessary to sacrifice code clarity
just to get decent error messages?

And how do you extend this approach to 'read' and (!!)?

-kzm
-- 
If I haven't seen further, it is by standing in the footprints of giants
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-04 Thread MR K P SCHUPKE
Yes, in principle.  But that means you still need to write more and
tedious code to deal with it.

Just because code is tedious does not mean it is not necessary to
handle all corner cases. A robust application does not fail when
given unexpected input.

Are you going to discard lists in favor of tuples,

Of course not... You can actually define constrained datatypes where
the maximum length is a parameter of the type. Unfortunately in haskell
because these values have to be at the type level we end up encoding
them as Peano numbers... See Conor McBrides Faking It paper for
some examples of how to do this. Also see Oleg, Ralf and My paper
Stronly Typed Heterogeneous Lists to se how far you can get with
these techniques (we define a heterogeneous list that can be constrained
in many ways, including by length, or content type).

I guess in a way you are nearly right as these techniques fundamentaly
us binary products like (,) - but thats also exactly what any binary
constructor including ':' is anyway...

The only difference is that I want to do it automatically

My point was that you can manually label some functions, but to automatically
do it for all functions is going to cause big stack space problems - think
about recursive functions... or mutually recursive functions... 

Keean.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-04 Thread MR K P SCHUPKE

mins = map ((\(x:_)-x).sort)

maybe what you meant was:

case sort x of
   (x:_) - ... do whatever with x ...
   _ - ... do failure conition ...

As I said, if you can _guarantee_ non failure I guess head is okay, but the
fact that this thread started with the observation that the error produced
by head is difficault to track dow
n we must conclude that programmers make mistakes and cannot be trusted to
make such guarantees  Hence my suggestion to use the type system.

Effectively the 'case' forms a guarantee of non-emtyness for the stuff in 
the case... but you cannot pass this guarantee into functions like 'head'

Using the type system to encode such things allows this 'guarantee' to
be passed into functions... 

Keean.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-04 Thread David Roundy
On Tue, Aug 03, 2004 at 12:51:50PM +0200, Ketil Malde wrote:
 Is there any easy way (TH?) to amend these to output the line number
 of the offending caller?  It would be a great improvement to see
 something like
 
 Prelude.head : empty list in Foo.hs, line 4711
 
 since programs generally contain many, many calls to functions like
 these.  

I include the following file in most files (and always use the C
preprocessor):

import DarcsUtils ( bug )
#define impossible (bug $ Impossible case at ++__FILE__++:++show (__LINE__ :: 
Int)++ compiled ++__TIME__++ ++__DATE__)

#define fromJust (\m - case m of {Nothing - bug (fromJust error at 
++__FILE__++:++show (__LINE__ :: Int)++ compiled ++__TIME__++ ++__DATE__); Just 
x - x})

Here bug is a function that just calls error with a little prefix
explaining that there is a bug in darcs, and would the user please report
it.  Obviously, defining a head here would be just as easy, but I usually
have more trouble with fromJust, which in a few places gets called in
internal routines where I *should* know that the data structure has no
Nothings, but have been known to make mistakes.

I also catch all error exceptions and print a nicer error message, so I
use fail and error raw to indicate actual user errors.
-- 
David Roundy
http://www.abridgegame.org
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-04 Thread Malcolm Wallace
Ketil Malde [EMAIL PROTECTED] writes:

 Hmm...if I run it through CPP and 
   #define HEAD (\x - if null x then error (__FILE__:__LINE__) else head x)
 is the __LINE__ resolved at the place of declaration or at the place of usage?

According to the C standard, at the position of /usage/ of the macro `HEAD'.

Incidentally, cpphs does not yet implement __FILE__ or __LINE__
replacements.  Is their usage widespread amongst Haskell users?

Regards,
Malcolm
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-04 Thread Ketil Malde
MR K P SCHUPKE [EMAIL PROTECTED] writes:

 mins = map ((\(x:_)-x).sort)

 maybe what you meant was:

   case sort x of
  (x:_) - ... do whatever with x ...
  _ - ... do failure conition ...

No, I don't think so.  I only want the bug to be reported, and the
umatched pattern will do it nicely.

 Yes, in principle.  But that means you still need to write more and
 tedious code to deal with it.

 Just because code is tedious does not mean it is not necessary to
 handle all corner cases. A robust application does not fail when
 given unexpected input.

But if I use head, I should *know* that I never pass it an
empty list.  Whether head returns a Nothing or just crashes doesn't
matter, I have to go and fix my *design*, because it has a bug,
and not a corner case that should be handled.

 Are you going to discard lists in favor of tuples,

 Of course not... You can actually define constrained datatypes where
 the maximum length is a parameter of the type. 

The only difference is that I want to do it automatically

 My point was that you can manually label some functions, but to automatically
 do it for all functions is going to cause big stack space problems - think
 about recursive functions... or mutually recursive functions... 

Yes, of course.  So *my* point is that it would be really nice to
write small leaf functions like these with an implicit file/line
parameter that identified the caller site, in order to avoid
cluttering the code with them.

Okay, perhaps I'm not using the type system to its full extent, but I
think this is fairly common practice.  

An easy solution seems to be to use -cpp and add

   #define head (\(x:_)-x)

at the top of the relevant source files.  However, I'm not sure how to
make this work with the other difficult functions.  Another
alternative (basically emulating the GHC's behavior in the above case)
is

   #define head (\x - case x of {(x:_) - x; _ - error (head failed at 
++__FILE__++:++ show __LINE__)})

It seems difficult to generalize this, though.

-kzm
-- 
If I haven't seen further, it is by standing in the footprints of giants
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-04 Thread MR K P SCHUPKE
No, I don't think so.  I only want the bug to be reported   

I think preventing the bug using the type system if possible is a good
idea... something that should be encouraged!

and not a corner case that should be handled.

So if the list depends on user input is not the empty list a corner
case of the function on user input?

write small leaf functions like these with an implicit file/line

This is a good idea - If I have given the impression I am opposed to it 
then I have not expressed myself very well. I just think where this can
be avoided using the type system in the first place is an even better
idea. Design by contract is the way forward for large complex systems, 
and where that contract can be expressed using the type system is
a selling point for Haskell in such applications.

It seems difficult to generalize this, though.

Again for read you can use reads...

Sven Panne said:

reads is probably what you are looking for:

Prelude (reads :: ReadS Integer) 
[]
Prelude (reads :: ReadS Integer) a
[]
Prelude (reads :: ReadS Integer) 2
[(2,)]
Prelude (reads :: ReadS Integer) 123blah
[(123,blah)]


Keean.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-04 Thread Ketil Malde
David Roundy [EMAIL PROTECTED] writes:

 Here bug is a function that just calls error with a little prefix
 explaining that there is a bug in darcs, and would the user please report
 it.  Obviously, defining a head here would be just as easy,

Cool!  The basic trick is just to inline the actual function
defintions using CPP macros.  I've made macros for most of the
troublesome functions, but I can't get it to work for operators
(something like `(!!)` doesn't parse, it seems)  Any tricks?

Unless I'm overlooking something, I could have a file prelude.h
containing something like:

8--
import Prelude hiding (head,(!!),read)

#define head (\xs - case xs of { (x:_) - x ; _ - bug head __FILE__ __LINE__})
#define at (let {at (y:_) 0  = y; at (y:ys) n = at ys (n-1); at _ _ = bug at 
__FILE__ __LINE__} in \a x - at a x)
#define read (\s - case [ x | (x,t) - reads s, (,) - lex t] of { [x] - x ; _ 
- bug read __FILE__ __LINE__})
#define fromJust (\x - case x of Just a - a; Nothing - bug fromJust __FILE__ 
__LINE__)

bug c f l = error (Program error - illegal parameters to '++c++', file '++f++', 
line ++show l)
8--

and just #include prelude.h if/when I want better debugging.  No
expensive stack frames, no unwanted strictness, and no clutter.

Any comments?

-kzm
-- 
If I haven't seen further, it is by standing in the footprints of giants
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-04 Thread Ketil Malde
Ketil Malde [EMAIL PROTECTED] writes:

 Unless I'm overlooking something

Which I of course did.

 #define at (let {at (y:_) 0  = y; at (y:ys) n = at ys (n-1); at _ _ = bug at 
 __FILE__ __LINE__} in \a x - at a x)

No prize for spotting the bug here.

-kzm
-- 
If I haven't seen further, it is by standing in the footprints of giants
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-04 Thread Ketil Malde
Ketil Malde [EMAIL PROTECTED] writes:

 import Prelude hiding (head,(!!),read)

 Any comments?

Here's one: I thought this would make it difficult to have other
imports of Prelude, hiding other pieces of it (e.g. catch, to avoid
ambiguities with Control.Exception.catch)

(Also, the definition of 'bug' hinders forces the #include to be after
any imports, not sure it's better to have a separate module for it,
which would then need to be on the module search path)

(I seem to be mainly following up to my own posts, so if somebody
asks, I'll take this to a quiet corner at the -cafe :-) 

-kzm
-- 
If I haven't seen further, it is by standing in the footprints of giants
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-03 Thread Graham Klyne
Two observations:
1. When I recently modified the HaXml XML parser, this is one of the 
significant changes I made:  providing (alterantive) return values based on 
Either, so that input errors could be handled by the invoking function, 
without forcing it into the IO monad.  I guess that's a vote of agreement.

2. I like to distinguish between expected errors and unexpected 
errors.  Having been burned in the past by using exceptions (not FP), I 
try to use them only for conditions that are truly unexpected; i.e. 
_exceptional_.  Bad input, IMO, is something that is not unexpected, so I 
don't really like to handle that via exceptions.

#g
--
At 13:09 02/08/04 -0700, Evan LaForge wrote:
Exceptions are convenient in that you can rely on libraries throwing them
instead of prechecking for valid values yourself (for instance, why check
that the argument to Char.digitToInt is valid if digitToInt does so already),
and you don't have to modify a lot of function signatures.  Unfortunately, in
the face of lazy evaluation, they can get thrown in unexpected places.  Even
with Exception.evaluate, or code which is already explicitly sequenced in the
IO monad, like t - Exception.evaluate (map Char.digitToInt ['a'..'g']) an
exception will only be thrown when you inspect the last element of 't'.
(digitToInt confusingly accepts hex digits---shouldn't it be higitToInt
then?).
So it seems to me that if you are, say, checking input, the options are
to handle exceptions from the checking code but expect them to come from the
processing code, or decorate all checking code with Rights and Lefts.
Problems with the first option are that checking code could also trigger some
exceptions, and Prelude functions throw undescriptive errors like user
error or low level ones like refuted pattern match and catching them over
the entire program means you could stifle a lot of real errors. This implies
that you have to make specific exceptions and convert Prelude and library
exceptions into yours as low down as possible, which is cluttering but maybe
not as cluttering as Either.  Problems with the second option are many of the
problems that lead to us wanting exceptions in the first place.
Using Either seems much simpler and functional-friendly.  So then, in what
contexts are exceptions appropriate in haskell?
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Graham Klyne
For email:
http://www.ninebynine.org/#Contact
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-03 Thread Ketil Malde
Graham Klyne [EMAIL PROTECTED] writes:

 2. I like to distinguish between expected errors and unexpected
 errors.  Having been burned in the past by using exceptions (not FP),
 I try to use them only for conditions that are truly unexpected;
 i.e. _exceptional_.  Bad input, IMO, is something that is not
 unexpected, so I don't really like to handle that via exceptions.

I agree, trying to handle exceptions caused by incorrect input is just
needless complication, the program should crash, and the calling
function should be fixed instead. 

Common errors that happen to me are:

   Prelude.head : empty list
   Prelude.read : no parse
andPrelude.(!!) : index too large
and so on.
   
Is there any easy way (TH?) to amend these to output the line number
of the offending caller?  It would be a great improvement to see
something like

Prelude.head : empty list in Foo.hs, line 4711

since programs generally contain many, many calls to functions like
these.  

-kzm 
-- 
If I haven't seen further, it is by standing in the footprints of giants
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-03 Thread Bjoern Knafla
Hi - I am just learning Haskell and am far away from exception handling 
intricacies. However I just recently read an article of Herb Sutter 
about exception handling in C++ with some rules when to use exception 
handling - and perhaps these rules might be applicable to Haskell too 
(article: When and How to Use Exceptions, Herb Sutter, C/C++ Users 
Journal August 2004, pp. 47 -- 51)?

Herb Sutter gave these rules :
An error is any failure that prevents a function from succeeding. Three 
main kind of errors:
- a condition that prevents the function from meeting a precondition of 
another function that must be called (so to say: the caller has to 
check for preconditions while the function called my use C/C++ asserts 
to assert the correctness of its preconditions)

- a condition that prevents a function from establishing one of its own 
postconditions (e.g. producing a (valid) return value)

- a condition that prevents the function from reestablishing an 
invariant that it is responsible to maintain (special kind of 
postcondition mainly found in object oriented code).


Any other condition is not an error and shouldn't be reported as one.
The code that could cause an error is responsible for detecting and 
reporting the error otherwise this is a programming mistake.


I am not sure if these rules apply to real functional programming but 
at least they seem to be useable. The point that the caller is 
responsible for checking the preconditions of functions it is calling 
is something I also found as a suggestion in using the object oriented 
language Eiffel.

Cheers and best regards
Bjoern
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-03 Thread Marcin 'Qrczak' Kowalczyk
W licie z wto, 03-08-2004, godz. 13:05 +0200, Bjoern Knafla napisa:

 Herb Sutter gave these rules :
 
 An error is any failure that prevents a function from succeeding. Three 
 main kind of errors:
[...]

These kinds don't explain much. They don't give a clue which errors
to report by exceptions and which by return values, because they don't
distinguish the reasons for which a (pre|post)condition can't be
fulfilled. And I see no point in distinguishing potential errors on
this axis.

I divide exceptional situations into 4 groups:

1. Expected error: The result can't be computed from this data; the
   caller was not supposed to check this beforehand because it would
   duplicate work of the function, or there would be a race condition,
   or the design is simpler that way.

2. Program error: The given function was not supposed to be invoked
   in this way by other parts of the program (with these arguments,
   or with this external state, in this order wrt. other functions
   etc.).

3. Out of resource: The function is sorry that it was not able to
   produce the result due to limited memory or arithmetic precision
   or similar resources. Not yet supported is also in this group.

4. Impossible error: The function thought this couldn't happen, it must
   have a bug. This is like 2 in that there is a bug somewhere, but like
   1 in that the calling code is probably fine.

I/O errors can be expected errors or out of resource conditions,
depending on whether they were caused by bad input or by external
failure.

Group 1 should be reported in Haskell by a distinguished result (Maybe,
Either, custom type) or by an exception passed in a suitable monad
(well, Maybe is a monad; this could be even the IO monad).

Other groups are handled in a similar way. In Haskell they can be
reported by a bottom, e.g. 'error' function. It makes sense to catch
them on a toplevel of the program or a large unit, and it's good that
GHC provides a way to catch them. There may be other actions possible
than just aborting the program: report the problem to the user, abort
just the given operation, but try to continue other work; save user data
before aborting; log the error or report it in an appropriate channel,
e.g. output a HTML page in case of a CGI program.

Sometimes the same function makes sense in two variants: one which
reports an expected error, and another which treats it as a program
error. Example: lookup in a dictionary.

Sometimes the qualification of an error changes while it is propagated.
I haven't thought about all cases, but for example program errors become
impossible errors if the caller thought that the arguments it passed
were good, and expected errors become program errors if the caller's
caller was not supposed to give arguments which cause such problems.

The most important distinction is between expected errors, whose way of
reporting should be visible in the interface and which should be checked
for in the calling code, and program errors, which should be
automatically propagated and reported near the toplevel.

-- 
   __( Marcin Kowalczyk
   \__/   [EMAIL PROTECTED]
^^ http://qrnik.knm.org.pl/~qrczak/

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-03 Thread Keith Wansbrough
 Exceptions should only really be used for unpredictcable events, I find
 that the defintion of functions like head is lacking rigor... I would 
 prefer to see:
 
 head :: [a] - Maybe a
 head (a0:_) = Just a0
 head _ = Nothing

In principle, yes, but in practice, that would be silly.  You use
head just when you know for sure that the list is non-empty; if it
is not, it's a program error for head, and an impossible error for
the caller.  Consider:

f (head xs)  -- old style

vs

f (case head xs of Some x - x; None - error whoops)  -- Schupke style

It should be clear that this function would never be used - if head
had this signature, programmers would just write

f (case xs of (x:_) - x; [] - error whoops)  -- direct style

--KW 8-)

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-03 Thread MR K P SCHUPKE
f (case xs of (x:_) - x; [] - error whoops)  -- direct style

Yup, this is how I do it... I never use head!

I like to pass failures back up to the level where some kind of sensible 
error message can be generated. In your example the error is no
better than with 'head' - the point is a Nothing can be 'caught' 
outside of an IO monad. 

I would suggest using the type system as I said earlier so:

toNonEmptyList :: [a] - Maybe (NonEmpty a)
toNonEmptyList (a0:_) = Just (NonEmpty a)
toNonEmptyList _ = Nothing

Then redefine head:

head :: NonEmpty a - a
head (NonEmpty (a0:_)) = a0


Keean/
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-03 Thread Alastair Reid

Prelude.head : empty list
Prelude.read : no parse
 andPrelude.(!!) : index too large
 and so on.

 Is there any easy way (TH?) to amend these to output the line number
 of the offending caller?

In a program of any size, I usually avoid using these functions and instead 
define functions like:

  --| 1st arg is error message for empty lists 
  head' :: Doc - [a] - a

  --| 1st arg is description of kind of thing in list
  --  Reports error if length of list /= 1
  unique :: Doc - [a] - a

etc.

Another approach is to use a function:

  inContext :: String - a - a

(implemented using mapException) like this:

  inContext evaluating expression (eval env e)

to transform an exception of the form:

   error Division by zero

into

   error Division by zero while evaluating expression

Since the inContext function is rather like ghc's profiling function 'scc', it 
would be nice if ghc had a command-line flag to insert a call to inContext 
everywhere that it inserts a call to scc when you use -prof-all.  (Of course, 
you'd probably take a big stack-space hit from doing so since the chain of 
calls to inContext is equivalent to the stack you would expect if using call 
by value without tail call optimization.

--
Alastair Reid

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-03 Thread Evan LaForge

 A lot of programming errors come from failure to correctly validate.

This was actually nicely illustrated in my program: I assumed that digitToInt
accepted '0'..'9' and wanted to rely on it throwing.  After puzzling over
out of range errors (other functions expected digitToInt to be in the 0..9
range) I figured it out and inserted an explicit check.  Unfortunately there
is no static check for pre and post conditions, unless you manually add them
to the type system, as you suggest.  But that's work ;)

Wrting a monad bind for Either that returns Left immediately and binds Right
would make Either style error propagation easier.  But it seems like it would
over sequence:

do a' - checka a
   b' - checkb b
   return $ process a' b'

is rather messier looking than 'process (checka a) (checkb b)'.  It doesn't
really matter what order 'a' and 'b' are checked, what I really want is the
monad-style magic plumbing.  I suppose I should just wrap 'process' in a
liftM2 and stop worrying about it.

 Of course you must make sure you don't write more than
 one constructor function for ValidInt. This suggests a

Can't you do this at the module level by exporting the ValidInt type, but not
the constructor?  Of course, then you have to stick it in its own module, and
simple range validation is getting even more heavyweight...



In response to the mysterious head exceptions thread, isn't there a way to
compile with profiling and then get the rts to give a traceback on exception?
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-03 Thread Graham Klyne
At 15:28 03/08/04 +0100, MR K P SCHUPKE wrote:
f (case xs of (x:_) - x; [] - error whoops)  -- direct style
Yup, this is how I do it... I never use head!
As a general principle, this bothers me.
In the longer term (i.e. if and when large-scale production Haskell systems 
become common), and as a matter of principle, I think it's better to use a 
prelude (or standard) function when one will do the job, because a 
widely-used industrial strength compiler might well have special 
knowledge of these and be able to apply special optimizations (as, e.g., 
some C/C++ compilers do for standard library functions like memcpy).

As for head, I think it's fine that it throws an error because it is 
specified to be defined for only non-empty lists.  (I remain silent on 
whether the prelude should contain a head-like function that returns a 
value for empty lists.)

#g

Graham Klyne
For email:
http://www.ninebynine.org/#Contact
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-03 Thread Ketil Malde
MR K P SCHUPKE [EMAIL PROTECTED] writes:

 head :: [a] - Maybe a
 head (a0:_) = Just a0
 head _ = Nothing

Argh, no!  Violating the precondition of head is a bug in the caller,
I want it to crash, but I also want to know where.  Wrapping it up in
Maybe (or any other error propagation) is not a solution. 

I don't want to write a lot of unwrapping code in all the callers,
just to get a trackable error message in the (few) cases where I'm
using the function incorrectly.

Neither do I want to write

(\x - if null x then error (__FILE__:__LINE__) else head x)

everywhere instead of head, nor pollute my code with error tracking, but
otherwise meaningless strings. (Which is what I generally do when I
get this kind of anonymous error.  if null x then error foo else
head x.

A mechanism for a function to report the caller site would obliviate
the need for all this ugliness.

-kzm

Hmm...if I run it through CPP and 
  #define HEAD (\x - if null x then error (__FILE__:__LINE__) else head x)
is the __LINE__ resolved at the place of declaration or at the place of usage?
-- 
If I haven't seen further, it is by standing in the footprints of giants
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-03 Thread Fergus Henderson
On 03-Aug-2004, Evan LaForge [EMAIL PROTECTED] wrote:
 
 In response to the mysterious head exceptions thread, isn't there a way to
 compile with profiling and then get the rts to give a traceback on exception?

There is, but it doesn't really work properly, due to
- lazy evaluation
- tail call optimization
- lack of line numbers in the traceback

-- 
Fergus J. Henderson |  I have always known that the pursuit
Galois Connections, Inc.|  of excellence is a lethal habit
Phone: +1 503 626 6616  | -- the last words of T. S. Garp.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] exceptions vs. Either

2004-08-03 Thread David Menendez
David Menendez writes:

 MR K P SCHUPKE writes:
 
  I would suggest using the type system as I said earlier so:
  
  toNonEmptyList :: [a] - Maybe (NonEmpty a)
  toNonEmptyList (a0:_) = Just (NonEmpty a)
  toNonEmptyList _ = Nothing
  
  Then redefine head:
  
  head :: NonEmpty a - a
  head (NonEmpty (a0:_)) = a0
 
 Oleg described a similar technique a few months ago.
 
 From http://haskell.org/pipermail/haskell/2004-June/014271.html:
 
 | newtype NonEmpty a = NonEmpty [a] -- the NonEmpty constructor
should
 | -- be hidden (not exported from its module)
 |
 | head' (NonEmpty a) = head a -- no error can occur! Can use unsafe
 version
 | tail' (NonEmpty a) = tail a -- no error can occur! Can use unsafe
 version
 |
 | -- trusted function: the only one that can use NonEmpty
constructor.
 | fork_list_len f g x = if null x then f else g (NonEmpty x)
 |
 | revers x  = revers' x []
 |  where
 |revers' x accum = fork_list_len accum (g accum) x
 |g accum x = revers' (tail' x) ((head' x):accum)
 
 We have these equivalences:
 
 toNonEmptyList== fork_list_len Nothing Just
 fork_list_len d f == maybe d f . toNonEmptyList
 
 I think defining 'toNonEmptyList' in terms of 'fork_list_len' is
 cleaner, but that's just my personal taste. (As it happens, I ended up
 defining a very similar function 'cons' in my recursion module[1]).
 
 [1]
 http://www.eyrie.org/~zednenem/2004/hsce/Control.Recursion.html#v%
 3Acons
-- 
David Menendez [EMAIL PROTECTED] http://www.eyrie.org/~zednenem/
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe