It is really good to think in terms of a cleverness budget. Every additional feature is not only implementation work, but also maintenance, extra cognitive overhead when adding new features, an extra thing for tooling outside of GHC to support. Personally, I'm on the wall on this one. Here are the things I see in favor of this proposal:
1) It is common practice to use -Wall. Infact, I think it should be a default, and should include more warnings than -Wall (-fwarn-tabs -fwarn-incomplete-uni-patterns -fwarn-incomplete-record-updates -fwarn-identities) 2) It lets us do things that are otherwise quite inconvenient. We can now easily shadow a bunch of identifiers without explicitly hiding them. Things I see against it: 1) It feels like a complicated way to avoid needing a "hiding ()" clause on your imports. 2) There is no good way to use this feature without creating a warning. I would like to be explicit in my name shadowing I'm thinking a pragma like {-# NO_WARN myFunction #-}, or, better yet, the more specific {-# SHADOWING myFunction #-} orso. What if instead we re-framed this as a "top-level where clause", like this: main :: IO () main = putStrLn ("Hi" <> "There") other-function :: IO () other-function = putStrLn ("I can " <> "also use it") -- NOTE: 0 indent! where (<>) :: String -> String -> String (<>) = (++) I would also like to see this extension enabling other top level declarations in where clauses, except not typeclasses. I have discussed this before, IIRC, with Richard, and there was some complexity getting local data types playing well with scoped type variables. It seems like a very worthwhile extension in its own right. I like this top-level where clause, because it riffs on existing syntax. Also, there isn't very much danger in someone accidentally dedenting their where clause to 0 level and not realizing it. The only danger there is if they were also simultaneously relying on scope shadowing (and somehow the types still work out). -Michael On Wed, Oct 5, 2016 at 9:35 AM, Christopher Allen <c...@bitemyapp.com> wrote: > I agree with Tom on this. This isn't a good way to spend the cleverness > budget. > > On Wed, Oct 5, 2016 at 11:34 AM, <amin...@gmail.com> wrote: >> I'm weakly against this proposal. I may compile with -Wall, but I read code >> by many people who don't. When I'm browsing a file and see e.g. >> >> import Network.Socket >> >> and then later in the file, I see a reference to "recvFrom", I currently >> know exactly what function is being called. I don't want to have to search >> around every time to make sure a function wasn't redefined in some dark >> corner of the module. >> >> This allows too much "sneakiness" for my taste. >> >> Tom >> >> >>> On Oct 3, 2016, at 04:29, Herbert Valerio Riedel <hvrie...@gmail.com> wrote: >>> >>> Hi *, >>> >>> I seem to recall this was already suggested in the past, but I can't >>> seem to find it in the archives. For simplicity I'll restate the idea: >>> >>> >>> foo :: Int -> Int -> (Int,Int) >>> foo x y = (bar x, bar y) >>> where >>> bar x = x+x >>> >>> results merely in a name-shadowing warning (for -Wall): >>> >>> foo.hs:4:9: warning: [-Wname-shadowing] >>> This binding for ‘x’ shadows the existing binding >>> bound at foo.hs:2:5 >>> >>> >>> However, >>> >>> import Data.Monoid >>> >>> (<>) :: String -> String -> String >>> (<>) = (++) >>> >>> main :: IO () >>> main = putStrLn ("Hi" <> "There") >>> >>> doesn't allow to shadow (<>), but rather complains about ambiguity: >>> >>> bar.hs:7:23: error: >>> Ambiguous occurrence ‘<>’ >>> It could refer to either ‘Data.Monoid.<>’, >>> imported from ‘Data.Monoid’ at bar.hs:1:1-18 >>> or ‘Main.<>’, defined at bar.hs:4:1 >>> >>> >>> This is of course in line with the Haskell Report, which says in >>> https://www.haskell.org/onlinereport/haskell2010/haskellch5.html#x11-1010005.3 >>> >>> | The entities exported by a module may be brought into scope in another >>> | module with an import declaration at the beginning of the module. The >>> | import declaration names the module to be imported and optionally >>> | specifies the entities to be imported. A single module may be imported >>> | by more than one import declaration. Imported names serve as top level >>> | declarations: they scope over the entire body of the module but may be >>> | shadowed by *local non-top-level bindings.* >>> >>> >>> However, why don't we allow this to be relaxed via a new language >>> extensions, to allow top-level bindings to shadow imported names (and >>> of course emit a warning)? >>> >>> Unless I'm missing something, this would help to keep existing and >>> working code compiling if new versions of libraries start exporting new >>> symbols (which happen to clash with local top-level defs), rather than >>> resulting in a fatal name-clash; and have no major downsides. >>> >>> If this sounds like a good idea, I'll happily promote this into a proper >>> proposal over at https://github.com/ghc-proposals/ghc-proposals; I >>> mostly wanted to get early feedback here (and possibly find out if and >>> where this was proposed before), before investing more time turning >>> this into a fully fledged GHC proposal. >>> >>> Cheers, >>> HVR >>> _______________________________________________ >>> ghc-devs mailing list >>> ghc-devs@haskell.org >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs >> _______________________________________________ >> ghc-devs mailing list >> ghc-devs@haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs > > > > -- > Chris Allen > Currently working on http://haskellbook.com > _______________________________________________ > ghc-devs mailing list > ghc-devs@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs