Difference between revisions of "Ifthenelse"
(→Why breaking lots of old and unmaintained code?: Changed the hawiki link for HaskellTwo to point to the Web Archive) 
m (Improved layout) 

Line 1:  Line 1:  
== Replace syntactic sugar by a function == 
== Replace syntactic sugar by a function == 

−  For processing conditions, 

⚫  
−  the <hask>ifthenelse</hask> syntax was defined in Haskell98. 

⚫  
−  with 

<haskell> 
<haskell> 

if' :: Bool > a > a > a 
if' :: Bool > a > a > a 

Line 16:  Line 13:  
=== Advantages === 
=== Advantages === 

−  The advantages of the function <hask>if'</hask> 

+  The advantages of the function <hask>if'</hask> over the syntax <hask>ifthenelse</hask> are the same like for all such alternatives. So let me repeat two important nonsyntactic strengths of Haskell: 

−  over the syntax <hask>ifthenelse</hask> 

−  are the same like for all such alternatives. 

−  So let me repeat two important nonsyntactic strengths of Haskell: 

* types: classification, documentation 
* types: classification, documentation 

* higher order functions: combinators 
* higher order functions: combinators 

−  If <hask>if'</hask> would be a regular function, 

+  If <hask>if'</hask> would be a regular function, each language tool can process it without hassle. Haddock can generate documentation for it, a text editor can make suggestions for values to insert, Hoogle can retrieve that function. 

−  each language tool can process it without hassle. 

−  Haddock can generate documentation for it, 

−  a text editor can make suggestions for values to insert, 

−  Hoogle can retrieve that function. 

For example, the Hoogle query 
For example, the Hoogle query 

Line 42:  Line 32:  
=== Use cases === 
=== Use cases === 

−  Each of the following functions could be defined in terms of <hask>if'</hask>. 
+  Each of the following functions could be defined in terms of <hask>if'</hask>. Actually, they do not even need to be in Prelude because they can be constructed so easily. 
−  Actually, they do not even need to be in Prelude 

−  because they can be constructed so easily. 

−  That function is harder to explain in English, 
+  That function is harder to explain in English, than by its implementation. :) 
−  than by its implementation. :) 

<haskell> 
<haskell> 

zipIf :: [Bool] > [a] > [a] > [a] 
zipIf :: [Bool] > [a] > [a] > [a] 

Line 57:  Line 47:  
</haskell> 
</haskell> 

−  From a list of expressions choose the one, 
+  From a list of expressions choose the one, whose condition is true. The first parameter is the default value. It is returned if no condition applies. 
−  whose condition is true. 

−  The first parameter is the default value. 

−  It is returned if no condition applies. 

<haskell> 
<haskell> 

select :: a > [(Bool, a)] > a 
select :: a > [(Bool, a)] > a 

Line 73:  Line 63:  
=== Why add this function to Prelude? === 
=== Why add this function to Prelude? === 

−  Actually people could define <hask>if'</hask> in each module, 

+  Actually people could define <hask>if'</hask> in each module, where they need it, or import it from a <hask>Utility</hask> module, that must be provided in each project. Both solutions are tedious and contradict to modularization and software reusage. The central question is, whether <hask>if'</hask> is an idiom, that is so general that it should be in the Prelude, or not. I think it is, otherwise it wouldn't have get a special syntax. 

−  where they need it, 

−  or import it from a <hask>Utility</hask> module, 

−  that must be provided in each project. 

−  Both solutions are tedious and 

−  contradict to modularization and software reusage. 

−  The central question is, whether <hask>if'</hask> is an idiom, 

−  that is so general that it should be in the Prelude, or not. 

−  I think it is, otherwise it wouldn't have get a special syntax. 

=== IfThenElse vs. guards === 
=== IfThenElse vs. guards === 

Some people (any exact statistics?) prefer guards to <hask>ifthenelse</hask>. 
Some people (any exact statistics?) prefer guards to <hask>ifthenelse</hask>. 

−  This practice has its own drawbacks, 
+  This practice has its own drawbacks, see [[Syntactic sugar/Cons]] and [[Things to avoid]]. 
−  see [[Syntactic sugar/Cons]] and [[Things to avoid]]. 

<! 
<! 

−  The default case is always builtin 
+  The default case is always builtin and needs no extra compiler check. Compare 
−  and needs no extra compiler check. 

−  Compare 

<haskell> 
<haskell> 

flipCond cond (x,y)  cond = (x,y) 
flipCond cond (x,y)  cond = (x,y) 

Line 101:  Line 83:  
=== Is IfThenElse so important? === 
=== Is IfThenElse so important? === 

−  Counting <hask>ifthenelse</hask> or <hask>if'</hask> 
+  Counting <hask>ifthenelse</hask> or <hask>if'</hask> in today's Haskell programs isn't a good measure for the importance a <hask>if'</hask> function, because 
−  in today's Haskell programs 

−  isn't a good measure for the importance a <hask>if'</hask> function, 

−  because 

* frequently guards are used instead of <hask>ifthenelse</hask> 
* frequently guards are used instead of <hask>ifthenelse</hask> 

* there is no standard function, and this let people stick to workarounds. 
* there is no standard function, and this let people stick to workarounds. 

Line 107:  Line 89:  
=== What is so bad about the ifthenelse sugar? === 
=== What is so bad about the ifthenelse sugar? === 

−  Since syntactic sugar introduces its own syntactic rules, 

+  Since syntactic sugar introduces its own syntactic rules, it is hard to predict how it interferes with other syntactic constructs. This special syntax for instance led to conflicts with do notation. A [http://hackage.haskell.org/trac/haskellprime/wiki/DoAndIfThenElse syntactic extension] to solve this problem is proposed for Haskell'. It is not known what conflicts this extension might cause in future. 

−  it is hard to predict how it interferes with other syntactic constructs. 

−  This special syntax for instance led to conflicts with do notation. 

−  A [http://hackage.haskell.org/trac/haskellprime/wiki/DoAndIfThenElse syntactic extension] to solve this problem is proposed for Haskell'. 

−  It is not known what conflicts this extension might cause in future. 

=== Why breaking lots of old and unmaintained code? === 
=== Why breaking lots of old and unmaintained code? === 

−  Haskell without <hask>ifthenelse</hask> syntax 

+  Haskell without <hask>ifthenelse</hask> syntax makes Haskell more logical and consistent. There is no longer confusion to beginners like: "What is so special about ifthenelse, that it needs a separate syntax? I though it could be simply replaced by a function. Maybe there is some subtlety that I'm not able to see right now." There is no longer confusion with the interference of 

−  makes Haskell more logical and consistent. 

+  <hask>ifthenelse</hask> syntax with <hask>do</hask> notation. Removing <hask>ifthenelse</hask> simplifies every language tool, say compiler, text editor, analyzer and so on. 

−  There is no longer confusion to beginners like: 

−  "What is so special about ifthenelse, that it needs a separate syntax? 

−  I though it could be simply replaced by a function. 

−  Maybe there is some subtlety that I'm not able to see right now." 

−  There is no longer confusion with the interference of 

−  <hask>ifthenelse</hask> syntax with <hask>do</hask> notation. 

−  Removing <hask>ifthenelse</hask> simplifies every language tool, 

−  say compiler, text editor, analyzer and so on. 

−  If we arrive at [[Haskell two]] some day, ([https://web.archive.org/web/20061011095312/http://haskell.org/hawiki/HaskellTwo http://haskell.org/hawiki/HaskellTwo] (Web Archive)) 
+  If we arrive at [[Haskell two]] some day, ([https://web.archive.org/web/20061011095312/http://haskell.org/hawiki/HaskellTwo http://haskell.org/hawiki/HaskellTwo] (Web Archive)) it will certainly be incompatible to former Haskell versions. This does not mean, that old code must be thrown away. 
−  +  There should be one tool, that converts Haskell 98 and Haskell' to Haskell2. 

−  +  Having '''one''' tool for this purpose is better than blowing '''all''' language tools with legacy code. Syntactic replacements like <hask>ifthenelse</hask> syntax to <hask>if'</hask> function should be especially simple. 

−  There should be one tool, 

−  that converts Haskell 98 and Haskell' to Haskell2. 

−  Having '''one''' tool for this purpose 

−  is better than blowing '''all''' language tools with legacy code. 

−  Syntactic replacements like <hask>ifthenelse</hask> syntax to 

−  <hask>if'</hask> function should be especially simple. 

=== Summary === 
=== Summary === 

Line 145:  Line 115:  
== Objections == 
== Objections == 

−  Haskell is not intended to be a minimalistic language, 

+  Haskell is not intended to be a minimalistic language, but to be one that is easy to read. <hask>ifthenelse</hask> resembles a phrase from English language. It shows clearly which expression is returned on a fulfilled condition, and which one is returned for an unsatisfied condition. It is thus easier to read. The special syntax saves parentheses around its arguments. 

−  but to be one that is easy to read. 

−  <hask>ifthenelse</hask> resembles a phrase from English language. 

−  It shows clearly which expression is returned on a fulfilled condition, 

−  and which one is returned for an unsatisfied condition. 

−  It is thus easier to read. 

−  The special syntax saves parentheses around its arguments. 

If properly indented, like 
If properly indented, like 

<haskell> 
<haskell> 
Revision as of 11:14, 19 December 2016
Replace syntactic sugar by a function
For processing conditions, the ifthenelse
syntax was defined in Haskell98. However it could be simply replaced by the function if'
with
if' :: Bool > a > a > a
if' True x _ = x
if' False _ y = y
Unfortunately there is no such function in the Prelude.
Advocacy
Advantages
The advantages of the function if'
over the syntax ifthenelse
are the same like for all such alternatives. So let me repeat two important nonsyntactic strengths of Haskell:
 types: classification, documentation
 higher order functions: combinators
If if'
would be a regular function, each language tool can process it without hassle. Haddock can generate documentation for it, a text editor can make suggestions for values to insert, Hoogle can retrieve that function.
For example, the Hoogle query
[Bool] > [a] > [a] > [a]
may return
zipWith3 if'
Use cases
Each of the following functions could be defined in terms of if'
. Actually, they do not even need to be in Prelude because they can be constructed so easily.
That function is harder to explain in English, than by its implementation. :)
zipIf :: [Bool] > [a] > [a] > [a]
zipIf = zipWith3 if'
Infix version. This duplicates the ternary operator of Clike languages, and can be used: (cond ? exp1 $ exp2)
. Additionally, Church booleans can be represented compactly by sectioning on (?), i.e. (True?) = const; (False?) = flip const
infixr 1 ?
(?) :: Bool > a > a > a
(?) = if'
From a list of expressions choose the one, whose condition is true. The first parameter is the default value. It is returned if no condition applies.
select :: a > [(Bool, a)] > a
select = foldr (uncurry if')
See Case.
Easy lifting into monads (MonadReader in this case)
ifF :: (a > Bool) > (a > b) > (a > b) > (a > b)
ifF = liftM3 if'
Why add this function to Prelude?
Actually people could define if'
in each module, where they need it, or import it from a Utility
module, that must be provided in each project. Both solutions are tedious and contradict to modularization and software reusage. The central question is, whether if'
is an idiom, that is so general that it should be in the Prelude, or not. I think it is, otherwise it wouldn't have get a special syntax.
IfThenElse vs. guards
Some people (any exact statistics?) prefer guards to ifthenelse
.
This practice has its own drawbacks, see Syntactic sugar/Cons and Things to avoid.
Is IfThenElse so important?
Counting ifthenelse
or if'
in today's Haskell programs isn't a good measure for the importance a if'
function, because
 frequently guards are used instead of
ifthenelse
 there is no standard function, and this let people stick to workarounds.
What is so bad about the ifthenelse sugar?
Since syntactic sugar introduces its own syntactic rules, it is hard to predict how it interferes with other syntactic constructs. This special syntax for instance led to conflicts with do notation. A syntactic extension to solve this problem is proposed for Haskell'. It is not known what conflicts this extension might cause in future.
Why breaking lots of old and unmaintained code?
Haskell without ifthenelse
syntax makes Haskell more logical and consistent. There is no longer confusion to beginners like: "What is so special about ifthenelse, that it needs a separate syntax? I though it could be simply replaced by a function. Maybe there is some subtlety that I'm not able to see right now." There is no longer confusion with the interference of
ifthenelse
syntax with do
notation. Removing ifthenelse
simplifies every language tool, say compiler, text editor, analyzer and so on.
If we arrive at Haskell two some day, (http://haskell.org/hawiki/HaskellTwo (Web Archive)) it will certainly be incompatible to former Haskell versions. This does not mean, that old code must be thrown away.
There should be one tool, that converts Haskell 98 and Haskell' to Haskell2.
Having one tool for this purpose is better than blowing all language tools with legacy code. Syntactic replacements like ifthenelse
syntax to if'
function should be especially simple.
Summary
 Light proposal, compatible with Haskell 98: Add
if'
to the Prelude, maybe with a different name.  Full proposal, incompatible with Haskell 98 and Haskell': Additionally remove
ifthenelse
syntax
See also
Objections
Haskell is not intended to be a minimalistic language, but to be one that is easy to read. ifthenelse
resembles a phrase from English language. It shows clearly which expression is returned on a fulfilled condition, and which one is returned for an unsatisfied condition. It is thus easier to read. The special syntax saves parentheses around its arguments.
If properly indented, like
if a
then b
else c
or
if a
then b else c
then there is no conflict with the do
notation.