if-then without -else?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

if-then without -else?

Johannes Waldmann-2
Dear Cafe,

a student in my class detected
this inconsistency in the design of Haskell:

> Why require that each "if-then" has an "else"
> while still allowing incomplete sets of patterns?
> We could define "if p then a"
> by translating to "case p of { True -> a }"

I think that "but then we'd have the dangling-else problem"
is not a good answer because this is really about semantics,
not surface syntax.

For reference, Scheme has short-if, see
http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-14.html#node_sec_11.4.3
(value is "unspecified" if condition is false)
and Common LISP does as well
https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node84.html#SECTION001160000000000000000
(value is "nil")

Was this considered at some point in Haskell's design process?
There is Section 5.2 on pattern matching in
http://haskell.cs.yale.edu/wp-content/uploads/2011/02/history.pdf (*)
but it does not mention if-then(-else).

- J.W.

(*) can we please add this to https://www.haskell.org/documentation
Upvote this: https://github.com/haskell-infra/hl/issues/86
_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|

Re: if-then without -else?

Arjen
On Mon, 2018-07-09 at 19:20 +0200, Johannes Waldmann wrote:
> Dear Cafe,
>
> a student in my class detected
> this inconsistency in the design of Haskell:
>
> > Why require that each "if-then" has an "else"
> > while still allowing incomplete sets of patterns?
> > We could define "if p then a"
> > by translating to "case p of { True -> a }"

This is the same as (case p of { True -> a; _ -> throw
PatternDoesNotMatchException }). Therefore (if False then a) would give
an exception.

Normally, every expression has a value. The value of (if p then x else
y) is properly defined. What would be the value of (if p then x)? If it
is (), then x should also have type (), I think.

You can do something like that in a Monad, and the function is called
when. And there is an unless, which is an if-else without a then.

> I think that "but then we'd have the dangling-else problem"
> is not a good answer because this is really about semantics,
> not surface syntax.
>
> For reference, Scheme has short-if, see
> http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-14.html#node_sec_11.4.3
> (value is "unspecified" if condition is false)
> and Common LISP does as well
> https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node84.html#SECTION001
> 160000000000000000
> (value is "nil")
>
> Was this considered at some point in Haskell's design process?
> There is Section 5.2 on pattern matching in
> http://haskell.cs.yale.edu/wp-content/uploads/2011/02/history.pdf (*)
> but it does not mention if-then(-else).
>
> - J.W.
>
> (*) can we please add this to https://www.haskell.org/documentation
> Upvote this: https://github.com/haskell-infra/hl/issues/86
> _______________________________________________
>

Hope this helps and kind regards, Arjen
_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|

Re: if-then without -else?

Johannes Waldmann-2
In reply to this post by Johannes Waldmann-2
> Therefore (if False then a) would give an exception.

Yes. And the question is, why is possible to write
this program using "case" but not with "if".

For the first part (allow incomplete sets of patterns in "case"):

No matter how hard we try, Haskell is not a total language -
there'll always be programs that denote bottom,
by raising exceptions (e.g., from incomplete patterns),
or by non-termination - which cannot be prohibited statically
if we want both the language to be Turing complete,
and type inference to be decidable.

Cf. Agda, which is total, and therefore
has a coverage checker (for patterns)
as well as a termination checker.

But then the second part (do not allow incomplete "if")
appears to be an inconsistency in the design.

Mind you - I don't propose to change this.
The question is just about justification for the design.

Are there applications for an incomplete "if"?
I can imagine something like assertions,
as in "f x = if some-precondition x then some-computation x"
Of course, that's only helpful if the exception
contains source information.

- J.W.
_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|

Re: if-then without -else?

Andrey Sverdlichenko
In hindsight, maybe non-exhaustive case expression should be errors, not warnings. But then adding new constructor to the type could break existing code in multiple places, even if constructor is never used. Not everybody ready to pay this price.

For the "if" expressions, condition type is always Bool with two constructors, so enforcing totality looks like natural choice here.

On Mon, Jul 9, 2018 at 2:40 PM Johannes Waldmann <[hidden email]> wrote:
> Therefore (if False then a) would give an exception.

Yes. And the question is, why is possible to write
this program using "case" but not with "if".

For the first part (allow incomplete sets of patterns in "case"):

No matter how hard we try, Haskell is not a total language -
there'll always be programs that denote bottom,
by raising exceptions (e.g., from incomplete patterns),
or by non-termination - which cannot be prohibited statically
if we want both the language to be Turing complete,
and type inference to be decidable.

Cf. Agda, which is total, and therefore
has a coverage checker (for patterns)
as well as a termination checker.

But then the second part (do not allow incomplete "if")
appears to be an inconsistency in the design.

Mind you - I don't propose to change this.
The question is just about justification for the design.

Are there applications for an incomplete "if"?
I can imagine something like assertions,
as in "f x = if some-precondition x then some-computation x"
Of course, that's only helpful if the exception
contains source information.

- J.W.
_______________________________________________
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.

_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|

Re: if-then without -else?

Tom Ellis-5
In reply to this post by Johannes Waldmann-2
On Mon, Jul 09, 2018 at 08:39:49PM +0200, Johannes Waldmann wrote:
> > Therefore (if False then a) would give an exception.
>
> Yes. And the question is, why is possible to write
> this program using "case" but not with "if".

Because the error conditions around case were badly designed.  My
understanding is that a large majority of Haskell developers believe that it
should not be possible to omit a branch in a case statement.
_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|

Re: if-then without -else?

Paul
In reply to this post by Andrey Sverdlichenko

If-without-else implies “empty-else”. It’s possible in monad context in “return ()” form. There are “when”, “unless” functions already. But in pure context “empty-else” can not imply empty result for “else” branch (what value should be used in “else” branch?). Empty-if exists in most languages in statements, i.e. under “IO a”, but not in expressions, so “a ? x : y” in C/C++, “x if a else y” in Python needs “else” branch. Non-exhaustive case is like “if ... then ... else undefined” IMHO.

 

 

 

From: [hidden email]
Sent: 9 июля 2018 г. 21:55
To: [hidden email]
Cc: [hidden email]
Subject: Re: [Haskell-cafe] if-then without -else?

 

In hindsight, maybe non-exhaustive case expression should be errors, not warnings. But then adding new constructor to the type could break existing code in multiple places, even if constructor is never used. Not everybody ready to pay this price.

For the "if" expressions, condition type is always Bool with two constructors, so enforcing totality looks like natural choice here.

 

On Mon, Jul 9, 2018 at 2:40 PM Johannes Waldmann <[hidden email]> wrote:

> Therefore (if False then a) would give an exception.

Yes. And the question is, why is possible to write
this program using "case" but not with "if".

For the first part (allow incomplete sets of patterns in "case"):

No matter how hard we try, Haskell is not a total language -
there'll always be programs that denote bottom,
by raising exceptions (e.g., from incomplete patterns),
or by non-termination - which cannot be prohibited statically
if we want both the language to be Turing complete,
and type inference to be decidable.

Cf. Agda, which is total, and therefore
has a coverage checker (for patterns)
as well as a termination checker.

But then the second part (do not allow incomplete "if")
appears to be an inconsistency in the design.

Mind you - I don't propose to change this.
The question is just about justification for the design.

Are there applications for an incomplete "if"?
I can imagine something like assertions,
as in "f x = if some-precondition x then some-computation x"
Of course, that's only helpful if the exception
contains source information.

- J.W.
_______________________________________________
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.

 


_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|

Re: if-then without -else?

David Feuer
In reply to this post by Johannes Waldmann-2
If-then-else is a syntactic convenience. Missing cases are usually wrong. We don't want to go out of our way to make it convenient to write wrong code.

On Mon, Jul 9, 2018, 1:20 PM Johannes Waldmann <[hidden email]> wrote:
Dear Cafe,

a student in my class detected
this inconsistency in the design of Haskell:

> Why require that each "if-then" has an "else"
> while still allowing incomplete sets of patterns?
> We could define "if p then a"
> by translating to "case p of { True -> a }"

I think that "but then we'd have the dangling-else problem"
is not a good answer because this is really about semantics,
not surface syntax.

For reference, Scheme has short-if, see
http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-14.html#node_sec_11.4.3
(value is "unspecified" if condition is false)
and Common LISP does as well
https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node84.html#SECTION001160000000000000000
(value is "nil")

Was this considered at some point in Haskell's design process?
There is Section 5.2 on pattern matching in
http://haskell.cs.yale.edu/wp-content/uploads/2011/02/history.pdf (*)
but it does not mention if-then(-else).

- J.W.

(*) can we please add this to https://www.haskell.org/documentation
Upvote this: https://github.com/haskell-infra/hl/issues/86
_______________________________________________
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.

_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|

Re: if-then without -else?

Stefan Monnier
In reply to this post by Johannes Waldmann-2
> Was this considered at some point in Haskell's design process?

I don't know, but such an `if .. then` without `else` would encourage
bad coding practices, IMO.

On a related note: in C and friends if can do

   if () { .... };

but you can't do

   int x = E1 ? E2;

So, even those pragmatic people (including those C++ people who like to
include not just the kitchen sink but the surrounding farm as
well) agree with Haskell's designers.


        Stefan

_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|

Re: if-then without -else?

Neil Mayhew
In reply to this post by Andrey Sverdlichenko
On 2018-07-09 12:54 PM, Olga Ershova wrote:
In hindsight, maybe non-exhaustive case expression should be errors, not warnings. But then adding new constructor to the type could break existing code in multiple places, even if constructor is never used. Not everybody ready to pay this price.

You make a good point, and this is the best explanation I've seen in this discussion. However, even if the constructor is never used in your own code, it may well be used in library code that you call. I think it's dangerous for for the programmer not to know when a new constructor is added. I prefer to have this warning enabled, and my policy is to use -Wall -Werror from the start of any new project. I then turn off specific warnings (eg orphans) with a pragma in individual source files when I really need to use something.

I was interested to see that GHC allows you to turn any warning into an error, so I assume Haskell could be made total for pattern matching with:

-Werror=incomplete-patterns

_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|

Re: if-then without -else?

J. Garrett Morris-5
In reply to this post by Johannes Waldmann-2
On Mon, Jul 9, 2018 at 12:20 PM Johannes Waldmann
<[hidden email]> wrote:
> > Why require that each "if-then" has an "else"
> > while still allowing incomplete sets of patterns?
> > We could define "if p then a"
> > by translating to "case p of { True -> a }"

Hi Johannes,

`if p then a` can only ever have value `a`, so why not just write `a`
in the first place?

Of course, it could fail to evaluate... but that's not something (as a
Haskell 1.0 program anyway) you could detect or recover.

Incomplete case matches, in contrast, can do meaningful things---to
name parts of a data structure, or perhaps reflecting a
programmer-believed invariant.  Sure, they let in degenerate cases,
like `case p of {True -> a}`, but that's different from adding syntax
to the language that only expresses degenerate cases.

 /g
_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|

Re: if-then without -else?

AntC
In reply to this post by Johannes Waldmann-2
> Why require that each "if-then" has an "else"

Never mind the semantics, this is a piece of syntactic history.

ALGOL 60 allowed omitted "else". That gave ambiguity:

if p
then if q
then ...
...
else ...

There was no layout rule. Does the "else" match to the outer "if-then" or the inner?

BCPL ~1965 had two constructs

if p
then test q
then ...
...
else ...

"if-then" has no "else". If you want an "else" use "test-then-else".


AntC

_______________________________________________
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.
Reply | Threaded
Open this post in threaded view
|

Re: if-then without -else?

Albert Y. C. Lai
In reply to this post by Johannes Waldmann-2
On 2018-07-09 01:20 PM, Johannes Waldmann wrote:

> a student in my class detected
> this inconsistency in the design of Haskell:
>
>> Why require that each "if-then" has an "else"
>> while still allowing incomplete sets of patterns?
>> We could define "if p then a"
>> by translating to "case p of { True -> a }"
>
> I think that "but then we'd have the dangling-else problem"
> is not a good answer because this is really about semantics,
> not surface syntax.

Anthony Clayden is right that if-then-else has the benefit of giving an
unambiguous grammar.

if-then can be made unambiguous if you throw in delimiting, e.g.,
if-then-fi, if-then-begin-end.

Suppose you like to support if-then (and have your disambiguation story)
on the ground that case-of-True is already supported, and you don't mind
the partiality, then why stop there?

Why is if-else getting no love from you?  Afterall, case-of-False is
already supported, too.

 >:)
_______________________________________________
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.