Ticket #2798 (closed task: fixed)

Opened 5 years ago

Last modified 3 years ago

Enable "rec" keyword when RecursiveDo is enabled?

Reported by: nominolo Owned by: igloo
Priority: high Milestone: 7.0.1
Component: Compiler Version: 6.11
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Difficulty: Unknown
Test Case: Blocked By:
Blocking: Related Tickets:

Description

GHC supports recursive statement groups marked by the keyword rec, however this is only activated via a hack. Consider this (silly) example program:

{-# LANGUAGE RecursiveDo, Arrows #-}

main :: IO ()

main =
 mdo x <- return (length [1..42::Int])
     rec b <- return x
         let a = const c
         c <- print "x"
     return (a b)

The Arrow language needs to be enabled, otherwise the rec keyword wouldn't be recognised. Currently this behaviour is undocumented, and rec groups only appear in the internal AST.

This ticket has been created to have a documented decsion whether this feature is supported or not. Given that GHC automatically identifies strongly-connected components and re-groups things (although it cannot re-order statements due to probable dependencies) having an explicet rec keyword probably isn't that useful. In particular

mdo foo   ...is equivalent to...      mdo rec foo
    bar                                       bar
    baz                                   baz

Thoughts?

Change History

  Changed 5 years ago by ross

The idea of "rec" was to use it with plain "do", to indicate feedback explicitly as an alternative to using "mdo". Many users of arrow notation prefer to do that. As you say, it's not much use together with "mdo".

follow-up: ↓ 3   Changed 5 years ago by simonpj

  • difficulty set to Unknown

I think the reason for 'mdo' was by analogy with 'let' and 'where': just say "use recursion" and let the compiler sort out the details. I have forgotten whether the same choice could be made for arrows, or whether 'rec' is essential there.

I don't feel strongly about this. I suppose we could do any of these:

  • Remove 'rec' altogether (including from arrows i.e. 'proc')
  • Remove 'mdo' and use 'do rec' instead
  • Allow 'rec' in 'do' as well as in 'proc'
  • Status quo ('rec' in 'proc' but not in 'do')

Simon

in reply to: ↑ 2   Changed 5 years ago by claus

Replying to simonpj:

I think the reason for 'mdo' was by analogy with 'let' and 'where': just say "use recursion" and let the compiler sort out the details.

I have often wanted a non-recursive 'let' as well as the current 'let rec'. It would get rid of many unreadable '-ed names and silly bugs. 'do', with non-recursive bindings by default, and recursive bindings possible, is slightly more pleasant in this regard (though the syntactic differences between pure and monadic bindings are too awkward). Unfortunately, that nice and simple distinction is out of reach for 'let' (too much code out there), but "let the compiler sort out the details" is good only if programmers still have control, and renaming is not the nicest way of exercising such control.

* Remove 'mdo' and use 'do rec' instead

Without bias to the actual choice, the name 'mdo' is unfortunate - I doubt it makes sense to Haskell newcomers, nor does it evoke useful semantic associations.

  Changed 4 years ago by igloo

  • milestone set to 6.12 branch

  Changed 4 years ago by igloo

  • priority changed from normal to high
  • milestone changed from 6.12 branch to 6.12.1

6.12.1 would be a good time to come to a decision about this.

  Changed 4 years ago by simonmar

We (Simon & Simon) think the ideal state of affairs would be:

  • Allow rec in do (as Ross intended)
  • Deprecate mdo

as far as flags go, there are two options:

  • have the existing RecursiveDo flag enable the new rec syntax, and deprecate the use of mdo. Eventually mdo would be removed as a keyword.
  • Define a new extension, e.g. DoRec for the new rec keyword, and deprecate the old RecursiveDo extension.

The second approach has the benefit that we can identify obsolete code on Hackage without trying to compile it, but it means having two similarly-named extensions which could lead to confusion.

  Changed 4 years ago by duncan

I don't think I'd bother with changing the extension name. We can discover deprecated stuff on hackage automatically by other (more general) means.

  Changed 4 years ago by isaacdupree

my feeling is to prefer DoRec -- it sounds more mnemonic to me; and it seems unpleasant for an extension to have two substantially different parsings that might conflict with existing code (if 'rec' is a variable name somewhere). e.g. how will haskell-src[-exts] deal with it after the Summer-of-Code effort? But I don't really mind either way. (P.S. do we have a way to mark extension-flags deprecated?) -Isaac

  Changed 4 years ago by isaacdupree

so if you want your code to compile on pre-6.12 you can:

- just use mdo

- use rec and enable Arrows also (I guess this hack could be, but shouldn't be, sanctioned by Cabal.. among other things, Arrows also introduces proc as a keyword, so it's not harmless)

  Changed 4 years ago by igloo

Extensions can be marked deprecated in xFlags in compiler/main/DynFlags.hs.

  Changed 4 years ago by igloo

  • owner set to igloo

  Changed 4 years ago by igloo

  • milestone changed from 6.12.1 to 6.14.1

Won't be done in time for 6.12.1.

  Changed 3 years ago by igloo

  • status changed from new to closed
  • failure set to None/Unknown
  • resolution set to fixed

It was done for 6.12.1 after all. RecursiveDo is deprecated in favour of DoRec.

Note: See TracTickets for help on using tickets.