Re: Reducing the need for CPP (was: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`)

2015-10-06 Thread Johan Tibell
It might be enough to just add a NOWARN  pragma that acts on
a single line/expression. I've seen it in both C++ and Python linters and
it works reasonably well and it's quite general.

On Tue, Oct 6, 2015 at 10:44 AM, Ben Gamari  wrote:

> Sven Panne  writes:
>
> > 2015-10-05 17:09 GMT+02:00 Gershom B :
> >
> >> On October 5, 2015 at 10:59:35 AM, Bryan O'Sullivan (b...@serpentine.com
> )
> >> wrote:
> >> [...] As for libraries, it has been pointed out, I believe, that without
> >> CPP one can write instances compatible with AMP, and also with AMP +
> MRP.
> >> One can also write code, sans CPP, compatible with pre- and post- AMP.
> [...]
> >>
> >
> > Nope, at least not if you care about -Wall: If you take e.g. (<$>) which
> is
> > now part of the Prelude, you can't simply import some compatibility
> module,
> > because GHC might tell you (rightfully) that that import is redundant,
> > because (<$>) is already visible through the Prelude. So you'll have to
> use
> > CPP to avoid that import on base >= 4.8, be it from it Data.Functor,
> > Control.Applicative or some compat-* module. And you'll have to use CPP
> in
> > each and every module using <$> then, unless I miss something obvious.
> > AFAICT all transitioning guides ignore -Wall and friends...
> >
> This is a fair point that comes up fairly often. The fact that CPP is
> required to silence redundant import warnings is quite unfortunate.
> Others languages have better stories in this area. One example is Rust,
> which has a quite flexible `#[allow(...)]` pragma which can be used to
> acknowledge and silence a wide variety of warnings and lints [1].
>
> I can think of a few ways (some better than others) how we might
> introduce a similar idea for import redundancy checks in Haskell,
>
>  1. Attach a `{-# ALLOW redundant_import #-}` pragma to a definition,
>
> -- in Control.Applicative
> {-# ALLOW redundant_import (<$>) #-}
> (<$>) :: (a -> b) -> f a -> f b
> (<$>) = fmap
>
> asking the compiler to pretend that any import of the symbol did not
> exist when looking for redundant imports. This would allow library
> authors to appropriately mark definitions when they are moved,
> saving downstream users from having to make any change whatsoever.
>
>  2. Or alternatively we could make this a idea a bit more precise,
>
> -- in Control.Applicative
> {-# ALLOW redundant_import Prelude.(<$>) #-}
> (<$>) :: (a -> b) -> f a -> f b
> (<$>) = fmap
>
> Which would ignore imports of `Control.Applicative.(<$>)` only if
> `Prelude.(<$>)` were also in scope.
>
>  3. Attach a `{-# ALLOW redundancy_import #-}` pragma to an import,
>
> import {-# ALLOW redundant_import #-} Control.Applicative
>
> -- or perhaps
> import Control.Applicative
> {-# ALLOW redundant_import Control.Applicative #-}
>
> allowing the user to explicitly state that they are aware that this
> import may be redundant.
>
>  4. Attach a `{-# ALLOW redundancy_import #-}` pragma to a name in an
> import list,
>
> import Control.Applicative ((<$>) {-# ALLOW redundant_import #-})
>
> allowing the user to explicitly state that they are aware that this
> imported function may be redundant.
>
> In general I'd like to reiterate that many of the comments in this
> thread describe genuine sharp edges in our language which have presented
> a real cost in developer time during the AMP and and FTP transitions. I
> think it is worth thinking of ways to soften these edges; we may be
> surprised how easy it is to fix some of them.
>
> - Ben
>
>
> [1] https://doc.rust-lang.org/stable/reference.html#lint-check-attributes
>
> ___
> Libraries mailing list
> librar...@haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>
>
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-prime


Re: Reducing the need for CPP (was: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`)

2015-10-06 Thread Jan-Willem Maessen
On Tue, Oct 6, 2015 at 4:44 AM, Ben Gamari  wrote:

> Sven Panne  writes:
>
> > 2015-10-05 17:09 GMT+02:00 Gershom B :
> >
> >> On October 5, 2015 at 10:59:35 AM, Bryan O'Sullivan (b...@serpentine.com
> )
> >> wrote:
> >> [...] As for libraries, it has been pointed out, I believe, that without
> >> CPP one can write instances compatible with AMP, and also with AMP +
> MRP.
> >> One can also write code, sans CPP, compatible with pre- and post- AMP.
> [...]
> >>
> >
> > Nope, at least not if you care about -Wall: If you take e.g. (<$>) which
> is
> > now part of the Prelude, you can't simply import some compatibility
> module,
> > because GHC might tell you (rightfully) that that import is redundant,
> > because (<$>) is already visible through the Prelude. So you'll have to
> use
> > CPP to avoid that import on base >= 4.8, be it from it Data.Functor,
> > Control.Applicative or some compat-* module. And you'll have to use CPP
> in
> > each and every module using <$> then, unless I miss something obvious.
> > AFAICT all transitioning guides ignore -Wall and friends...
> >
> This is a fair point that comes up fairly often. The fact that CPP is
> required to silence redundant import warnings is quite unfortunate.
> Others languages have better stories in this area. One example is Rust,
> which has a quite flexible `#[allow(...)]` pragma which can be used to
> acknowledge and silence a wide variety of warnings and lints [1].
>
> I can think of a few ways (some better than others) how we might
> introduce a similar idea for import redundancy checks in Haskell,
>
>  1. Attach a `{-# ALLOW redundant_import #-}` pragma to a definition,
>
> -- in Control.Applicative
> {-# ALLOW redundant_import (<$>) #-}
> (<$>) :: (a -> b) -> f a -> f b
> (<$>) = fmap
>
> asking the compiler to pretend that any import of the symbol did not
> exist when looking for redundant imports. This would allow library
> authors to appropriately mark definitions when they are moved,
> saving downstream users from having to make any change whatsoever.
>
>  2. Or alternatively we could make this a idea a bit more precise,
>
> -- in Control.Applicative
> {-# ALLOW redundant_import Prelude.(<$>) #-}
> (<$>) :: (a -> b) -> f a -> f b
> (<$>) = fmap
>
> Which would ignore imports of `Control.Applicative.(<$>)` only if
> `Prelude.(<$>)` were also in scope.
>

One obvious solution I haven't seen mentioned is the ability to add
nonexistent identifier to a hiding clause (these identifiers might
presumably exist in some other version of the import):

import Prelude hiding ((<$>))

I can see the argument for marking such imports with a pragma, though it
gets a bit ugly.

-Jan-Willem Maessen
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-prime