<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Jul 9, 2021, at 12:35 AM, Eric Seidel <<a href="mailto:eric@seidel.io" class="">eric@seidel.io</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">On Thu, Jul 1, 2021, at 13:16, Joachim Breitner wrote:<br class=""><blockquote type="cite" class="">a different way to phrase that question might be: Do we want these<br class="">defaulting declarations to behave just exactly like named things, or<br class="">exactly like typeclass instances, or do we afford a new class with it’s<br class="">own exporting/importing behavior. Is that a fair assessment?<br class=""></blockquote><br class="">Not entirely, I think. <br class=""><br class="">We currently have two types of import/export behavior:<br class="">named things, and typeclass instances. The proposal as currently<br class="">written places defaulting rules somewhere in between: defaulting<br class="">rules are exported like named things, but imported like class instances.<br class="">This is new, but not too foreign, as the behavior on both sides exactly<br class="">matches existing behavior we're familiar with. It's just the combination<br class="">that's new.<br class=""></div></div></blockquote><div><br class=""></div><div>This doesn't match my understanding of the proposal. It looks to me that, as written in the proposal, exports of a `default` would have to be explicit. That is, a module starting with `module M where ...` would not export any defaults. This fact is a bit implied in the proposal ("This
proposal does not modify that behaviour: a <code class="">default</code> declaration by itself does not apply outside its module."), but it's my best understanding. </div><br class=""></div>---<div class=""><br class=""></div><div class="">Simon and I have discussed. We both came to an agreement that imports should have to be explicit.</div><div class=""><br class=""></div><div class="">GHC currently has two import/export strategies.</div><div class=""><br class=""></div><div class="">Strategy 1: Always. In the Always strategy, an entity is always exported from a module and always brought into scope from an imported module. The Always strategy is used for type and class instances.</div><div class=""><br class=""></div><div class="">Strategy 2: Public. In the Public strategy, an entity is exported by default (no export list) or when explicitly included in an export list. It is brought into scope from an importing module by default (no import list) or when explicitly included in an import list. A Public entity may be excluded from scope by a `hiding` clause. All top-level named entities are exported/imported via the Public strategy.</div><div class=""><br class=""></div><div class="">I propose (with Simon's support)</div><div class=""><br class=""></div><div class="">Strategy 3: Private. In the Private strategy. an entity is exported only when explicitly included in an export list, and it is brought into scope from an imported module only when explicitly included in the import list. I propose we use Private for `default` declarations (only).</div><div class=""><br class=""></div><div class="">Reasons:</div><div class=""><br class=""></div><div class="">* Changing defaulting behavior really can launch the rockets. Suppose T has a Num instance whose fromInteger uses unsafePerformIO to launch the rockets. Then including T in an import list could make a very innocent-looking `x = 5` declaration launch the rockets.</div><div class=""><br class=""></div><div class="">* GHC currently supports an option -ddump-minimal-imports, which displays import lists describing what symbols must be brought into scope from an imported module. If a `import M` import statement brought defaulting behavior into scope, then going from `import M` to `import M (foo, bar)` might deleteriously change defaulting behavior, thus invalidating the work of -ddump-minimal-imports.</div><div class=""><br class=""></div><div class="">* The proposal as written does not describe how `module` exports work with named defaults. For example, what happens in `module B (module A) where import A`? Normally, that re-exports all names in scope both as `A.blah` and as `blah`. But, of course, a default isn't named in this way. So is the default exported? By requiring explicit inclusion in the export list, the Private strategy sidesteps this question.</div><div class=""><br class=""></div><div class="">* This is a more conservative choice. We can always revisit this in the light of experience. However, if defaults were always imported, it would be much more disruptive to make them imported only by request.</div><div class=""><br class=""></div><div class="">We have rightly identified that using the Private strategy would potentially reduce the usefulness of this idea, especially with alternative Preludes. As far as I know, GHC does not currently officially support having an alternative Prelude. That is, an "alternative Prelude" is really just disabling the import of base.Prelude and then importing some other module. However, we could imagine a compiler flag that specifies another package (or module name) to use as the Prelude... and then we could also specify how it is imported. For example, we could say that the Prelude is imported with</div><div class=""><br class=""></div><div class="">> import Prelude</div><div class="">> import Prelude ( default(..) )</div><div class=""><br class=""></div><div class="">where the second line says to grab all the defaults. I think this would be reasonable, but not necessary in the first version of this current proposal.</div><div class=""><br class=""></div><div class="">Richard</div></body></html>