[Haskell-cafe] Bool is not...safe?!

Paul aquagnu at gmail.com
Sat Jul 7 05:15:12 UTC 2018


By the way, there are a lot of articles why checked exceptions are bad design (more problems than benefit).

More interesting for me is this snippet:

case (action :: Either err a) of
   Right result -> ...
   Left err -> deal_with err

Somebody says me that to use Bool in such way is “not safe” because no way to know what does “True” returning from “action” mean. Success or failure? But with some ADT (Success|Failure) code is more Haskellish and safe.

But is it true? We are talking about semantics, not type-safety because type-checker passes both cases (positive branch under False/Failure, negative branch under True/Success). But the same with Right/Left: nothing says you to use Right for positive and Left for error case. Is it true?

Bool is algebra <1, 0, +, *> or more familiar <T, F, |, &> (let’s ignore other operations). We are talking about semantics and not TYPE safety. Semantic is not here <T, F>, semantic is here: <|, &>. You can use Right for negative branch processing if you have only types. Type system can not save you from such “bug”. But operational model – can. Semantic of Either is here: < (>>=), return, fail >. Operation “>>=” forces you to treat Right for positive case (otherwise, your code mixing with other Eithers will have strange behaviour). The same with Bool, short-circuit operations describe semantic and force you to use True for happy-ways:

e1 || e2

e2 will be evaluated only if e1 leads to false. In Bash: command e2 will be executed only if e1 fails (no False, any number =/= 0). The semantic is defining by operations, not types (operations “interpret” values and are linked with semantics), and they are similar in case of Either and Bool. So, Bool type is not less safe then Either. Changing of convenient leads to the same problems in both cases: strange behaviour.

Problem with Haskell is that it’s imperative and not declarative language. Haskell can not work with “behaviour”, behaviour can not be “lifted” to type system which lives at compile-time only. If type-checker passes – all is good. So, “pure $ print 1” is right in Haskell but mostly it’s error. IMHO root of the problem is more deep than talking about types.

The root of the problem is that imperative nature of Haskell leads to missing term “evaluation to something”. Haskell program is not evaluated expression and in the same as in Java or C: it is IO action. But in Prolog every piece of code is evaluated to TRUTH or to FALSE. Each sentence is a goal which can be achieved and becomes a fact or can not be – and becomes lie. So, if you inverse semantic in Haskell – program is compiled although with strange behaviour but in Prolog program become lie. Prolog evaluation model has clean definition in run-time too, not only at compile-time. Execution of Prolog program is a CHECK: is it truth or lie? Strange behaviour of Haskell == lie in Prolog (at run-time). You will get answer “No.” (for example). It’s dialog with MU-TH-UR 6000 or HAL-9000 😊 not execution of some action.


From: Joachim Durchholz
Sent: 6 июля 2018 г. 23:36
To: haskell-cafe at haskell.org
Subject: Re: [Haskell-cafe] Bool is not...safe?!

Am 06.07.2018 um 22:04 schrieb Olaf Klinke:
> 
>> Am 05.07.2018 um 22:39 schrieb Olga Ershova <blaze at ruddy.ru>:
>>
>>
>>
>> On Thu, Jul 5, 2018 at 4:27 PM Olaf Klinke <olf at aatal-apotheke.de> wrote:
>> Does anyone know whether the C and C++ folks are now using more informative structs as return types?
>>   
>> When returning errors, they call them "exceptions".

True but not really.
C does not have exceptions, so C APIs have always been returning 
discriminated unions.
C++ exceptions tend to be used in different ways, sometimes like Olga 
says, sometimes differently.

> Quite so. One might say that the equivalent of try...catch blocks in Haskell is the pattern match
> 
> case (action :: Either err a) of
>    Right result -> ...
>    Left err -> deal_with err

That's kind of how "checked exceptions" in Java work: You declare them 
in the function signature.

> But what keeps bugging me about exceptions is this: When working with libraries having nested dependencies, is there a way of knowing the complete set of exceptions that might be thrown by a block of code?

So for checked exceptions you know what may go up.
I.e. it's really equivalent to pattern matching.

"Unchecked" exceptions are not declared.
I.e. you can use them as untyped pattern match.

> It is generally considered bad style to write a catch-all. Instead, only catch the exceptions you know how to deal with. But if I don't know
what can be thrown, then I can not make my code bullet-proof. The
explicit return type seems the clearer approach to this problem.

Not generally actually.
At the top level, you do indeed catch all exceptions, as a signal that 
the called computation failed.
Typical reactions to that are:
- Abort the program.
- Log the error and wait for the next request (background programs).
- Report an error message to the user (interactive programs).
- Retry (a useful strategy if nondeterminism is involved).
- Fall back to a simpler strategy (for really large software systems).
Some design philosophies do this not just at the top level, but at each 
intermediate level. Some systems are built using "monitor layers", 
modules that do this kind of subtask monitoring and report an exception 
only if retrying or falling back didn't work.

Regards,
Jo
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20180707/c5161eb6/attachment.html>


More information about the Haskell-Cafe mailing list