Skip to main content

Swift Evolution, July 2016

Tags

Julu 2016

As a follower and contributor to the Swift language every once and awhile I like to take stock of the latest proposals on Swift Evolution and see what has been accepted, what is in-review, or what has been rejected for the current release of the language.  This allows me to gauge the direction of the language and to also see what Apple's reaction is to different proposal's in case I ever wanted to write my own proposal for Swift. 

Before I dive into my thoughts and opinions are on the outlined proposals I thought it might be a good time to discuss the question, "What is Swift Evolution?"  Swift Evolution is a central repository for all of the coming and going proposals to the Swift language.  Apple is completely developing the Swift language out in the open and encourages the community to get involved as much as possibly.  Swift Evolution is a Github repository that allows the community to see the decision making process that Apple is going through as they evaluate proposals and decide which one's are and are not valuable to the language.  You can check out all of the approved proposals for upcoming releases of Swift and see which one's are being discussed for future releases of the language.

Below I have outlined 3 interesting language proposals and 1 proposal that I am personally interested in because of my own interest in data science.  

 

Drop NS Prefix in Swift Foundation  SE-0086

Authors: Tony Parker, Philippe Hausler.

As mentioned in my Swift 3.0 post, Apple is removing all NS prefixes for all Swift Foundation types.  This will largely remove any legacy "Next Step" prefix's and allow the language to pave it's own direction without being tied to the "Next Step" or the Objective-C era.  When you think about what is happening with this proposal, this is a pretty big deal.  It is almost like saying "OK Next Step and Objective-C, you have taken the language and the platform this far, but now we will take it from here and blaze our own path!"  It is also important from a language perspective that the core libraries be as small and as concise as possible, and this proposal is a clear indication that the future of Swift is making improvement to become this way and to also moving away from the Objective-C and Next Step era.  This is not a bad thing either.

If you look on this proposal there are some guidelines that were setup that that helped Apple make the decision on whether the Foundation type was to keep the NS prefix from the Objective-C era or if it would be dropped in favor of the Swift era type name.   Below are the 3 rules that Apple setup:

  1. If the class is specifically for Objective-C, or inherently tied to the Objective-C runtime and NS namespace, keep NSprefix. Examples: NSObjectNSAutoreleasePoolNSExceptionNSProxy.
  2. If the class is platform-specific, keep the NS prefix. Many of these types are located in Foundation, but actually belong to the namespace of a higher-level framework like AppKit or UIKit. The higher level frameworks are keeping their prefixes, so these types should match. Examples: NSUserNotificationNSBackgroundActivity,NSXPCConnection.
  3. If the class has a value-type equivalent, then keep the NS prefix, per SE-0069. Examples: NSArrayNSString,NSPersonNameComponents.

Along with the rules above there is a complete type conversion table setup on this proposal to allow your to see the Foundation type from the Objective-C era and the new type name in Swift.  Here is a link to that table.

 

Default classes to be non-subclassable publicly  SE-0117

Authors: Javier Soto, John McCall.

This proposal is a very very interesting.  The intention of this proposal is to give more flexibility around how public access control works and how the rest of your program interacts with it.  Currently, if you mark a class public it can be used by other parts of your program and it can also be subclassed.  This proposal intends to change the way the public access modifier works by allowing access outside of your module or to other parts of you program, but not to allowing other parts of your program to override or subclass the item that you marked public.  If you wish to exposed a class or method to the rest of your program to be overridden or subclassed then these items must be marked with the open modifier.  Thus, separating how the public access modifier works.

Another interesting point brought up under the motivation for this proposal is the performance gains that can come with this change.  If I was Apple and I was reading through this proposal I would be looking more at the performance gains brought up in this proposal than the architectural gains for the language.  The authors for this proposal point out that when something is labeled as public the compiler needs to create property dispatch code on each publicly labeled access modifier because each public value needs to be given the chance to be overridden or subclassed.  This proposal eliminates the need to create extra dispatch code because these properties that are not marked open can never be overridden or subclassed.  Think about that for a minute.  To me, this is a lot more motivation to implement this change than the architectural problem of not allowing classes and methods to be subclassed and overridden.  This seems like it could be a pretty significant performance boost for the language.

Below is an example of how the new open access modifier will work when you declare classes, methods, and properties.

/// ModuleA:
 
/// This class is not subclassable by default.
public class NonSubclassableParentClass {
    /// This method is not overridable.
    public func foo() {}
 
    /// This raises a compilation error: a method can't be marked `open`
    /// if the class it belongs to can't be subclassed.
    public open func bar() {}
 
    /// The behavior of `final` methods remains unchanged.
    public final func baz() {}
}
 
public open class SubclassableParentClass {
    /// This property is not overridable.
    public var size : Int
 
    /// This method is not overridable.
    public func foo() {}
 
    /// Overridable methods in an `open` class must be explicitly
    /// marked as `open`.
    public open func bar() {}
 
    /// The behavior of a `final` method remains unchanged.
    public final func baz() {}
}
 
/// The behavior of `final` classes remains unchanged.
public final class FinalClass { }
 
 
 
/// ModuleB:
 
import ModuleA
 
/// This raises a compilation error: `NonSubclassableParentClass` is
/// not `open`, so it is not subclassable outside of `ModuleA`.
class SubclassA : NonSubclassableParentClass { }
 
/// This is allowed since `OpenParentClass` is `open`.
class SubclassB : SubclassableParentClass {
    /// This raises a compilation error: `SubclassableParentClass.foo` is not
    /// `open`, so it is not overridable outside of `ModuleA`.
    override func foo() { }
 
    /// This is allowed since `SubclassableParentClass.bar` is `open`.
    override func bar() { }
}

 

Reconfiguring sizeof and related functions into a unified MemoryLayout struct  SE-0101

Authors:  Erica Sadun, Dave Abrahams

This proposal aims to remove free-standing value-style functions that exist alone, just as they do in C, and combine them into one unified struct.  One of the motivations for this proposal that was pointed out is that these functions do not correspond to anything named sizeof in LLVM and that these functions increase the surface area and complexity of the project while also providing unsafe functionality.  No specific details were given as to how these functions are unsafe, but I can imagine that the authors meant these functions are unsafe because they allow the direct calculation of an instance variable at a specific point and time in the program without taking into account the mutative nature of variable. 

This is a very interesting proposal to me because this proposal further separates the language away from any C based origins that Swift may still have.  For me, sizeof has always be a really really important function to let any C based program know how much memory needs to be mallocated when asking for dynamic memory.  While my opinion is that this further seperates the language from C, it sort of falls right in-line with how the rest of the proposals have been heading.  For example, removing c-style loops, and increment and decrement operators.  As of writing this post this proposal is still in review, but it will be interesting to see what the proposal review team comes back with and what the final decision is on this proposal by Apple.

Below is the MemoryLayout struct that was briefly mentioned in the title of this proposal. This is pretty simple and concise and also unifies the functions together in a nice struct.

/// Accesses the memory layout of `T` through its
/// `size`, `stride`, and `alignment` properties
public struct MemoryLayout<T> {
    /// Returns the contiguous memory footprint of `T`.
    ///
    /// Does not include any dynamically-allocated or "remote" 
    /// storage. In particular, `MemoryLayout<T>.size`, when 
    /// `T` is a class type, is the same regardless of how many 
    /// stored properties `T` has.
     public static var size: Int { return _sizeof(T) }
 
    /// For instances of `T` in an `Array<T>`, returns the number of
    /// bytes from the start of one instance to the start of the
    /// next. This is the same as the number of bytes moved when an
    /// `UnsafePointer<T>` is incremented. `T` may have a lower minimal
    /// alignment that trades runtime performance for space
    /// efficiency. The result is always positive.
    public static var stride: Int { return _strideof(T) }
 
    /// Returns the default memory alignment of `T`.
    public static var alignment: Int { return _alignof(T) }
}
 
 
// Types
MemoryLayout<Int>.size // 8
MemoryLayout<Int>.stride // 8
MemoryLayout<Int>.alignment // 8

 

Implementation of Binary Search Functions  SE-0074

Authors:  Lorenzo Racca, Jeff Hajewski, Nate Cook

I love this proposal.  This proposal is not a relevant proposal to July, and was rejected back in May, but I am adding it here now because I have just seen it for the first time and I simply love the motivation behind this proposal.  This proposal is asking that binary search functions be added to the Swift language by adding three new methods called partitionedIndex(where:), sortedIndex(of:), and sortedRange(of:).  Currently, the time complexity of using the existing function Sequence.contains(_:) is a linear search and has to perform a search that is represented as O(n).  Adding in binary search methods could potentially cut down this time complexity to O(log n).  This is a large improvement when you are talking about arrays with over 100k plus indices!

While I understand Apple's feedback that this proposal ultimately would add too much complexity to the API, I really wish this proposal would have been accepted.  I think this is an extremely interesting proposal and most likely this functionality will be created anyways outside the language.  On a side note, if any of the authors of this proposal read this post and would like help developing this functionality as a module or framework, please contact me, I would be more than happy to lend my time and effort towards developing this functionality!

 

That was all of the interesting proposal's that I seen for the month of July.  Please send in your comments or feedback if you agree, disagree, or just have something in-general to say!  Thanks!

Member for

3 years 9 months
Matt Eaton

Long time mobile team lead with a love for network engineering, security, IoT, oss, writing, wireless, and mobile.  Avid runner and determined health nut living in the greater Chicagoland area.