[swift-evolution] [Review] SE-0005 Better Translation of Objective-C APIs Into Swift

Dave Abrahams dabrahams at apple.com
Mon Feb 1 19:49:51 CST 2016

on Mon Feb 01 2016, Tony Parker <swift-evolution at swift.org> wrote:

> Hi Drew,
>> On Jan 30, 2016, at 3:01 PM, Drew Crawford via swift-evolution
>> <swift-evolution at swift.org> 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 <module> import * ) should be avoided, as
>>> they make it unclear which names are present in the namespace,
>>> confusing both readers and many automated tools. There is one
>>> defensible use case for a wildcard import...
>> When a language has a robust namespacing system, which we do not,
>> there are many follow-on consequences.  One is that an import
>> statement is much more of a scalpel than a bludgeon; each import
>> statement only introduces a handful of new names (even if it is a
>> so-called "wildcard" import that grabs all children of some
>> namespace, most of those children are themselves namespaces), unlike
>> importing Foundation which contains thousands of direct child types
>> that are injected into the local scope.
>> Another consequence is that class names become quite short, shadow
>> each other, and nobody bats an eye.  I searched the C# standard
>> library for "Session", and found some 12 classes with that name:
>> <Screen Shot 2016-01-30 at 3.44.23 PM.png>
>> These "standard library" classes not only potentially shadow
>> programmer-defined types, they also shadow each other.  But because
>> the C# language has a robust namespacing system, the chances of
>> there being more than one thing called "Session" in scope in your
>> program (or for that matter, when developing the standard library
>> itself) is quite small, so it's a non-issue.
>> Now we return to the question of dropping the NS prefix, which will
>> rename thousands of classes in a typical program that has `import
>> Foundation`, in a way that potentially (let's be honest.  More like
>> "probably") shadows one or more programmer-defined classes.  Our
>> review criteria is:
>>> Is the problem being addressed significant enough to warrant a change to Swift?
>> No, the elimination of 2 characters is not significant enough of a
>> problem to break all Swift programs, let alone to introduce
>> literally thousands of new opportunities for shadowing.
>> To its credit, the proposal acknowledges this, and offers a concession:
>>> Note that this removal can create conflicts with the standard
>>> library. For example, NSString and NSArray will become String and
>>> Array, respectively, and Foundation's versions will shadow the
>>> standard library's versions.  In cases where the Swift 3 names of
>>> standard library entities conflict with prefix-stripped Foundation
>>> entities, we retain the NS prefix. These Foundation entities are:
>>> NSArray, NSDictionary, NSInteger, NSRange, NSSet, and NSString.
>> But of course this needlessly draws a distinction between NSString
>> et al and the "normal" Foundation types, and what's more it draws
>> that distinction based on the present composition of the Swift
>> standard library and the present composition of Foundation.  But we
>> have already decided not to guarantee the source compatibility of
>> the standard library, so what happens when that composition changes?
>> Will we then go back and tweak which classes get NS prefixed to them
>> again?
>> In my view, if Swift's namespacing is not good enough to let us drop
>> the NS in NSString it is not good enough to drop any prefix.  If we
>> believe that a programmer will struggle to distinguish between Swift
>> String and Foundation String then we should expect them to struggle
>> for any two classes in any two frameworks, and this is special
>> pleading on the part of Foundation.  C#'s libraries declare *twelve*
>> different `Session`s and nobody bats an eye, but we have two types
>> share a name and everybody loses their minds?  Our namespacing is
>> not good enough to kill the prefix, period.
> I’m actually not sure how this line about shadowing ended up in the
> guidelines, 

Tony, what do you mean?  Unless I missed something, nobody is claiming
that the guidelines say anything directly about shadowing.

> because it is not our plan. Instead, I have always wanted to do
> something very close to what you suggest and rename these to something
> like “Dynamic.Array” to reflect its role as a dynamically-dispatched,
> subclass-capable Array.
> Types like NSURL are intended to be the canonical URL for everyone to
> use, so for me it feels very natural to drop the prefix and make them
> as accessible as Array, String, etc.
> - Tony
>> We should either drop these prefixes or we should not; because the
>> claimed motivation–that we have "good enough" namespacing in the
>> language now–is either true or it is not.  This proposal admits that
>> it is not, and tries to drop the prefixes anyway.  I believe that is
>> a mistake.
>> I certainly support the goal of eliminating these prefixes, they are
>> ugly, they need to be killed, and namespacing is the right solution.
>> But we must not jump out of the plane until we are very sure our
>> parachute is in order.  In Swift 3 it is not.
>> I do think the bulk of the proposal is fine, and I apologize for
>> using quite stark language for such a small paragraph in an
>> otherwise reasonable proposal, but I think the problem buried in
>> here is quite serious and is being overlooked.
>> Drew
>>> On Jan 22, 2016, at 3:02 PM, Douglas Gregor via swift-evolution
>>> <swift-evolution at swift.org
>>> <mailto:swift-evolution at swift.org>>
>>> wrote:
>>> Hello Swift community,
>>> The review of SE-0005"Better Translation of Objective-C APIs Into
>>> Swift" begins now and runs through January 31, 2016. The proposal
>>> is available here:
>>> https://github.com/apple/swift-evolution/blob/master/proposals/0005-objective-c-name-translation.md
>>> <https://github.com/apple/swift-evolution/blob/master/proposals/0005-objective-c-name-translation.md>
>>> Reviews are an important part of the Swift evolution process. All
>>> reviews should be sent to the swift-evolution mailing list at
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> or, if you would like to keep your feedback private, directly to
>>> the review manager. When replying, please try to keep the proposal
>>> link at the top of the message:
>>> Proposal link:
>>> https://github.com/apple/swift-evolution/blob/master/proposals/0005-objective-c-name-translation.md
>>> <https://github.com/apple/swift-evolution/blob/master/proposals/0005-objective-c-name-translation.md>
>>> Reply text
>>> Other replies
>>>  <https://github.com/apple/swift-evolution#what-goes-into-a-review-1>What
>>> goes into a review?
>>> The goal of the review process is to improve the proposal under
>>> review through constructive criticism and, eventually, determine
>>> the direction of Swift. When writing your review, here are some
>>> questions you might want to answer in your review:
>>> What is your evaluation of the proposal?
>>> Is the problem being addressed significant enough to warrant a change to Swift?
>>> Does this proposal fit well with the feel and direction of Swift?
>>> If you have used other languages or libraries with a similar
>>> feature, how do you feel that this proposal compares to those?
>>> How much effort did you put into your review? A glance, a quick
>>> reading, or an in-depth study?
>>> More information about the Swift evolution process is available at
>>> https://github.com/apple/swift-evolution/blob/master/process.md
>>> <https://github.com/apple/swift-evolution/blob/master/process.md>
>>> Thank you,
>>> -Doug Gregor
>>> Review Manager
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> <mailto:swift-evolution at swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution


More information about the swift-evolution mailing list