Issue #43 20 Oct 2016
Written by: Jesse Squires
Remember SE-0025? That’s the proposal that controversially introduced fileprivate
. However, if you’re regretting this change (like me), then you might have another chance to be heard! See the mailing list discussion in this issue for details. This issue also covers “id-as-Any” and continues the on-going discussion about what should be considered a source-breaking change.
Starter tasks
- SR-2960: Better Document
utils/run-test
. Neitherbuild-script -h
nordocs/Testing.rst
mention the existence ofutils/run-test
, but they should. This is the best way to run a subset of the tests, and a huge quality-of-life improvement for working on the compiler or standard library. - SR-2948: Discarding a closure from a
@discardableResult
function results in a compile error. A function marked with@discardableResult
should not be a compiler error if its returning closure is not used.
Submit a task by sending a pull request or opening an issue.
Community
There’s a new post — Objective-C id as Swift Any — on the official Apple Developer Swift blog. It clearly explains the changes in Swift 3.0 regarding Objective-C id
importing into Swift as Any
instead of AnyObject
. If you’ve been confused about this, the post should clear things up!
If you are contributing to or interested in LLVM, the LLVM Developers’ Meeting is coming up on November 3-4.
Commits and pull requests
Rintaro Ishizaki has submitted a pull request to fix SR-2843. The theme of “is this a source-breaking change” returns!
In type parsing,
P1 & P2.Type
was parsed as(metatype (composition P1 & P2))
and accepted. On the other hand, in expression position,(P1 & P2.Type).self
was converted to justP1
(P2.Type
was silently discarded). This PR fixes this problem, while keeping source compatibility to the current behavior. That said, expr:(P1 & P2.Type).self
as type:P1
is just a bug. IMO, no need to keep this behavior.
DougGregor fixed an unintentional source-breaking change from Swift 3 regarding implicitly-unwrapped optionals and type inference.
Back in June, Austin Zheng rewrote native hashed collection indices, refactoring Dictionary
and Set
. This week, Alexis Beingessner took over and rebased the pull request and resolved conflicts. Despite some behavior differences and possible bridging performance regressions, it looks like the changes bring a lot of structural improvements to the code.
Greg Parker submitted a pull request for a new reference count representation (work-in-progress). Based on the benchmarks noted by @swift-ci, there seem to be quite a few regressions — but I’m sure these will be fixed before merging!
Dave Abrahams made a small tweak to (hopefully) speed up Set
/Dictionary
initialization from a Sequence
.
Doug Coleman opened a pull request to make the utils/update-checkout
python script run in parallel. 😎 This should be useful for contributors.
From this week’s LLVM weekly, a lengthy proposal on moving LLVM to GitHub was added. As mentioned before, having all of these projects on GitHub could be beneficial to Swift contributors, and possibly lower the barrier to getting involved with LLVM.
Proposals in review
SE-0144: Allow Single Dollar Sign as a Valid Identifier by Ankur Patel is under review. As discussed last issue, Ankur is the author of Dollar.swift which would break after a recent fix in the compiler.
The mainline Swift compiler emits an error message when the
$
character (U+0024) is used as an identifier by itself, which is a source breaking change from Swift 3.0.
This proposal suggests reverting this change, enabling the use of
$
as a valid identifier in future versions of Swift (>= 3.1).
Mailing lists
Ankit Aggarwal asked for feedback on a draft proposal for version pinning in SwiftPM.
The other week, David Hart started a discussion about private
and fileprivate
from SE-0025: Scoped Access Level, asking if “this ship has sailed” or not. As expected, the email elicited many responses from the community. Like David and Russ, I agree that this proposal was a mistake — in practice, using fileprivate
feels cumbersome and too complex. I find extremely little value in private
. In particular, these new access levels make type extensions more burdensome to implement since an extension
cannot access private
members. If the community is willing to put forth a detailed proposal with significant evidence to support that reverting SE-0025 would be best, it sounds like the Core Team will review it. As Lattner notes below, this would require a “pretty high burden of proof.” In any case, this discussion can be deferred until Spring — after Swift 4 Phase 1 is completed.
From David Hart:
[…] I instead want to share my experience using
private
andfileprivate
since release. Here are my thoughts:We should start with the premise that the proposal has added a substantial amount of complexity:
It has added an extra modifier and access level to learn. It has complicated the access level rules with Inner types as mentioned in the Complications with private types section of the proposal. I have seen many people (twitter, work, slack) be confused about the difference between
private
andfileprivate
at the global level. The answer is none, which shows that both modifiers are not very orthogonal. Since release, I saw people prefer one over the other, as a matter of style. They tend to always usefileprivate
or always usingprivate
. In the latter case, functions and properties get clumped in the same class scope instead of be written through multiple extensions.I have the impression that the motivations for the proposal are much less real in practice:
The first motivation stated is: “It is not clear whether the implementation details are meant to be completely hidden or can be shared with some related code without the danger of misusing the APIs marked as
private
.” I’ve found that to be fairly rare in practice because the implementation details only used to leak inside the same file, which greatly reduces the dangers. The second motivation stated is: “It forces a one class per file structure, which is very limiting.” First of all, this is partly false. I think it forces putting classes which share implementation details in the same file, which I don’t think is necessarily a bad thing.To summarise, it seems that the confusion the proposal brought over semantics and style are not worth the limited benefits that it brought. I’d be tempted to backtrack the proposal and re-introduce
private
as a file scoped access-level and deprecatefileprivate
.
I agree. The minor benefit that
fileprivate
brings is not worth the cognitive overhead it introduces. We should just admit it was a mistake and back it out. We can avoid source-breaking changes by makingfileprivate
a synonym for private and provide fixits/warnings for a release to give people a chance to move off it.
[…] This proposal has been litigated numerous times already, and the bar for source-breaking changes is much higher now. To effectively re-open the discussion would require a proposal that significantly changes the model with a lot of evidence that such a new model is a drastic improvement over what we have now. “Back out SE-0025” is not a viable option now.
[…] I’m convinced as the Swift language and other Swift-based projects both gain more maturity, we will be able to get a holistic view of how access control should work and how it should correlate to project structure. Before then, any change may simply do more harm than good.
Not speaking for the core team, just MHO:
I agree with Russ here, and with others who have said upthread that the “thing that has changed” is that we are starting to get usage experience with
fileprivate
vsprivate
. I think we all understand the value of having fewer access control levels, and so if “private” isn’t conceptually pulling its weight, then it is reasonable to consider phasing it out.That said, there is no specific rush to have this discussion, and I think it is reasonable to put a pretty high burden of proof on someone who wants to drive such a proposal. For example, if we had the discussion in the spring timeframe, we should have a pretty large body of Swift 3 code readily at hand (e.g. SwiftPM packages and other various github repos).
Given that, it should be easy enough to see how widely
private
is actually being used in practice. If it is very rare, then the argument to ditch it (make it a synonym forfileprivate
, and eventually phasing outfileprivate
) is strong. If lots of people are usingprivate
and only some are usingfileprivate
, then the discussion is quite different.
Finally
And finally — tabs or spaces? 😄