Few comments on Swift Programming Language (part V)
This is final part of my wee notes on new programming language from Apple called Swift.
Optional chaining is a process for querying and calling properties, methods, and subscripts on an optional that might currently be nil. If the optional contains a value, the property, method, or subscript call succeeds; if the optional is nil, the property, method, or subscript call returns nil. Multiple queries can be chained together, and the entire chain fails gracefully if any link in the chain is nil.
I have seen in passing similar feature in Oxygene language. This is convenience feature and as such should be praised but in reality isn't it encouraging to Law of Demeter violating? I can see it being helpful while navigating data structures of some API when doing something quickly in a script or when writing not so good UI code and trying to display some deeply hidden value from data structure but nothing beyond that comes to my mind (I might be missing something though).
let roomCount = john.residence?.numberOfRooms
On the syntax level optional chaining feature feels cheap - you only need to add ? before .. But if you write unit tests, you still need to test this. Thus it's better to write this alternatively so there is less to test. And this code is a violation of rule ('law') mentioned above anyway. Having said that this can be a nice tool when dealing with deeply data-structured external API as stated above and just shouldn't be overused.
Another possible problem with optional chaining I can think of is when you have chain looking like variable.foo?.bar?.field and you are expecting that bar can be nil but foo rather shouldn't be nil but since you are using optional chaining you want to use it here as well - nil is accepted result anyway. Then few months later something changes and foo is nil not as an exception but as a normal business situation which needs to be handled separately. Then you have a problem because when foo is nil the effect will be the same as when bar was nil so you will not get any exception and everything will look okay at a first glance... Obviously this is not be a problem when doing TDD.
if john.residence?.printNumberOfRooms() {
Will control flow enter if body when printNumberOfRooms function will return false? Yes, because all what is required to satisfy this if condition is residence to be assigned. Feels like magic trick although it's in sync with language rules. Still, no magic tricks in language is less bug provoking.
init(name: String, director: String) { self.director = director super.init(name: name) }
It's nice to see you again, the ability to set order of superclass constructor execution (like in Delphi) instead of always executing it before derived class constructor (like in C# and Java). Yes, it can be dangerous but it can be also sometimes useful and the choice simply should be given.
let library = [ Movie(name: "Casablanca", director: "Michael Curtiz"), Song(name: "Blue Suede Shoes", artist: "Elvis Presley") ] // the type of "library" is inferred to be MediaItem[]
Wow, type inferring for collections! Even TypeScript, whose type inferring is very robust, doesn't do it!
if let movie = item as? Movie {
Right, in this example the if let variable = <optional> form impresses with brevity. Note that as? works like as in other languages (safe cast).
An extension can extend an existing type to make it adopt one or more protocols. Where this is the case, the protocol names are written in exactly the same way as for a class or structure:
extension SomeType: SomeProtocol, AnotherProtocol { // implementation of protocol requirements goes here }
This is interesting. Generally extensions in Swift look like a similar idea to extension methods in C# but they can do more things than just attaching methods to type. Some of those things (e.g. 'Provide new initializers', 'Define and use new nested types') are not much helpful as extensions in OO programming so I'll not talk about them. But ability of making an existing type to conform to a protocol (I understand it as making implicit Adapter) sounds very nice and can simplify Adapter writing and using.
The only gotcha is the name itself. People use term 'extension' in C# for example for: extension method, subclass, partial class. Naming language feature just 'extension' doesn't help. But Objective-C name for similar concept ('category') wasn't intuitive neither.
If a class has a superclass, list the superclass name before any protocols it adopts, followed by a comma:
class SomeClass: SomeSuperclass, FirstProtocol, AnotherProtocol {
Syntax is exactly like C#. The only obvious difference: protocol in Swift is what interface is in many other languages. And it seems that Swift is free from 'begin interface name with I' convention.
A protocol can require any conforming type to provide an instance property or type property with a particular name and type.
Speaking of experience of person who did it wrong: in good OO programming you are doing something wrong if you need property on interface. You only should have methods there.
protocol Togglable { mutating func toggle()
In theory it's useful that mutating keyword can be used in interface because it's important information for the caller. However mutating only applies to structures (cannot be used in classes).
I cannot see why one would write interface for structure other than maybe using structure instead of class for it's memory specifics (though that would be misleading perhaps unless used coherently)? I'm just speculating here. Personally I've never written interface for structure although it's possible in C# too and I always use structures only for data structures purpose so I don't need to interface them.
protocol DiceGameDelegate { func gameDidStart(game: DiceGame)
Oh, the Java way. No direct support for events in Swift.
func wishHappyBirthday(celebrator: protocol<Named, Aged>) { println("Happy birthday \(celebrator.name) - you're \(celebrator.age)!") }
Protocol composition (<Named, Aged> in example above) is like telling that instance should implement both (or more) interfaces. In languages without this feature (such as C#, Java) this is often done by making new interface which inherits from two (or more) interfaces. But interface multiplying isn't a good thing. On the contrary - reusable interfaces specific to single task type are good. Thus protocol composition seems like a very good feature in Swift because it promotes usage of well cut interfaces. The only gotcha is that if class implements two interfaces then almost by definition it has too much responsibility.
In order to use as or is operators on the left hand side of protocol you need to use special attribute (@objc) on protocol definition. That's like enabling RTTI for only one type so it is probably optimal but still odd compared to some mainstream languages.
@objc protocol CounterDataSource { @optional func incrementForCount(count: Int) -> Int
The @optional attribute of interface method means that class implementing interface doesn't have to implement this particular method. This is interesting because sometimes when class doesn't implement a method, a dummy method which throws exception is written. This violates Liskov substitution principle. Using @optional instead wouldn't violate it. At least in my opinion. The other matter is whenever interface is well designed if some of its methods is optional in the first place.
if let amount = dataSource?.incrementForCount?(count) { count += amount } else if let amount = dataSource?.fixedIncrement? { count += amount }
In this example the incrementForCount and fixedIncrement are both optional methods. If dataSource is our dependency, shouldn't it do what we ask it for according to our preferences instead of forcing us to query it for implemented methods?
protocol Container { typealias ItemType mutating func append(item: ItemType)
Type alias (typealias ItemType above) is a way of making interfaces generic in Swift. It's disappointing that usual generics syntax (type parameters after name) that works for classes, structures and functions cannot be used for interfaces in Swift.
One interesting rare thing which Swift does is that you don't have to specify concrete (or generic) replacement for type alias in implementation as long as Swift can infer it. Most likely Swift designers thought that this is good reason to move type parameters away from interface name.
func allItemsMatch< C1: Container, C2: Container where C1.ItemType == C2.ItemType, C1.ItemType: Equatable> (someContainer: C1, anotherContainer: C2) -> Bool {
Use of type aliases instead of type parameters implies also different way of specifying constrains on them as can be seen above. The same effect could be achieved in other languages the usual way by declaring three type parameters (two for containers and one for item).
The above code defines operator +++ which can be then overloaded by any types as required. This is not only operator overloading but also defining completely custom operators as long as they consist of / = - + * % < > ! & | ^ . ~ characters. Not something we find in C# or Java. Rare feature but do we have real good use for it? Badly used operator overloading can obviously be very misleading. Maybe rightful introduction of new operators will not be that bad as long as they differ visually enough from existing operators and are used consistently in project.
Thanks for reading. Head over here to read the previous comments on Swift.