[GHC] #11706: Increase precedence of statements (if-then-else, case-of, do)

GHC ghc-devs at haskell.org
Mon Mar 14 00:40:19 UTC 2016


#11706: Increase precedence of statements (if-then-else, case-of, do)
-------------------------------------+-------------------------------------
           Reporter:  YoYoYonnY      |             Owner:
               Type:  feature        |            Status:  new
  request                            |
           Priority:  lowest         |         Milestone:  ⊥
          Component:  Compiler       |           Version:
  (Parser)                           |
           Keywords:                 |  Operating System:  Unknown/Multiple
       Architecture:                 |   Type of failure:  None/Unknown
  Unknown/Multiple                   |
          Test Case:                 |        Blocked By:
           Blocking:                 |   Related Tickets:
Differential Rev(s):                 |         Wiki Page:
-------------------------------------+-------------------------------------
 Warning: Skip to the {{{TL; DR}}}, and maybe the {{{How it works}}}
 section; You don't want to read this. (I've warned you.)

 == The problem ==

 We do it all the time: Writing that one dollar sign just before our
 expressions, just because Haskell can't parse it:

 {{{#!hs
 f x = g $ if x then {- ... -} else {- ... -}
 f x = g $ case x of {- ... -}
 f x = g $ do {- ... -}
 }}}

 However, we programmers are lazy and want to type as few characters as
 possible. Think about the precious characters we would save if we could
 write code this way:

 {{{#!hs
 f x = g if x then {- ... -} else {- ... -}
 f x = g case x of {- ... -}
 f x = g do {- ... -}
 }}}

 Wow, our productivity just shot up by a whopping 6%!

 However, this code looks ugly, noone would ever write this... Right?
 There has to be some way to catagorize this feature with others people
 would never use...

 == Pragmas to the rescue! ==

 The {{{LANGUAGE}}} pragma! Of course! We can add a syntactic extension to
 enable above syntax! But how should we name it...

 {{{InlineStatements}}}? {{{InfixStatements}}}?
 {{{ParenthesizedStatements}}}? {{{IncreasedStatementPrecedence}}}?
 {{{StatementsWithoutParenthesis}}}?

 I don't know. I am [1] not the parents who might one day give birth to
 this feature. I am merely the one who conceptualized it.

 [1] (probably, unless this request remains unnoticed for another 20 years
 or so)

 == How it works ==

  * Implicit parenthesis will be put around ''all'' statements, according
 to the following rules:
   1. Parenthesis will be opened at the start of the statement.
   2. Parenthesis will be closed at the end of the statement. The end of
 the statement is determined by
    1. The curly brackets around the statement, or;
    2. The indentation of the statement

 Basically, these are the rule Haskell already uses.

 Sorry if this is obvious, but some people seemed to get confused, so
 here's some examples:

 === (Correct) Examples ===

 Examples are in the form:

 {{{#!hs
 implicitParenthesis -- New syntax

 explicitParenthesis -- Old syntax
 }}}

 Call {{{idM :: Monad m => m a -> m a}}} as {{{idM :: IO String -> IO
 String}}}.

 {{{#!hs
 idM do
     putStrLn "What's my name?"
     getLine

 idM (do { putStrLn "What's my name?"; getLine; })
 }}}

 Create function {{{whatsMyName :: Maybe String -> String}}}.

 {{{#!hs
 whatsMyName x = id case x of
     Just name = "My name is " ++ name
     Nothing = "What's my name?"

 whatsMyName x = id (case x of { Just name = "My name is " ++ name; Nothing
 = "What's my name?"; })
 }}}

 Another example using {{{let}}} and {{{if-then-else}}}.

 {{{#!hs
 main = putStrLn
     (++)
         "I've been tryna work it out... The square root of 69 is 8
 something, right? "
         let
             eight_something = 8.306623862918075
           in if sqrt 69 == eight_something
             then "Yeah"
             else "Oh na na"

 main = putStrLn ((++) "I've been tryna work it out... The square root of
 69 is 8 something, right? " (let eight_something = 8.306623862918075 in
 (if sqrt 69 == eight_something then "Yeah" else "Oh na na"))
 }}}

 === Incorrect examples ===

 {{{#!hs
 f do
     putStrLn "This won't work..."
   True

 f (do { putStrLn "This won't work..."; True; })
 }}}

 {{{#!hs
 f
     do
         putStrLn "This won't work..."
      True -- Indented by extra space

 f (do { putStrLn "This won't work..."; True; })
 }}}

 == TL; DR ==

 What there is:

 {{{#!hs

 main = when  $ do putStrLn "Parenthesis..."
 main = when True (do putStrLn "Parenthesis...")

 }}}

 What I want:

 {{{#!hs

 when (doBlocksNeedParenthesis) do putStrLn "This code is invalid."
 when (doBlocksNeedParenthesis) $ do putStrLn "This code is valid."
 when (doBlocksNeedParenthesis) (do putStrLn "This code is valid aswell.")
 when (thisIsImplemented) do putStrLn "These are all equal"
 when (thisIsImplemented) (do putStrLn "These are all equal")
 when (thisIsImplemented) $ do putStrLn "These are all equal"

 }}}

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11706>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list