Hiding import behaviour

2014-10-16 Thread Malcolm Gooding
With the prelude changes that people have been discussing recently
I've been wondering is there any reason why importing an identifier
explicitly and unqualified doesn't automatically hide any implicit
imports of the same identifier? Specifically I'm wondering about cases
where you've imported an identifier explicitly from only one module,
like this:

module Foo (x, ...) where { ... }
module Bar (x, ...) where { ... }

import Bar
import Foo (x)

Even if you needed a pragma to enable it I can't think of any sensible
reason why that shouldn't be equivalent to:

import Bar hiding (x)
import Foo (x)

I don't know much of GHC's internals, but it seems like a pretty
minimal change. Typing rules remain the same; explicit imports just
shadow implicits. So importing multiple identifiers both implicitly or
both explicitly would remain ambiguous.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-16 Thread David Feuer
I think this is a great idea. I also think it should apply to the name
shadowing warning—identifiers imported implicitly should never trigger that.

On Thu, Oct 16, 2014 at 6:19 PM, Malcolm Gooding  wrote:

> With the prelude changes that people have been discussing recently
> I've been wondering is there any reason why importing an identifier
> explicitly and unqualified doesn't automatically hide any implicit
> imports of the same identifier? Specifically I'm wondering about cases
> where you've imported an identifier explicitly from only one module,
> like this:
>
> module Foo (x, ...) where { ... }
> module Bar (x, ...) where { ... }
>
> import Bar
> import Foo (x)
>
> Even if you needed a pragma to enable it I can't think of any sensible
> reason why that shouldn't be equivalent to:
>
> import Bar hiding (x)
> import Foo (x)
>
> I don't know much of GHC's internals, but it seems like a pretty
> minimal change. Typing rules remain the same; explicit imports just
> shadow implicits. So importing multiple identifiers both implicitly or
> both explicitly would remain ambiguous.
> ___
> Glasgow-haskell-users mailing list
> Glasgow-haskell-users@haskell.org
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-16 Thread Austin Seipp
My first thought is: Wouldn't this make it impossible to reorder or
sort imports lexicographically (or otherwise), without fully parsing,
renaming and typechecking the code?

For example, I often use ghc-mod plus stylish-haskell to order and
format my imports. If there is no syntactic indication that one import
should be hidden (and another preferred) as there is now, then
reordering the imports of a working program willy-nilly could result
in a program that no longer typechecks (or worse, one that does, but
is now wrong).

Maybe there are some cases today where something like this could
happen, but this seems awfully, awfully implicit and hard-to-follow as
a language feature.

In general I think a program that has imports like this that may clash
can be automated to make it easier to manage - but ultimately such
imports tend to represent a complex relationship between a module and
its dependencies - I'd prefer it if these were as clear as possible.

On Thu, Oct 16, 2014 at 5:19 PM, Malcolm Gooding  wrote:
> With the prelude changes that people have been discussing recently
> I've been wondering is there any reason why importing an identifier
> explicitly and unqualified doesn't automatically hide any implicit
> imports of the same identifier? Specifically I'm wondering about cases
> where you've imported an identifier explicitly from only one module,
> like this:
>
> module Foo (x, ...) where { ... }
> module Bar (x, ...) where { ... }
>
> import Bar
> import Foo (x)
>
> Even if you needed a pragma to enable it I can't think of any sensible
> reason why that shouldn't be equivalent to:
>
> import Bar hiding (x)
> import Foo (x)
>
> I don't know much of GHC's internals, but it seems like a pretty
> minimal change. Typing rules remain the same; explicit imports just
> shadow implicits. So importing multiple identifiers both implicitly or
> both explicitly would remain ambiguous.
> ___
> Glasgow-haskell-users mailing list
> Glasgow-haskell-users@haskell.org
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>



-- 
Regards,

Austin Seipp, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com/
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-16 Thread htebalaka
Well I suppose tooling might need to be aware of the feature depending on
what it does, but I don't see why the code actually typechecking would need
to be dependent on ordering. When I say shadowing I don't mean explicitly
having any explicit import create a new scope, since in that case it would
be sensitive to re-ordering, which I agree would be bad. My thought would be
first you would need to parse all the imports to see which identifiers they
import, then do another pass to change the imports to hide any identifiers
that should be shadowed.

So in the example I gave you would need to be aware that Foo exports x,
because otherwise there would be no way to know that x needs to be hidden
from Bar. I assume GHC already would have access to that information though.



--
View this message in context: 
http://haskell.1045720.n5.nabble.com/Hiding-import-behaviour-tp5758155p5758161.html
Sent from the Haskell - Glasgow-haskell-users mailing list archive at 
Nabble.com.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-16 Thread David Feuer
It should be good enough (for what you're talking about) to hide them all.
Turn

import A (foo)
import B (bar)
import C hiding (baz)
import D

into

import A (foo)
import B (bar)
import C hiding (foo,bar,baz)
import D hiding (foo,bar)

There's no reason to worry about hiding nonexistent identifiers, I don't
think.

On Thu, Oct 16, 2014 at 7:10 PM, htebalaka  wrote:

> Well I suppose tooling might need to be aware of the feature depending on
> what it does, but I don't see why the code actually typechecking would need
> to be dependent on ordering. When I say shadowing I don't mean explicitly
> having any explicit import create a new scope, since in that case it would
> be sensitive to re-ordering, which I agree would be bad. My thought would
> be
> first you would need to parse all the imports to see which identifiers they
> import, then do another pass to change the imports to hide any identifiers
> that should be shadowed.
>
> So in the example I gave you would need to be aware that Foo exports x,
> because otherwise there would be no way to know that x needs to be hidden
> from Bar. I assume GHC already would have access to that information
> though.
>
>
>
> --
> View this message in context:
> http://haskell.1045720.n5.nabble.com/Hiding-import-behaviour-tp5758155p5758161.html
> Sent from the Haskell - Glasgow-haskell-users mailing list archive at
> Nabble.com.
> ___
> Glasgow-haskell-users mailing list
> Glasgow-haskell-users@haskell.org
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-16 Thread htebalaka
Yeah, I just realized that would work too. You would still need to do two
passes over the imports, so foo and bar are hidden from anything imported
above A. Though while we're reasoning syntactically, you would also need to
hide them from the Prelude if it was being implicitly imported.



--
View this message in context: 
http://haskell.1045720.n5.nabble.com/Hiding-import-behaviour-tp5758155p5758166.html
Sent from the Haskell - Glasgow-haskell-users mailing list archive at 
Nabble.com.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-17 Thread Alexander Berntsen
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA256

On 17/10/14 00:40, Austin Seipp wrote:
> Maybe there are some cases today where something like this could 
> happen, but this seems awfully, awfully implicit and hard-to-follow
> as a language feature.
> 
> In general I think a program that has imports like this that may
> clash can be automated to make it easier to manage - but ultimately
> such imports tend to represent a complex relationship between a
> module and its dependencies - I'd prefer it if these were as clear
> as possible.
Very strong +1 from me. It seems awfully implicit and obscure for very
little benefit, and it may mean quite a bit of work for tool developers.
- -- 
Alexander
alexan...@plaimi.net
https://secure.plaimi.net/~alexander
-BEGIN PGP SIGNATURE-
Version: GnuPG v2
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iF4EAREIAAYFAlRAxf8ACgkQRtClrXBQc7WGewD/Vt/7OdyPgzORiE4uHtU/p22a
TLGGnQuceSlrMJiWFhMA/0GuZ1leom0ILvrqW/oJYugnwGgX1atqmneJoZ72qNEM
=+oUV
-END PGP SIGNATURE-
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-18 Thread htebalaka
On 10/17/14 12:32, Alexander Berntsen wrote:
> On 17/10/14 00:40, Austin Seipp wrote: 
> > Maybe there are some cases today where something like this could 
> > happen, but this seems awfully, awfully implicit and hard-to-follow 
> > as a language feature. 
> > 
> > In general I think a program that has imports like this that may 
> > clash can be automated to make it easier to manage - but ultimately 
> > such imports tend to represent a complex relationship between a 
> > module and its dependencies - I'd prefer it if these were as clear 
> > as possible. 
> Very strong +1 from me. It seems awfully implicit and obscure for very 
> little benefit, and it may mean quite a bit of work for tool developers.

I guess my central point is I don't see how anyone can benefit from the
current behaviour. For instance, a simple real world example:

import Prelude
import Data.Text.Lazy.IO (putStrLn)

Regardless of the ordering of the imports, is there any way for me to use
putStrLn in any context without hiding it from the Prelude (and any other
modules that I might be unintentionally importing it from)? Any unqualified
use will be ambiguous, unless you hide it from every other module that might
export a function with the same name. I would think the fact that it
shouldn't be implicitly imported from other modules would directly follow
from the fact you imported it explicitly (otherwise, why did you import
it?). I'm having trouble coming up with a single example where the current
behaviour is useful.

I can't speak to tooling, though I suppose if this doesn't get implemented
I'll write my own. Just to be very clear, supposing you have some Import
datatype which stores a list of any identifiers that are being explicitly
imported unqualified (or conversely, a list of any identifiers that are
being hidden), then the behaviour I'm suggesting is a pragma to enable
something like this:

hide :: [Import] -> [Import]
hide = flip (fmap fmap appendHiddenImports) <*> collectOnly where
collectOnly :: [Import] -> [Identifier]
collectOnly = concat . mapMaybe getExplicitImports
appendHiddenImports :: [Identifier] -> Import -> Import
getExplicitImports :: Import -> Maybe [Identifier]

where appendHiddenImports would only change import statements that import an
unspecified number of unqualified identifiers, like "import X hiding (x, y)"
or "import Y".



--
View this message in context: 
http://haskell.1045720.n5.nabble.com/Hiding-import-behaviour-tp5758155p5758246.html
Sent from the Haskell - Glasgow-haskell-users mailing list archive at 
Nabble.com.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-18 Thread David Feuer
You mention only unqualified imports, but if we do this, it should also
apply to qualified ones:

import qualified Data.List as L
import qualified MyModule as L (isInfixOf)
On Oct 18, 2014 2:02 PM, "htebalaka"  wrote:

> On 10/17/14 12:32, Alexander Berntsen wrote:
> > On 17/10/14 00:40, Austin Seipp wrote:
> > > Maybe there are some cases today where something like this could
> > > happen, but this seems awfully, awfully implicit and hard-to-follow
> > > as a language feature.
> > >
> > > In general I think a program that has imports like this that may
> > > clash can be automated to make it easier to manage - but ultimately
> > > such imports tend to represent a complex relationship between a
> > > module and its dependencies - I'd prefer it if these were as clear
> > > as possible.
> > Very strong +1 from me. It seems awfully implicit and obscure for very
> > little benefit, and it may mean quite a bit of work for tool developers.
>
> I guess my central point is I don't see how anyone can benefit from the
> current behaviour. For instance, a simple real world example:
>
> import Prelude
> import Data.Text.Lazy.IO (putStrLn)
>
> Regardless of the ordering of the imports, is there any way for me to use
> putStrLn in any context without hiding it from the Prelude (and any other
> modules that I might be unintentionally importing it from)? Any unqualified
> use will be ambiguous, unless you hide it from every other module that
> might
> export a function with the same name. I would think the fact that it
> shouldn't be implicitly imported from other modules would directly follow
> from the fact you imported it explicitly (otherwise, why did you import
> it?). I'm having trouble coming up with a single example where the current
> behaviour is useful.
>
> I can't speak to tooling, though I suppose if this doesn't get implemented
> I'll write my own. Just to be very clear, supposing you have some Import
> datatype which stores a list of any identifiers that are being explicitly
> imported unqualified (or conversely, a list of any identifiers that are
> being hidden), then the behaviour I'm suggesting is a pragma to enable
> something like this:
>
> hide :: [Import] -> [Import]
> hide = flip (fmap fmap appendHiddenImports) <*> collectOnly where
> collectOnly :: [Import] -> [Identifier]
> collectOnly = concat . mapMaybe getExplicitImports
> appendHiddenImports :: [Identifier] -> Import -> Import
> getExplicitImports :: Import -> Maybe [Identifier]
>
> where appendHiddenImports would only change import statements that import
> an
> unspecified number of unqualified identifiers, like "import X hiding (x,
> y)"
> or "import Y".
>
>
>
> --
> View this message in context:
> http://haskell.1045720.n5.nabble.com/Hiding-import-behaviour-tp5758155p5758246.html
> Sent from the Haskell - Glasgow-haskell-users mailing list archive at
> Nabble.com.
> ___
> Glasgow-haskell-users mailing list
> Glasgow-haskell-users@haskell.org
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-18 Thread Austin Seipp
[Import]
> hide = flip (fmap fmap appendHiddenImports) <*> collectOnly where
> collectOnly :: [Import] -> [Identifier]
> collectOnly = concat . mapMaybe getExplicitImports
> appendHiddenImports :: [Identifier] -> Import -> Import
> getExplicitImports :: Import -> Maybe [Identifier]
>
> where appendHiddenImports would only change import statements that import an
> unspecified number of unqualified identifiers, like "import X hiding (x, y)"
> or "import Y".
>
>
>
> --
> View this message in context: 
> http://haskell.1045720.n5.nabble.com/Hiding-import-behaviour-tp5758155p5758246.html
> Sent from the Haskell - Glasgow-haskell-users mailing list archive at 
> Nabble.com.
> ___
> Glasgow-haskell-users mailing list
> Glasgow-haskell-users@haskell.org
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>

-- 
Regards,

Austin Seipp, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com/
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-18 Thread Austin Seipp
 This all just seems like a relatively large amount of hoops to jump
> through, just to avoid writing 'hiding' in a on a few things, so to
> me, the cure looks worse than the disease. But I may just be missing
> something completely.
>
>> Any unqualified use will be ambiguous, unless you hide it from every other 
>> module that might
>> export a function with the same name. I would think the fact that it
>> shouldn't be implicitly imported from other modules would directly follow
>> from the fact you imported it explicitly (otherwise, why did you import
>> it?). I'm having trouble coming up with a single example where the current
>> behaviour is useful.
>>
>> I can't speak to tooling, though I suppose if this doesn't get implemented
>> I'll write my own. Just to be very clear, supposing you have some Import
>> datatype which stores a list of any identifiers that are being explicitly
>> imported unqualified (or conversely, a list of any identifiers that are
>> being hidden), then the behaviour I'm suggesting is a pragma to enable
>> something like this:
>>
>> hide :: [Import] -> [Import]
>> hide = flip (fmap fmap appendHiddenImports) <*> collectOnly where
>> collectOnly :: [Import] -> [Identifier]
>> collectOnly = concat . mapMaybe getExplicitImports
>> appendHiddenImports :: [Identifier] -> Import -> Import
>> getExplicitImports :: Import -> Maybe [Identifier]
>>
>> where appendHiddenImports would only change import statements that import an
>> unspecified number of unqualified identifiers, like "import X hiding (x, y)"
>> or "import Y".
>>
>>
>>
>> --
>> View this message in context: 
>> http://haskell.1045720.n5.nabble.com/Hiding-import-behaviour-tp5758155p5758246.html
>> Sent from the Haskell - Glasgow-haskell-users mailing list archive at 
>> Nabble.com.
>> ___
>> Glasgow-haskell-users mailing list
>> Glasgow-haskell-users@haskell.org
>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>
>
> --
> Regards,
>
> Austin Seipp, Haskell Consultant
> Well-Typed LLP, http://www.well-typed.com/



-- 
Regards,

Austin Seipp, Haskell Consultant
Well-Typed LLP, http://www.well-typed.com/
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-18 Thread htebalaka
I don't normally import things qualified like that, so it hadn't occurred to
me, but that makes sense. I do want to be clear that this shouldn't be
sensitive to ordering, and it can occur before type checking. You just need
to know what modules are importing which identifiers explicitly, and what
modules are importing an unspecified set of identifiers. It should be
possible to do while parsing even, as soon as you've reached a point where
you know every import statement has been reached.

The behaviour would thus remain the same if someone was to explicitly import
the same identifier from two or more modules, since hiding the implicit
imports wouldn't remove the ambiguity in that case. I'm pretty sure the code
I provided is sufficient; you would just need a separate pass for qualified
and unqualified imports.


David Feuer wrote
> You mention only unqualified imports, but if we do this, it should also
> apply to qualified ones:
> 
> import qualified Data.List as L
> import qualified MyModule as L (isInfixOf)
> On Oct 18, 2014 2:02 PM, "htebalaka" <

> goodingm@

> > wrote:
> 
>> On 10/17/14 12:32, Alexander Berntsen wrote:
>> > On 17/10/14 00:40, Austin Seipp wrote:
>> > > Maybe there are some cases today where something like this could
>> > > happen, but this seems awfully, awfully implicit and hard-to-follow
>> > > as a language feature.
>> > >
>> > > In general I think a program that has imports like this that may
>> > > clash can be automated to make it easier to manage - but ultimately
>> > > such imports tend to represent a complex relationship between a
>> > > module and its dependencies - I'd prefer it if these were as clear
>> > > as possible.
>> > Very strong +1 from me. It seems awfully implicit and obscure for very
>> > little benefit, and it may mean quite a bit of work for tool
>> developers.
>>
>> I guess my central point is I don't see how anyone can benefit from the
>> current behaviour. For instance, a simple real world example:
>>
>> import Prelude
>> import Data.Text.Lazy.IO (putStrLn)
>>
>> Regardless of the ordering of the imports, is there any way for me to use
>> putStrLn in any context without hiding it from the Prelude (and any other
>> modules that I might be unintentionally importing it from)? Any
>> unqualified
>> use will be ambiguous, unless you hide it from every other module that
>> might
>> export a function with the same name. I would think the fact that it
>> shouldn't be implicitly imported from other modules would directly follow
>> from the fact you imported it explicitly (otherwise, why did you import
>> it?). I'm having trouble coming up with a single example where the
>> current
>> behaviour is useful.
>>
>> I can't speak to tooling, though I suppose if this doesn't get
>> implemented
>> I'll write my own. Just to be very clear, supposing you have some Import
>> datatype which stores a list of any identifiers that are being explicitly
>> imported unqualified (or conversely, a list of any identifiers that are
>> being hidden), then the behaviour I'm suggesting is a pragma to enable
>> something like this:
>>
>> hide :: [Import] -> [Import]
>> hide = flip (fmap fmap appendHiddenImports) <*> collectOnly where
>> collectOnly :: [Import] -> [Identifier]
>>     collectOnly = concat . mapMaybe getExplicitImports
>> appendHiddenImports :: [Identifier] -> Import -> Import
>> getExplicitImports :: Import -> Maybe [Identifier]
>>
>> where appendHiddenImports would only change import statements that import
>> an
>> unspecified number of unqualified identifiers, like "import X hiding (x,
>> y)"
>> or "import Y".
>>
>>
>>
>> --
>> View this message in context:
>> http://haskell.1045720.n5.nabble.com/Hiding-import-behaviour-tp5758155p5758246.html
>> Sent from the Haskell - Glasgow-haskell-users mailing list archive at
>> Nabble.com.
>> ___
>> Glasgow-haskell-users mailing list
>> 

> Glasgow-haskell-users@

>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>
> 
> ___
> Glasgow-haskell-users mailing list

> Glasgow-haskell-users@

> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users





--
View this message in context: 
http://haskell.1045720.n5.nabble.com/Hiding-import-behaviour-tp5758155p5758251.html
Sent from the Haskell - Glasgow-haskell-users mailing list archive at 
Nabble.com.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-18 Thread htebalaka
 speak, where with
>> 'hiding', order no longer matters in the import list.
>>
>> Of course you might say, "Well, of course Prelude exports putStrLn, so
>> you wouldn't move the import, and it wouldn't be a problem". The
>> problem is I don't know what exports an arbitrary module has; it
>> doesn't seem to scale mentally for humans at all. In this case, I know
>> Prelude exports that, but in the general case of:
>>
>> import Frob
>> import Knob (xyz)
>>
>> Today, this means I only import 'xyz' from Knob, and there are no
>> other ambiguous names. But under your proposal, I have zero clue if
>> 'xyz' is actually shadowing a prior import. So unless I check *all*
>> the transitive exports of 'Frob', I have no clue if it's actually safe
>> to move the import of 'Knob' higher up - an identifier may not be
>> shadowed if I do that. OTOH, I know *for a fact* when I see this:
>>
>> import Frob hiding (xyz)
>> import Knob (xyz)
>>
>> which 'xyz' I'm referring to later, without ambiguity. Also, what
>> happens if I do this:
>>
>> import Knob (xyz)
>> import Frob
>>
>> legitimately, without shadowing, and 'Frob' later ends up exporting
>> its own 'xyz'? Do I just get an ambiguous identifier error, like I
>> would today? Again, shadowing in this sense only works 'one-way': top
>> to bottom, and it fails any other case they might be rearranged.
>>
>> This all just seems like a relatively large amount of hoops to jump
>> through, just to avoid writing 'hiding' in a on a few things, so to
>> me, the cure looks worse than the disease. But I may just be missing
>> something completely.
>>
>>> Any unqualified use will be ambiguous, unless you hide it from every
>>> other module that might
>>> export a function with the same name. I would think the fact that it
>>> shouldn't be implicitly imported from other modules would directly
>>> follow
>>> from the fact you imported it explicitly (otherwise, why did you import
>>> it?). I'm having trouble coming up with a single example where the
>>> current
>>> behaviour is useful.
>>>
>>> I can't speak to tooling, though I suppose if this doesn't get
>>> implemented
>>> I'll write my own. Just to be very clear, supposing you have some Import
>>> datatype which stores a list of any identifiers that are being
>>> explicitly
>>> imported unqualified (or conversely, a list of any identifiers that are
>>> being hidden), then the behaviour I'm suggesting is a pragma to enable
>>> something like this:
>>>
>>> hide :: [Import] -> [Import]
>>> hide = flip (fmap fmap appendHiddenImports) <*> collectOnly where
>>> collectOnly :: [Import] -> [Identifier]
>>> collectOnly = concat . mapMaybe getExplicitImports
>>>     appendHiddenImports :: [Identifier] -> Import -> Import
>>> getExplicitImports :: Import -> Maybe [Identifier]
>>>
>>> where appendHiddenImports would only change import statements that
>>> import an
>>> unspecified number of unqualified identifiers, like "import X hiding (x,
>>> y)"
>>> or "import Y".
>>>
>>>
>>>
>>> --
>>> View this message in context:
>>> http://haskell.1045720.n5.nabble.com/Hiding-import-behaviour-tp5758155p5758246.html
>>> Sent from the Haskell - Glasgow-haskell-users mailing list archive at
>>> Nabble.com.
>>> ___
>>> Glasgow-haskell-users mailing list
>>> 

> Glasgow-haskell-users@

>>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>>
>>
>> --
>> Regards,
>>
>> Austin Seipp, Haskell Consultant
>> Well-Typed LLP, http://www.well-typed.com/
> 
> 
> 
> -- 
> Regards,
> 
> Austin Seipp, Haskell Consultant
> Well-Typed LLP, http://www.well-typed.com/
> ___
> Glasgow-haskell-users mailing list

> Glasgow-haskell-users@

> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users





--
View this message in context: 
http://haskell.1045720.n5.nabble.com/Hiding-import-behaviour-tp5758155p5758254.html
Sent from the Haskell - Glasgow-haskell-users mailing list archive at 
Nabble.com.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-18 Thread htebalaka
; use
>>>> putStrLn in any context without hiding it from the Prelude (and any
>>>> other
>>>> modules that I might be unintentionally importing it from)?
>>>
>>> I suppose my point isn't that the current behavior is more useful, but
>>> the *proposed behavior seems more confusing for humans*. I would
>>> rather have GHC inform me of an ambiguous import as opposed to
>>> silently accepting or rejecting my program based on the import list,
>>> and whether it shadows something prior to it. I don't even always know
>>> what identifiers may get imported in the first place, due to
>>> transitive module reexports. It just seems like pretty confusing
>>> behavior - shadowing of identifiers is rarely a 'feature' for humans,
>>> IMO.
>>>
>>> In the example you have, what happens if I change the import list of
>>> Data.Text by removing it, for example, or what happens if I *remove*
>>> the Prelude import, and stick it after the Text import? Rather than
>>> getting an out of scope identifier error, or something ambiguous, I'd
>>> get a confusing type error based on Prelude's use of putStrLn in the
>>> context of needing Texts', because the shadowing would fail to apply
>>> since it didn't occur before the Text import. Shadowing of previously
>>> imported identifiers only works one-way, so to speak, where with
>>> 'hiding', order no longer matters in the import list.
>>>
>>> Of course you might say, "Well, of course Prelude exports putStrLn, so
>>> you wouldn't move the import, and it wouldn't be a problem". The
>>> problem is I don't know what exports an arbitrary module has; it
>>> doesn't seem to scale mentally for humans at all. In this case, I know
>>> Prelude exports that, but in the general case of:
>>>
>>> import Frob
>>> import Knob (xyz)
>>>
>>> Today, this means I only import 'xyz' from Knob, and there are no
>>> other ambiguous names. But under your proposal, I have zero clue if
>>> 'xyz' is actually shadowing a prior import. So unless I check *all*
>>> the transitive exports of 'Frob', I have no clue if it's actually safe
>>> to move the import of 'Knob' higher up - an identifier may not be
>>> shadowed if I do that. OTOH, I know *for a fact* when I see this:
>>>
>>> import Frob hiding (xyz)
>>> import Knob (xyz)
>>>
>>> which 'xyz' I'm referring to later, without ambiguity. Also, what
>>> happens if I do this:
>>>
>>> import Knob (xyz)
>>> import Frob
>>>
>>> legitimately, without shadowing, and 'Frob' later ends up exporting
>>> its own 'xyz'? Do I just get an ambiguous identifier error, like I
>>> would today? Again, shadowing in this sense only works 'one-way': top
>>> to bottom, and it fails any other case they might be rearranged.
>>>
>>> This all just seems like a relatively large amount of hoops to jump
>>> through, just to avoid writing 'hiding' in a on a few things, so to
>>> me, the cure looks worse than the disease. But I may just be missing
>>> something completely.
>>>
>>>> Any unqualified use will be ambiguous, unless you hide it from every
>>>> other module that might
>>>> export a function with the same name. I would think the fact that it
>>>> shouldn't be implicitly imported from other modules would directly
>>>> follow
>>>> from the fact you imported it explicitly (otherwise, why did you import
>>>> it?). I'm having trouble coming up with a single example where the
>>>> current
>>>> behaviour is useful.
>>>>
>>>> I can't speak to tooling, though I suppose if this doesn't get
>>>> implemented
>>>> I'll write my own. Just to be very clear, supposing you have some
>>>> Import
>>>> datatype which stores a list of any identifiers that are being
>>>> explicitly
>>>> imported unqualified (or conversely, a list of any identifiers that are
>>>> being hidden), then the behaviour I'm suggesting is a pragma to enable
>>>> something like this:
>>>>
>>>> hide :: [Import] -> [Import]
>>>> hide = flip (fmap fmap appendHiddenImports) <*> collectOnly where
>>>> collectOnly :: [Import] -> [Identifier]
>>>> collectOnly = concat . mapMaybe getExplicitImports
>>>> appendHiddenImports :: [Identifier] -> Import -> Import
>>>> getExplicitImports :: Import -> Maybe [Identifier]
>>>>
>>>> where appendHiddenImports would only change import statements that
>>>> import an
>>>> unspecified number of unqualified identifiers, like "import X hiding
>>>> (x, y)"
>>>> or "import Y".
>>>>
>>>>
>>>>
>>>> --
>>>> View this message in context:
>>>> http://haskell.1045720.n5.nabble.com/Hiding-import-behaviour-tp5758155p5758246.html
>>>> Sent from the Haskell - Glasgow-haskell-users mailing list archive at
>>>> Nabble.com.
>>>> ___
>>>> Glasgow-haskell-users mailing list
>>>> 

>> Glasgow-haskell-users@

>>>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>>>
>>>
>>> --
>>> Regards,
>>>
>>> Austin Seipp, Haskell Consultant
>>> Well-Typed LLP, http://www.well-typed.com/
>> 
>> 
>> 
>> -- 
>> Regards,
>> 
>> Austin Seipp, Haskell Consultant
>> Well-Typed LLP, http://www.well-typed.com/
>> ___
>> Glasgow-haskell-users mailing list

>> Glasgow-haskell-users@

>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users





--
View this message in context: 
http://haskell.1045720.n5.nabble.com/Hiding-import-behaviour-tp5758155p5758257.html
Sent from the Haskell - Glasgow-haskell-users mailing list archive at 
Nabble.com.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-18 Thread Joachim Breitner
Hi,

Am Samstag, den 18.10.2014, 11:02 -0700 schrieb htebalaka:
> I guess my central point is I don't see how anyone can benefit from the
> current behaviour. For instance, a simple real world example:
> 
> import Prelude
> import Data.Text.Lazy.IO (putStrLn)

I find this quite convincing. If I bother to explicitly write out „take
putStrLn from Data.Text.Lazy.IO“, why should the compiler assume that I
might have meant some putStrLn from somewhere else.

Of course, order should not matter (I don’t think anyone suggested it
should, I think Austin simply mis-read that).

Greetings,
Joachim


-- 
Joachim “nomeata” Breitner
  m...@joachim-breitner.de • http://www.joachim-breitner.de/
  Jabber: nome...@joachim-breitner.de  • GPG-Key: 0xF0FBF51F
  Debian Developer: nome...@debian.org



signature.asc
Description: This is a digitally signed message part
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-18 Thread David Feuer
I'm generally in favor of the proposal, but I figured I should mention one
situation when I personally might find this confusing. If the module import
list is very long, and includes an unrestricted import of a well-known
module, it might be easy to assume a certain well-known function comes from
there, when in fact it comes from some other module on the other end of the
import list.
On Oct 18, 2014 6:39 PM, "Joachim Breitner" 
wrote:

> Hi,
>
> Am Samstag, den 18.10.2014, 11:02 -0700 schrieb htebalaka:
> > I guess my central point is I don't see how anyone can benefit from the
> > current behaviour. For instance, a simple real world example:
> >
> > import Prelude
> > import Data.Text.Lazy.IO (putStrLn)
>
> I find this quite convincing. If I bother to explicitly write out „take
> putStrLn from Data.Text.Lazy.IO“, why should the compiler assume that I
> might have meant some putStrLn from somewhere else.
>
> Of course, order should not matter (I don’t think anyone suggested it
> should, I think Austin simply mis-read that).
>
> Greetings,
> Joachim
>
>
> --
> Joachim “nomeata” Breitner
>   m...@joachim-breitner.de • http://www.joachim-breitner.de/
>   Jabber: nome...@joachim-breitner.de  • GPG-Key: 0xF0FBF51F
>   Debian Developer: nome...@debian.org
>
>
> ___
> Glasgow-haskell-users mailing list
> Glasgow-haskell-users@haskell.org
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>
>
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-19 Thread Herbert Valerio Riedel
On 2014-10-19 at 00:39:42 +0200, Joachim Breitner wrote:
>> I guess my central point is I don't see how anyone can benefit from the
>> current behaviour. For instance, a simple real world example:
>> 
>> import Prelude
>> import Data.Text.Lazy.IO (putStrLn)
>
> I find this quite convincing. If I bother to explicitly write out „take
> putStrLn from Data.Text.Lazy.IO“, why should the compiler assume that I
> might have meant some putStrLn from somewhere else.

I think we've reached the point where this proposal should be turned
into a Wiki page detailing the exact semantics[1], and giving this
extension a catchy name...

If it's trivial enough (in the sense there is little design-space
variation to get it wrong), having it in 7.10 rather than 7.12 may be
still possible (and IMHO desirable to be able to start using it earlier
rather than later on real-world code).


 [1]: Cases to consider include all combinations of variations of
  import-statements; as well as turning most unqualified imports
  from which entities are to be hidden into a pair of qualified and
  unqualified import:

  import Doo (doo)
  import Bar -- provide 'doo' as well

  which I'd think should be transformed into
  
  import Doo (doo)
  import qualified Bar
  import Bar hiding (doo)

  as to allow to still have 'Bar.doo' in scope (unless some other
  import explicitly mentions `... as Bar (doo)`, in which case that
  needs to be hidden from the qualified `Bar` import as well)

Cheers,
  hvr
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-19 Thread Erik Hesselink
I feel that this extension, while looking tempting for writing code
from scratch, might hurt maintainability of code. Adding an explicit
import can suddenly cause type errors in completely unrelated places
(when it hides an implicit import and the new function is type
incorrect), or worse, can cause semantic change (when it hides an
implicit import and the new function is type correct, but has
different behavior). Remember that not all code is written by the same
person, or in a short time frame, so not everybody might fully
understand every module and every import of the code they're editing.

Erik

On Sun, Oct 19, 2014 at 1:32 AM, David Feuer  wrote:
> I'm generally in favor of the proposal, but I figured I should mention one
> situation when I personally might find this confusing. If the module import
> list is very long, and includes an unrestricted import of a well-known
> module, it might be easy to assume a certain well-known function comes from
> there, when in fact it comes from some other module on the other end of the
> import list.
>
> On Oct 18, 2014 6:39 PM, "Joachim Breitner" 
> wrote:
>>
>> Hi,
>>
>> Am Samstag, den 18.10.2014, 11:02 -0700 schrieb htebalaka:
>> > I guess my central point is I don't see how anyone can benefit from the
>> > current behaviour. For instance, a simple real world example:
>> >
>> > import Prelude
>> > import Data.Text.Lazy.IO (putStrLn)
>>
>> I find this quite convincing. If I bother to explicitly write out „take
>> putStrLn from Data.Text.Lazy.IO“, why should the compiler assume that I
>> might have meant some putStrLn from somewhere else.
>>
>> Of course, order should not matter (I don’t think anyone suggested it
>> should, I think Austin simply mis-read that).
>>
>> Greetings,
>> Joachim
>>
>>
>> --
>> Joachim “nomeata” Breitner
>>   m...@joachim-breitner.de • http://www.joachim-breitner.de/
>>   Jabber: nome...@joachim-breitner.de  • GPG-Key: 0xF0FBF51F
>>   Debian Developer: nome...@debian.org
>>
>>
>> ___
>> Glasgow-haskell-users mailing list
>> Glasgow-haskell-users@haskell.org
>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>
>
> ___
> Glasgow-haskell-users mailing list
> Glasgow-haskell-users@haskell.org
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-19 Thread htebalaka
At least in the case where something being hidden causes an unintended type
error, compiler errors could /potentially/ be aware of the extension, though
defining unintended seems non-trivial. You don't want actual type errors
being replaced with "maybe you didn't realize this other function is being
auto-hidden", and you definitely don't want to have to type check for
different combination of hidden functions. I don't think it's really worth
extending the scope, unless there's some trivial solution I'm missing.

What I want to be able to do is use a not-too-large set of more general (IO
-> MonadIO) or differently monomorphic (String -> Text) functions than what
I'm implicitly importing. In either case I think the change is semantically
safe: any type errors you encounter are actual type errors. This should make
that kind of use a little more lightweight than it is currently. I'll
definitely concede it could be unsuitable behaviour by default for large
projects. My coding is mostly personal-use stuff, so that's where my
experience is.

Is there a good example proposal somewhere for what kind of format I should
follow. I'm somewhat busy at the moment, but I'll write up a more detailed
proposal on the wiki by the end of the week unless someone feels compelled
to beat me to it.


Erik Hesselink wrote
> I feel that this extension, while looking tempting for writing code
> from scratch, might hurt maintainability of code. Adding an explicit
> import can suddenly cause type errors in completely unrelated places
> (when it hides an implicit import and the new function is type
> incorrect), or worse, can cause semantic change (when it hides an
> implicit import and the new function is type correct, but has
> different behavior). Remember that not all code is written by the same
> person, or in a short time frame, so not everybody might fully
> understand every module and every import of the code they're editing.
> 
> Erik
> 
> On Sun, Oct 19, 2014 at 1:32 AM, David Feuer <

> david.feuer@

> > wrote:
>> I'm generally in favor of the proposal, but I figured I should mention
>> one
>> situation when I personally might find this confusing. If the module
>> import
>> list is very long, and includes an unrestricted import of a well-known
>> module, it might be easy to assume a certain well-known function comes
>> from
>> there, when in fact it comes from some other module on the other end of
>> the
>> import list.
>>
>> On Oct 18, 2014 6:39 PM, "Joachim Breitner" <

> mail@

> >
>> wrote:
>>>
>>> Hi,
>>>
>>> Am Samstag, den 18.10.2014, 11:02 -0700 schrieb htebalaka:
>>> > I guess my central point is I don't see how anyone can benefit from
>>> the
>>> > current behaviour. For instance, a simple real world example:
>>> >
>>> > import Prelude
>>> > import Data.Text.Lazy.IO (putStrLn)
>>>
>>> I find this quite convincing. If I bother to explicitly write out „take
>>> putStrLn from Data.Text.Lazy.IO“, why should the compiler assume that I
>>> might have meant some putStrLn from somewhere else.
>>>
>>> Of course, order should not matter (I don’t think anyone suggested it
>>> should, I think Austin simply mis-read that).
>>>
>>> Greetings,
>>> Joachim
>>>
>>>
>>> --
>>> Joachim “nomeata” Breitner
>>>   

> mail@

>  • http://www.joachim-breitner.de/
>>>   Jabber: 

> nomeata@

>   • GPG-Key: 0xF0FBF51F
>>>   Debian Developer: 

> nomeata@

>>>
>>>
>>> ___
>>> Glasgow-haskell-users mailing list
>>> 

> Glasgow-haskell-users@

>>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>>
>>
>> ___
>> Glasgow-haskell-users mailing list
>> 

> Glasgow-haskell-users@

>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>
> ___
> Glasgow-haskell-users mailing list

> Glasgow-haskell-users@

> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users





--
View this message in context: 
http://haskell.1045720.n5.nabble.com/Hiding-import-behaviour-tp5758155p5758327.html
Sent from the Haskell - Glasgow-haskell-users mailing list archive at 
Nabble.com.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-19 Thread htebalaka
 think anyone suggested it
>>>> should, I think Austin simply mis-read that).
>>>>
>>>> Greetings,
>>>> Joachim
>>>>
>>>>
>>>> --
>>>> Joachim “nomeata” Breitner
>>>>   

>> mail@

>>  • http://www.joachim-breitner.de/
>>>>   Jabber: 

>> nomeata@

>>   • GPG-Key: 0xF0FBF51F
>>>>   Debian Developer: 

>> nomeata@

>>>>
>>>>
>>>> ___
>>>> Glasgow-haskell-users mailing list
>>>> 

>> Glasgow-haskell-users@

>>>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>>>
>>>
>>> ___
>>> Glasgow-haskell-users mailing list
>>> 

>> Glasgow-haskell-users@

>>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>>>
>> ___
>> Glasgow-haskell-users mailing list

>> Glasgow-haskell-users@

>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users





--
View this message in context: 
http://haskell.1045720.n5.nabble.com/Hiding-import-behaviour-tp5758155p5758346.html
Sent from the Haskell - Glasgow-haskell-users mailing list archive at 
Nabble.com.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-20 Thread Mario Blažević

On 14-10-19 08:10 AM, Erik Hesselink wrote:

I feel that this extension, while looking tempting for writing code
from scratch, might hurt maintainability of code.


That depends on how you define maintainability.


Adding an explicit
import can suddenly cause type errors in completely unrelated places
(when it hides an implicit import and the new function is type
incorrect), or worse, can cause semantic change (when it hides an
implicit import and the new function is type correct, but has
different behavior). Remember that not all code is written by the same
person, or in a short time frame, so not everybody might fully
understand every module and every import of the code they're editing.


	Your example requires somebody actively editing the import list. A code 
change causes a compile error or worse? That is not all that surprising.


	No, what I find much worse is a cabal update causing an error in a 
module that was correct before the update. Consider


> module Main where
>
> import Foo (foo)
> import Bar
>
> main = foo

	Now suppose Bar came from the package bar-1.0, and the new version 
bar-1.0.1 decides to export foo. With the current behaviour, this change 
would break my module. With Malcolm's proposal the old code would 
continue to work.


	Anyway, count me as +1 on the proposal. It would improve the long-term 
stability of Haskell code.


___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-21 Thread Erik Hesselink
On Mon, Oct 20, 2014 at 11:57 PM, Mario Blažević  wrote:
> On 14-10-19 08:10 AM, Erik Hesselink wrote:
>>
>> Adding an explicit
>> import can suddenly cause type errors in completely unrelated places
>> (when it hides an implicit import and the new function is type
>> incorrect), or worse, can cause semantic change (when it hides an
>> implicit import and the new function is type correct, but has
>> different behavior). Remember that not all code is written by the same
>> person, or in a short time frame, so not everybody might fully
>> understand every module and every import of the code they're editing.
>
> Your example requires somebody actively editing the import list. A
> code change causes a compile error or worse? That is not all that
> surprising.

But right now, we have a useful property that adding imports and code
to a module does not break or change other code in that module. With
this extension, that changes. I find this kind of local reasoning very
useful, IMHO it's one of the most useful things about Haskell in
general.

> No, what I find much worse is a cabal update causing an error in a
> module that was correct before the update. Consider
>
>> module Main where
>>
>> import Foo (foo)
>> import Bar
>>
>> main = foo
>
> Now suppose Bar came from the package bar-1.0, and the new version
> bar-1.0.1 decides to export foo. With the current behaviour, this change
> would break my module. With Malcolm's proposal the old code would continue
> to work.

That's a very good point. Given that and the above, I don't understand
your conclusion:

> Anyway, count me as +1 on the proposal. It would improve the
> long-term stability of Haskell code.

How is adding more ways to break something "improving the long-term stability"?

Regards,

Erik
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-21 Thread Richard Eisenberg
I'm having a hard time keeping track of what's going on in this discussion. 
But, I'm generally in favor of making *some* change along the lines discussed 
here, and also in #9702 (https://ghc.haskell.org/trac/ghc/ticket/9702). Could 
the proposers of various features perhaps create a wiki page, naming the 
individual pieces or proposals, and then we can have something closer to a vote 
among a stable list of candidates?

Thanks!
Richard

On Oct 21, 2014, at 7:14 AM, Erik Hesselink  wrote:

> On Mon, Oct 20, 2014 at 11:57 PM, Mario Blažević  wrote:
>> On 14-10-19 08:10 AM, Erik Hesselink wrote:
>>> 
>>> Adding an explicit
>>> import can suddenly cause type errors in completely unrelated places
>>> (when it hides an implicit import and the new function is type
>>> incorrect), or worse, can cause semantic change (when it hides an
>>> implicit import and the new function is type correct, but has
>>> different behavior). Remember that not all code is written by the same
>>> person, or in a short time frame, so not everybody might fully
>>> understand every module and every import of the code they're editing.
>> 
>>Your example requires somebody actively editing the import list. A
>> code change causes a compile error or worse? That is not all that
>> surprising.
> 
> But right now, we have a useful property that adding imports and code
> to a module does not break or change other code in that module. With
> this extension, that changes. I find this kind of local reasoning very
> useful, IMHO it's one of the most useful things about Haskell in
> general.
> 
>>No, what I find much worse is a cabal update causing an error in a
>> module that was correct before the update. Consider
>> 
>>> module Main where
>>> 
>>> import Foo (foo)
>>> import Bar
>>> 
>>> main = foo
>> 
>>Now suppose Bar came from the package bar-1.0, and the new version
>> bar-1.0.1 decides to export foo. With the current behaviour, this change
>> would break my module. With Malcolm's proposal the old code would continue
>> to work.
> 
> That's a very good point. Given that and the above, I don't understand
> your conclusion:
> 
>>Anyway, count me as +1 on the proposal. It would improve the
>> long-term stability of Haskell code.
> 
> How is adding more ways to break something "improving the long-term 
> stability"?
> 
> Regards,
> 
> Erik
> ___
> Glasgow-haskell-users mailing list
> Glasgow-haskell-users@haskell.org
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
> 

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-21 Thread Daniel Trstenjak

Hi Erik,

> But right now, we have a useful property that adding imports and code
> to a module does not break or change other code in that module. With
> this extension, that changes.

So your biggest concern is about silent breakage of code, that suddenly
a different function is used which has the same name and type, but
different semantics.

In all other cases the compiler would throw an error, because the types
wouldn't match.

I have the feeling, that the proposal shouldn't be about implicit/explicit 
imports,
but about prefering the function with the fitting type.

If there're two functions with the same name and type in scope, then the
compiler most likely should always throw an error.

The only exception might be, if there's a function locally defined in the
module, then this one might be prefered over every imported one with the
same name and type. But perhaps even in this case it might be a good idea to
throw an error.


Greetings,
Daniel
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-21 Thread Mario Blažević

On 14-10-21 07:14 AM, Erik Hesselink wrote:

On Mon, Oct 20, 2014 at 11:57 PM, Mario Blažević  wrote:

On 14-10-19 08:10 AM, Erik Hesselink wrote:


Adding an explicit
import can suddenly cause type errors in completely unrelated places
(when it hides an implicit import and the new function is type
incorrect), or worse, can cause semantic change (when it hides an
implicit import and the new function is type correct, but has
different behavior). Remember that not all code is written by the same
person, or in a short time frame, so not everybody might fully
understand every module and every import of the code they're editing.


 Your example requires somebody actively editing the import list. A
code change causes a compile error or worse? That is not all that
surprising.


But right now, we have a useful property that adding imports and code
to a module does not break or change other code in that module. With
this extension, that changes. I find this kind of local reasoning very
useful, IMHO it's one of the most useful things about Haskell in
general.


	Right now, adding an import can certainly cause a compiler error. It 
can't change the run-time behaviour of a correct module, that is true.


	With the proposal, there would be still be a somewhat weaker guarantee: 
adding an *implicit* import would never change the module's run-time 
behaviour.




 No, what I find much worse is a cabal update causing an error in a
module that was correct before the update. Consider


module Main where

import Foo (foo)
import Bar

main = foo


 Now suppose Bar came from the package bar-1.0, and the new version
bar-1.0.1 decides to export foo. With the current behaviour, this change
would break my module. With Malcolm's proposal the old code would continue
to work.


That's a very good point. Given that and the above, I don't understand
your conclusion:


 Anyway, count me as +1 on the proposal. It would improve the
long-term stability of Haskell code.


How is adding more ways to break something "improving the long-term stability"?


	You seem determined to misunderstand every message in this thread. What 
I said was that the change from bar-1.0 to bar-1.0.1 breaks the example 
code *with the current behaviour*. The proposal removes this breakage. 
Anything that keeps the old code compiling and working with new 
libraries improves its long-term stability in my book.


	Note that the bar-1.0.1 upgrade wasn't even a major version change. 
This is correct according to the PVP:



Otherwise, if only new bindings, types, classes, non-orphan instances
or modules (but see below) were added to the interface, then A.B may
remain the same but the new C must be greater than the old C.


but it still breaks the example module.

	Mind you, while the current proposal only increases the chances that 
old Haskell code continues to work with new libraries. If my module had 
defined a function foo itself instead of importing it, the upgrade would 
still break it. An extended version of the proposal might state that 
implicitly imported members get shadowed by local definitions as well, 
but this might be harder to implement. Besides, even this proposal 
wouldn't protect the importer from new instance imports from clashing 
with the local ones. There's no shadowing solution in this case.


	To summarize, the proposal is not providing any hard guarantees, and 
it's weakening an existing guarantee (see above). I'm still in favour, 
because it increases the stability of the legacy Haskell codebase.



___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-21 Thread Erik Hesselink
On Tue, Oct 21, 2014 at 4:55 PM, Mario Blažević  wrote:
> On 14-10-21 07:14 AM, Erik Hesselink wrote:
>>
>> On Mon, Oct 20, 2014 at 11:57 PM, Mario Blažević 
>> wrote:
>>>  No, what I find much worse is a cabal update causing an error in
>>> a
>>> module that was correct before the update. Consider
>>>
 module Main where

 import Foo (foo)
 import Bar

 main = foo
>>>
>>>
>>>  Now suppose Bar came from the package bar-1.0, and the new
>>> version
>>> bar-1.0.1 decides to export foo. With the current behaviour, this change
>>> would break my module. With Malcolm's proposal the old code would
>>> continue
>>> to work.
>>
>>
>> That's a very good point. Given that and the above, I don't understand
>> your conclusion:
>>
>>>  Anyway, count me as +1 on the proposal. It would improve the
>>> long-term stability of Haskell code.
>>
>>
>> How is adding more ways to break something "improving the long-term
>> stability"?
>
>
> You seem determined to misunderstand every message in this thread.
> What I said was that the change from bar-1.0 to bar-1.0.1 breaks the example
> code *with the current behaviour*. The proposal removes this breakage.
> Anything that keeps the old code compiling and working with new libraries
> improves its long-term stability in my book.
>
> Note that the bar-1.0.1 upgrade wasn't even a major version change.
> This is correct according to the PVP:

You're right, I misread your message. I understand now, and you're
right that this is currently something that can break your package,
although it happens so rarely that people still depend on major
version ranges, even though they sometimes don't use explicit or
qualified imports.

Regards,

Erik
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-21 Thread htebalaka
The current situation could be summed up as requiring some code duplication
when explicitly importing (due to the possibility of one or more redundant
hides), while encouraging a sort of measure-twice-cut-once mentality. Not
suggesting changing the default; I'll have a proposal detailing the exact
semantics and possible consequences of using it on the wiki on Thursday, so
that more people can weigh in.


Erik Hesselink wrote
> On Tue, Oct 21, 2014 at 4:55 PM, Mario Blažević <

> mblazevic@

> > wrote:
>> On 14-10-21 07:14 AM, Erik Hesselink wrote:
>>>
>>> On Mon, Oct 20, 2014 at 11:57 PM, Mario Blažević <

> mblazevic@

> >
>>> wrote:
>>>>  No, what I find much worse is a cabal update causing an error
>>>> in
>>>> a
>>>> module that was correct before the update. Consider
>>>>
>>>>> module Main where
>>>>>
>>>>> import Foo (foo)
>>>>> import Bar
>>>>>
>>>>> main = foo
>>>>
>>>>
>>>>  Now suppose Bar came from the package bar-1.0, and the new
>>>> version
>>>> bar-1.0.1 decides to export foo. With the current behaviour, this
>>>> change
>>>> would break my module. With Malcolm's proposal the old code would
>>>> continue
>>>> to work.
>>>
>>>
>>> That's a very good point. Given that and the above, I don't understand
>>> your conclusion:
>>>
>>>>  Anyway, count me as +1 on the proposal. It would improve the
>>>> long-term stability of Haskell code.
>>>
>>>
>>> How is adding more ways to break something "improving the long-term
>>> stability"?
>>
>>
>> You seem determined to misunderstand every message in this
>> thread.
>> What I said was that the change from bar-1.0 to bar-1.0.1 breaks the
>> example
>> code *with the current behaviour*. The proposal removes this breakage.
>> Anything that keeps the old code compiling and working with new libraries
>> improves its long-term stability in my book.
>>
>> Note that the bar-1.0.1 upgrade wasn't even a major version
>> change.
>> This is correct according to the PVP:
> 
> You're right, I misread your message. I understand now, and you're
> right that this is currently something that can break your package,
> although it happens so rarely that people still depend on major
> version ranges, even though they sometimes don't use explicit or
> qualified imports.
> 
> Regards,
> 
> Erik
> ___
> Glasgow-haskell-users mailing list

> Glasgow-haskell-users@

> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users





--
View this message in context: 
http://haskell.1045720.n5.nabble.com/Hiding-import-behaviour-tp5758155p5758451.html
Sent from the Haskell - Glasgow-haskell-users mailing list archive at 
Nabble.com.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-21 Thread htebalaka
It's occurred to me that a much simpler description of the proposed change
would be automatically lifting *uses* of the explicitly imported variable to
a qualified use, /if/ there was only one explicit import of the identifier.
For instance, with the following import:

import Data.Text.Lazy.IO (putStrLn)
import Prelude
import qualified Data.List as L
import qualified MyModule as L (isInfixOf)

automatically change any unqualified (and un-shadowed) use of putStrLn to
Data.Text.Lazy.IO.putStrLn, and any use of L.infixOf to MyModule.isInfixOf.

The latter should be easier to implement covering a number of corner cases:

* you can still refer to Prelude.putStrLn or Data.List.isInfixOf by
prepending the path, which the naive auto-hiding transformation would
prevent.
* possibly easier to have the pragma available to use in GHCi, since you
don't need to retroactively hide identifiers from previously imported
modules when a new explicit import is made.
* works better with imports like "import Data.Either (Either(..)); import
MyModule (Left)", which would otherwise require translating the Data.Either
import to something like "import Data.Either (Either(..)) hiding (Left)"
which isn't currently possible or "import Data.Either (Either(Right))" which
can't be done without knowing which modules export which identifiers.

The only remaining corner case is if you shadow the name of a module like:

import Data.Text.Lazy.IO (putStrLn)
import Prelude as Data.Text.Lazy.IO

An unqualified user of putStrLn /should/ refer to the text version, but if
anything translating it to Data.Text.Lazy.IO.putStrLn makes it more
ambiguous. I assume GHC can disambiguate even if the user can't, or if you
didn't want to cover that case the existing ambiguous identifier occurrence
error could still fire. Really just depends where in the pipeline the change
is implemented.

I suppose I'll describe both possible implementations. Functionally they're
the same, but maybe this one is simpler.



--
View this message in context: 
http://haskell.1045720.n5.nabble.com/Hiding-import-behaviour-tp5758155p5758463.html
Sent from the Haskell - Glasgow-haskell-users mailing list archive at 
Nabble.com.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-21 Thread Merijn Verstraaten


signature.asc
Description: Message signed with OpenPGP using GPGMail
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-23 Thread htebalaka
Proposal is up for your viewing pleasure:
http://www.haskell.org/haskellwiki/PermissiveImportsProposal



--
View this message in context: 
http://haskell.1045720.n5.nabble.com/Hiding-import-behaviour-tp5758155p5758553.html
Sent from the Haskell - Glasgow-haskell-users mailing list archive at 
Nabble.com.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Hiding import behaviour

2014-10-24 Thread Richard Eisenberg
Thanks for writing this up so clearly.

I'm +1 on the proposal as written. I think the (smallish) drawbacks are 
mitigated by the fact that the whole feature is opt-in.

Implementation should be relatively straightforward.

Thanks,
Richard

On Oct 23, 2014, at 2:22 PM, htebalaka  wrote:

> Proposal is up for your viewing pleasure:
> http://www.haskell.org/haskellwiki/PermissiveImportsProposal
> 
> 
> 
> --
> View this message in context: 
> http://haskell.1045720.n5.nabble.com/Hiding-import-behaviour-tp5758155p5758553.html
> Sent from the Haskell - Glasgow-haskell-users mailing list archive at 
> Nabble.com.
> ___
> Glasgow-haskell-users mailing list
> Glasgow-haskell-users@haskell.org
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users