Haskell has much more than import everything and import itemized. https://wiki.haskell.org/Import
Hiding is important for avoiding collisions of name and/or function. On Mon, Jul 18, 2016 at 9:19 PM, Joe Groff via swift-evolution < [email protected]> wrote: > Our import story definitely needs work, and this is a step in the right > direction. Thanks for working on this! Some comments: > > - The import changes can be separated from the submodule issues. Enhancing > imports is IMO more important, and is source-breaking today, whereas > 'module ' declarations and submodules can be added later. I'd suggest > breaking this into two proposals. > - I think the `import` design you propose is a bit more complicated than > it needs to be. Python and Haskell get by just having "import everything" > and "import itemized (with aliases)". I don't see the need for 'hiding'; if > you have a rule that itemized imports get priority over import-everything, > then that covers the most important use case of selectively shadowing one > module's imports with another. Bikeshed-wise, I don't see much reason to > veer from the Java/Haskell-ish template of: > > import Foo.* // import everything from module Foo > import Foo.(x, y, z as zed) // import x, y, and z from foo, renaming Foo.z > to zed > > -Joe > > > On Jul 18, 2016, at 2:09 PM, Robert Widmann via swift-evolution < > [email protected]> wrote: > > > > Hello all, > > > > TJ Usiyan, Harlan Haskins, and I have been working on a proposal to > rework qualified imports and introduce an explicit module system to Swift > that we’d like to publish for your viewing pleasure. > > > > The initial impetus was set out in a radar (rdar://17630570) I sent > fairly early on that didn’t receive a response, so I started a > swift-evolution thread discussing the basics of this proposal. It has been > refined and expanded a bit to include an effort to make Swift modules > explicit and updated with the feedback of that first thread. Contents of > the proposal are inline and can also be had as a gist or on Github. > > > > Cheers, > > > > ~Robert Widmann > > > > Qualified Imports and Modules > > > > • Proposal: SE-NNNN > > • Authors: Robert Widmann, Harlan Haskins, TJ Usiyan > > • Status: Awaiting review > > • Review manager: TBD > > Introduction > > > > We propose a complete overhaul of the qualified imports syntax and > semantics and the introduction of a module system. > > > > Motivation > > > > Swift code is modular by default. However, it is not clear how to > decompose existing modules further into submodules. In addition, it is > difficult to tell how importing a module affects its export to consumers of > a library. This leads many to either fake namespaces with enums, attempt to > structure Swift code with modulemaps, or use a large amount of > version-control submodules. All of these can be rolled into one complete > package in the form of a comprehensive rethink of the qualified import > system and the introduction of a module system. > > > > Proposed solution > > > > Modules will now become an explicit part of working with canonical Swift > code. The grammar and semantics of qualified imports will change completely > with the addition of import qualifiers and import directives. We also > introduce three new contextual keywords: using, hiding, and renaming, to > facilitate fine-grained usage of module contents. > > > > Detailed design > > > > Qualified import syntax will be revised to the following > > > > module-decl -> module <module-path> > > import-decl -> <access-level-modifier> import <module-path> <(opt) > import-directive-list> > > module-path -> <identifier> > > -> <identifier>.<import-path> > > import-directive-list -> <import-directive> > > -> <import-directive> <import-directive-list> > > import-directive -> using (<identifier>, ...) > > -> hiding (<identifier>, ...) > > -> renaming (<identifier>, to: <identifier>, ...) > > > > This introduces the concept of an import directive. An import directive > is a file-local modification of an imported identifier. A directive can be > one of 3 operations: > > > > 1) using: The using directive is followed by a list of identifiers > within the imported module that should be exposed to this file. > > > > // The only visible parts of Foundation in this file are > > // Date.init(), Date.hashValue, and Date.description. > > import Foundation.Date using (Date.init(), Date.hashValue, > Date.description) > > 2) hiding: The hiding directive is followed by a list of identifiers > within the imported module that should be hidden from this file. > > > > // Imports all of Foundation.Date except `Date.compare()` > > import Foundation.Date hiding (Date.compare()) > > 3) renaming: The renaming directive is followed by a list of identifiers > separated by to: that should be exposed to this file but renamed. > > > > // Imports all of Dispatch.DispatchQueue but renames the static member > > // DispatchQueue.main, to DispatchQueue.mainQueue > > import Dispatch.DispatchQueue renaming (DispatchQueue.Type.main to: > DispatchQueue.Type. > > mainQueue) > > > > // Renaming can also rename modules. All members of UIKit have to be > qualified with > > // `UI` now. > > import UIKit renaming (UIKit, to: UI) > > Import directives chain to one another and can be used to create a > fine-grained module import: > > > > // Imports all of Foundation except `DateFormatter` and renames `Cache` > to `LRUCache` > > import Foundation > > hiding (DateFormatter) renaming (Cache to: LRUCache) > > > > // Imports SCNNode except SCNNode.init(mdlObject:) and renames > `.description` to > > // `.nodeDescription` > > import SceneKit > > using (SCNNode) > > renaming (SCNNode > > .description, to: SCNNode. > > nodeDescription) > > hiding (SCNNode > > .init(mdlObject:)) > > Directive chaining occurs left-to-right: > > > > // This says to 1) Hide nothing 2) Use nothing 3) rename Int to INT. It > is invalid > > // because 1) We will show everything 2) Then hide everything 3) > Therefore Int is unavailable, error. > > import Swift hiding () using () renaming (Int > > , to: INT) > > > > // This says to 1) Use Int 2) Hide String 3) rename Double to Triple. > It is invalid > > // because 1) Int is available 2) String is not, error. 3) Double is > unavailable, error. > > import Swift using (Int) hiding (String) renaming (Double > > , to: Triple) > > > > // Valid. This will be merged as `using (Int)` > > import Swift using () using (Int > > ) > > > > // Valid. This will be merged as `hiding (String, Double)` > > import Swift hiding (String) hiding (Double > > ) hiding () > > > > // Valid (if redundant). This will be merged as `using ()` > > import Swift using (String) hiding (String) > > Module scope is delimited by the keyword module followed by a fully > qualified name and must occur as the first declaration in a file. For > example: > > > > // ./Math/Integers/Arithmetic.swift > > > > module Math > > .Integers. > > Arithmetic > > > > > > public protocol > > _IntegerArithmetic {} > > > > > > public struct > > _Abs {} > > > > > > @_versioned > > internal func _abs<Args>(_ args: Args) -> > > (_Abs, Args) {} > > > > > > // ./Math/Integers.swift > > > > module Math > > . > > Integers > > > > > > // _abs is visible in this module and all others within the project, > > // but is not exported along with it. > > internal import Math.Integers.Arithmetic > > > > > > > > public protocol IntegerArithmetic : _IntegerArithmetic, Comparable > > {} > > > > public protocol SignedNumber : Comparable > > , ExpressibleByIntegerLiteral {} > > > > > > > > // Math.swift > > > > module Math > > > > > > // Exports the entire public contents of Math.Integers, but nothing in > > // Math.Integers.Arithmetic. > > public import Math.Integers > > Modules names are tied to a directory structure that describes their > location relative to the current module and it will now be an error to > violate this rule. For example: > > > > module String // lives in ./String.swift > > > > module > > String.Core // lives in ./String/Core.swift > > > > module > > String.Core.Internals.Do.You.Even.Write // lives in > ./String/Core/Internals/Do/You/Even/Write.swift > > Existing projects that do not adopt these rules will still retain their > implicit module name (usually defined as the name of the framework or > application that is being built) and may continue to use whatever directory > structure they wish, however they may not declare any explicit modules. > > > > This proposal also solves the problem of module export. A module that is > imported without an access level modifier will default to an internal > import per usual. However, when it is useful to fully expose the public > content of submodules to a client, a public modifier can be used. > Similarly, when it is useful to access internal or [file]private APIs, but > not expose them to clients, those access modifiers may be used. The rule of > thumb is: Only identifiers that are at least as visible as the qualifier on > the import make for valid import declarations. For example: > > > > // A submodule declaring a `private` class that gets imported with > > // an `internal` qualifier with a `using` directive is an invalid import > > // declaration. > > > > module Foo > > . > > Bar > > > > > > private class > > PrivateThing {} > > > > module Foo > > > > > > // Error: PrivateThing not visible, use `private import` > > import Foo.Bar using (PrivateThing) > > // However, a submodule declaring a `public` struct that gets imported > with > > // an `private` qualifier is a valid import declaration. > > > > module Foo > > . > > Bar > > > > > > public class > > PublicThing {} > > > > module Foo > > > > > > // All good! Foo can see Foo.Bar.PrivateThing. > > private import Foo.Bar using (PublicThing) > > Because import directives are file-local, they will never be exported > along with a public import and will default to exporting the entire > contents of the module as though you had never declared them. > > > > // In this file and this file alone, the directives apply. To the user > > // of this module, it is as though this declaration were simply: > > // public import Foundation.Date > > public import Foundation.Date hiding (Date.init > > ()) > > renaming (Date > > .Type. > > distantPast, > > to: Date > > .Type. > > letsGoLivingInThePast, > > Date > > .Type. > > timeIntervalSinceReferenceDate, > > to: Date > > .Type. > > startOfTheUniverse) > > renaming (Date > > .Type.<, to: Date.Type.<<<<<) > > Impact on existing code > > > > Existing code that is using qualified module import syntax (import > {func|class|typealias|class|struct|enum|protocol} <qualified-name>) will be > deprecated. Code that is not organized into modules will remain unaffected > and organized into one contiguous top-level module. However, it is strongly > recommended that frameworks be decomposed and reorganized around the new > module system. > > > > As a case study, the public interface to the standard library appears to > already be mostly broken down into submodules as described in > GroupInfo.json. > > > > Code that is defined in modulemaps already defines a module structure > that can be imported directly into this scheme. > > > > Alternatives considered > > > > Module export can also be placed on the module declaration itself. The > relevant parts of the grammar that have changed are below with an example: > > > > module-decl -> <access-level-modifier> module <module-path> > > import-decl -> import <module-path> <(opt) import-directive-list> > > > > private module String.Core. > > Internals > > > > > > // Shh, it's a secret. > > While this style makes it immediately obvious to the library author > which modules are public or private, it causes the consumer problems > because submodule exports are no longer explicit and are entirely ad-hoc. > In the interest of enabling, for one, users of IDEs to drill into public > submodules, making export local to import seems more appropriate. > > _______________________________________________ > > swift-evolution mailing list > > [email protected] > > https://lists.swift.org/mailman/listinfo/swift-evolution > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
