|
Subject: Re: [Review] SE-0005 Better Translation of Objective-C APIs Into Swift Newsgroups: gmane.comp.lang.swift.evolution Date: Monday 1st February 2016 21:24:23 UTC (9 months ago) +1 to Nate's reasoning. I understand this might be quite controversial, and I appreciate the work that's been done on Foundation, but I am wary about canonicalizing a "standard library" that cannot fully embrace Swift features and idioms as such, at least at this point in time. I understand the desire to make open-source Foundation a standard for cross-platform development, but this should not be at the expense of libraries which seek to provide 'Swiftier' solutions to the same problems. Best, Austin On Mon, Feb 1, 2016 at 1:10 PM, Nate Cook via swift-evolution < [email protected]> wrote: > This is a concurring opinion with Drew's review, agreeing that we should > reconsider removing the "NS" prefix but providing my own reasons. The > proposal as a whole is exciting and far-reaching, but this particular > change is misguided. My objections are: > > *1) The change will elide the different semantic expectations for > Foundation and Swift standard library types.* > > Prefix-less Foundation types will blur the different norms and > expectations for Foundation types vs what we have in the Swift standard > library, particularly in regards to value vs reference semantics of > collection types. > > The Swift standard library defines Array, Set, and Dictionary as > collection types with value semantics that operate quite differently from > their peers in Foundation. This change will introduce OrderedSet, > CountedSet, HashTable, MapTable, and others, all of which use reference > semantics and therefore don't provide the same set of guarantees about > ownership and immutability. > > As an example, the seemingly similar Set and CountedSet types produce > different results from nearly identical code. Swift's Set type has value > semantics, so changes to a copy don't affect the original Set instance: > > let simpleSet = Set(["one", "two", "three"]) > var copiedSimpleSet = simpleSet > copiedSimpleSet.remove("one") > > copiedSimpleSet.contains("one") // false > simpleSet.contains("one") // true > > CountedSet (née NSCountedSet), on the other hand, uses reference > semantics, so changes to a copy of an instance. This is true whether the > copy is an explicit one made via assignment or the implicit copy made when > calling a function with CountedSet as a parameter. This example shows how > nearly code nearly identical to the above produces very different results: > > let countedSet = CountedSet(array: ["one", "two", "three"]) > var copiedCountedSet = countedSet > copiedCountedSet.remove("one") > > copiedCountedSet.contains("one") // false > countedSet.contains("one") // false! > > Collections constructed from immutable/mutable class clusters (like > OrderedSet and MutableOrderedSet) pose the same problems, since you may be > using a mutable instance of the "immutable" collection. We clearly are > already dealing with this difference today, but eliminating the "NS" prefix > implies that Foundation types are on the same level as the standard > library. This makes the confusion more pronounced and significantly > increases both the learning curve of the Swift & Foundation APIs and the > risk of errors when using different collection types. > > *2) The change may stifle the development of more Swift-oriented APIs.* > > Foundation types were developed in and for a language that uses reference > semantics and subclassing, rather than value semantics and a > protocol-oriented approach. The designs therefore use and reinforce norms > that relate better to Objective-C than to Swift—class clusters of > non-final, immutable types with mutable subclasses, immutable types with > separate but related mutable counterparts, etc. > > A Swift-native CountedSet (and other collections) would surely have value > semantics built in. What about other types—do the new > Calendar/Date/DateComponents types look like the system that we would > design from the ground up in Swift? How about URL and URLComponents? > Dropping the "NS" prefix would make it more difficult to gradually expand > the standard library to encompass bridging versions of these and other > common types. > > *3) The change will make it harder to find information about the revised > APIs.* > > Excellent search-ability is an unintended benefit of the "NS" prefix, and > can be understood as a way that these types avoid collisions in the vast > namespace-less sea of Internet search results. Searching for help with URL > and Calendar will be much more difficult than their NS'ed counterparts. > > Especially given the challenges that this proposal will pose for code > sourced from tutorials, blog posts, Stack Overflow answers, etc., keeping > at least the class names as sign posts seems valuable. > > *4) We'll still be using prefixes after the change.* > > While the removal of "NS" is far-reaching, prefixes will still be a common > occurrence in code written in Swift. UIKit and AppKit, along with all the > various frameworks, will still retain their prefixes, so removing prefixes > in the case of Foundation types will be more the exception than the norm. > As such, any benefit of the removal would be mitigated by the continued use > of prefixes for the rest of the first-party types we rely on. > > > In sum, the change would make the language and its APIs more confusing and > more difficult to use today, would make it more difficult to migrate to > modern designs in the future, and would ultimately provide a very minor > benefit. I encourage the Swift core team to reconsider the "Strip the "NS" > prefix from Foundation APIs" portion of the proposal. > > Nate > > > On Jan 30, 2016, at 5:01 PM, Drew Crawford via swift-evolution < > [email protected]> wrote: > > I am in favor of this proposal on balance, and I leave the bulk of this to > people who interop with Objective-C more often than I do. > > I would like to confine my remarks to one corner where I think we are > making a very serious mistake. > > The removal of the "NS" prefix for the Foundation module (or other > specifically identified modules) is a mechanical translation for all global > symbols defined within that module that can be performed in the Clang > importer. > > > As I understand it (and I am no Cocoa historian) the NS prefix was > originally introduced because Objective-C lacks namespacing. > > The thinking seems to be that since Swift has proper namespacing, this > historicism is no longer necessary. I find this argument very flimsy. > > Of course Swift has stronger namespacing if one's frame of reference is > Objective-C or C. But for those of us coming from other language > backgrounds, namespacing means something much stronger than Swift's concept > of it. I don't mean to suggest that Swift's design is wrong exactly (less > is sometimes more), but I do mean to say that if we propose to undo a > decision that worked for several decades and break every Swift project in > existence on the theory that Swift's namespacing is strong enough we had > better be right. > > For those unfamiliar, I will explain some of the namespacing tools Swift > lacks relative to other languages. First, many languages have a > "hierarchical" namespace system, where one can say > > import Foundation.Net.URL > let s = Session(...) > > > instead of for example > > import Foundation > let s = NSURLSession(...) > > > Some form of this is used in Rust, Python, and C#, as far as I know. I > believe Swift has some counterfeit version of this, as the book mentions > you can import a "submodule > <https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/swift/grammar/import-declaration>", > but I do not know what that is, do not know how to make one, have never > seen anyone use one, the book suggests it goes only 2 levels deep, and > perhaps as a consequences of some of these problems nobody thought of using > this for Foundation. > > A closely related difference is the use of so-called "selective" imports, > where we import only a single symbol (or a list of explicitly-identified > symbols) into the scope. We might express this as > > from Foundation.Net.URL import Session, HTTP //import two classes only > let s = Session(...) > > > Again I think Swift technically supports some way to avoid importing a > whole gigantic namespace like Foundation, but I am not aware of any actual > uses of this feature, and certainly the convention is not to write code > this way. Meanwhile, let's check in with the Python community, who > standardized the following guidance on these "wildcard" imports as part of > their language evolution process: > > Wildcard imports ( from |
||