mikeash.com: just this guy, you know?

Posted at 2014-06-20 13:17 | RSS feed (Full text feed) | Blog Index
Next article: Friday Q&A 2014-07-04: Secrets of Swift's Speed
Previous article: Friday Q&A 2014-06-06: Secrets of dispatch_once
Tags: fridayqna swift
Friday Q&A 2014-06-20: Interesting Swift Features
by Mike Ash  

Roughly six hundred million people have asked me to write something about Swift. I'm hoping to write a series of articles about various aspects of it. For today, I want to start things off by exploring a few Swift features that are interesting and unusual from the perspective of Objective-C, and why I think they're going to be good to have.

Explicit Optionals
Swift makes optional values a first-class language construct, and requires that any optional type be explicitly marked as such. For example:

    var a: Int
    var b: Int?

Here, a is a plain Int and it always contains some integer value. b is an optional Int and it either contains an integer value, or it contains nothing.

That example is not so special, but it gets more interesting with other types:

    var c: String
    var d: String?

Just like above, c is a plain String and it always contains some string value. d is an optional String and it can either contain a string value or it can contain nothing.

Let's look at the equivalent Objective-C declarations:

    int e;
    NSString *f;

Here, e is a plain int, and it always contains some integer value. f is an NSString *, which means it can either contain a pointer to an NSString, or it can contain nil, which generally means "nothing".

Note how e is a non-optional type, while f is effectively optional. The existence of NULL in C (which is the same as nil in Objective-C) means that all pointer types in the language are implicitly optional types. If you have a NSString *, it means "pointer to NSString, or nil". If you have a char *, it means "pointer to char, or NULL".

The existence of NULL in C blows apart the entire static type system when it comes to pointers. Every pointer type is a half truth. Whenever you see a type "pointer to X", there's always an implied "...or NULL."

NULL behaves totally differently. You can dereference a pointer, but you can't dereference NULL. You can send it messages in Objective-C, but the return value is always 0, even when that makes no sense:

    [nil isEqual: nil] // returns NO!

Log a nil string, and you get (null). [nil arrayByAppendingArray: obj] does not produce a one-element array containing obj, but rather nil. Everything has two different behaviors: the regular one, and the nil or NULL one.

This is a major problem because our code doesn't behave that way. Sometimes we write our code for "pointer to X or NULL," but sometimes we just write it for "pointer to X." But there is no way to express this latter type in the language.

To illustrate the problem this poses, consider the following two questions:

  1. Is nil a legal argument to pass to isEqual:?
  2. is nil a legal argument to pass to isEqualToString:?

I'll give you a moment while you check the documentation.

The answer to the first question is "yes". The docs say: "May be nil, in which case this method returns NO."

The answer to the second question is... no? Maybe? The docs don't say. It's generally best to assume that if nil isn't explicitly allowed, then it's not legal.

Method parameters can sometimes be nil, and sometimes not. Return values are the same way. Some methods never return nil, and some do. If a method returns nil and you pass the return value to a method that doesn't accept nil, trouble ensues. You have to add checks, and the compiler can't help you with this because, as far as it knows, everything accepts nil. Even if you can keep on top of everything, the documentation often glosses over the handling of nil.

Here's another illustrative question: is this code legal?

    free(NULL);

In my experience, about 99% of C and Objective-C programmers will say "no". Checks like these are extremely common:

    if(ptr)
        free(ptr);

But if you check the man page, it turns out to be fine. "The free() function deallocates the memory allocation pointed to by ptr. If ptr is a NULL pointer, no operation is performed."

If people frequently get something as simple as this wrong, what hope do we have in more complex situations?

Swift approaches this in a consistent manner by making all types non-optional, and allowing any type to be made optional with an additional annotation.

For types that would be pointers in Objective-C, this solves the inconsistencies caused by nil and NULL. If a parameter can accept nil, then it will be declared as an optional type. If it can't, it won't. The compiler can easily check your code to make sure it's doing the right thing. Likewise, if a return value can be nil, it will be an optional type, making it obvious. In the common case, your types will be non-optional, making it clear that they always hold something.

Because any type can be made optional, it solves some other problems as well. A lot of methods in the frameworks return special sentinel values to indicate the absence of a return value. For example, indexOfObject: returns NSNotFound, which is just an alias for NSIntegerMax. It's easy to forget about this:

    NSUInteger index = [array indexOfObject: obj];
    [array removeObjectAtIndex: index]; // oops

The equivalent in Swift would return an optional type:

    func indexOfObject(obj: T) -> Int?

Not finding the object would be indicated by not returning an integer at all, and the fact that optionals are a different type means the compiler can check everything for you.

Multiple Return Values
Swift allows a function to return multiple values. Or if you look at it in a different way, Swift functions always return one value, but that value can be a tuple which is easily unpacked at the call site.

C and Objective-C support this in two ways, neither of which is great. Functions/methods can return a struct or a class containing multiple values, or they can use out parameters. Returning a struct is so unwieldy that it's basically never used except in cases where the struct is conceptually a single unit, like frame returning a NSRect or CGRect. Out parameters get a lot of use in Cocoa, though, especially for error handling.

The NSError class and the corresponding NSError ** pattern showed up late in the 10.2 era and quickly became pervasive. Where some languages would throw an exception, Cocoa indicates errors by returning an NSError * to the caller through a parameter. Code like this is common:

    NSError *error;
    NSData *data = [NSData dataWithContentsOfFile: file options: 0 error: &error];
    if(data == nil) {
        // handle error
    }

This can get annoying, and since the error is always optional, a lot of code ends up looking like this instead:

    NSData *data = [NSData dataWithContentsOfFile: file options: 0 error: NULL];

This is bad, but temptation strikes us all.

Multiple return values present another option besides exceptions and out pointers. In Python with PyObjC, for example, this code would look like:

    data, error = NSData.dataWithContentsOfFile_options_error_(file, 0, None)
    if not data:
        # handle error

It's a bit odd due to the bridging, where you still have to pass None for the out parameter even though it's being translated into a second return value. A native Python call might look like:

    data, error = Data.dataWithContentsOfFile(file, 0)

A Swift version would look almost identical:

    let (data, error) = Data.dataWithContentsOfFile(file, 0)

This is ultimately a small thing, but NSError returns are so common in Cocoa that anything which makes it nicer is welcome. The problem has bothered me enough that I've committed preprocessor crimes against humanity trying to build multiple return values in Objective-C, and I'm glad I don't have to anymore.

(I think a good case could be made that an even better way to handle error returns would be with an either type. In any case, I look forward to exploring the options.)

Generics
This is a huge one. Swift supports generic classes and functions.

This opens up a lot of possibilities. A big one is that container classes can now have a static type which declares, at compile time, what kind of objects they contain. In Objective-C, you lose static type information as soon as objects go into a container:

    NSArray *array = @[ @"a", @"b", @"c" ];

We can deal with this, but it's not the best. For one thing, it completely breaks dot syntax:

    NSLog(@"%@", array[0].uppercaseString);

This fails to compile because the type of array[0] is id and that doesn't work with dot syntax.

For another, it takes some effort to keep track of what's in the thing. This isn't a big deal for local variables where you set up and use it right away. It can be a bit more of a pain for instance variables, and can be really annoying for parameters and return values. When you fail and get the type wrong, the result is a runtime error.

It gets worse for dictionaries, where there are two types to worry about. I have a lot of instance variables with names like _idStringToHamSandwichMap to help me remember that the keys are NSString instances and the values are HamSandwich instances.

In Swift, the types are not Array and Dictionary, but Array<String> and Dictionary<String, HamSandwich>. When you extract an element from the array, the result is not id (or Any/AnyObject in Swift) but String. It chains nicely too, so if you ask Dictionary<String, HamSandwich> for a list of all of its values, the result is a collection type that knows it contains HamSandwich instances.

Functions can be generic as well. This lets you write functions that operate on any type without losing type information when you go through them. For example, you might write a small helper function in Objective-C to provide a default value for a value when the value is nil:

    id DefaultNil(id first, id fallback) {
        if(first) return first;
        return fallback;
    }

(Let's ignore for a moment the nonstandard ?: operator which provides this exact behavior.)

This works great, but loses type information, so that this doesn't work:

    NSLog(@"%@", DefaultNil(myName, genericName).uppercaseString);

It's possible to make this better by using macros and the nonstandard __typeof__ operator, but it gets frightening fast.

The rough equivalent in Swift would look like:

    func DefaultNil(first: AnyObject?, fallback: AnyObject) -> AnyObject {
        if first { return first! }
        return fallback
    }

Swift's stricter static typing would make this a pain to use, much more so than Objective-C, which loses the type info but basically trusts us when we tell it what it is. However, with generics we can solve the problem easily:

    func DefaultNil<T>(first: T?, fallback: T) -> T {
        if first { return first! }
        return fallback
    }

This preserves the type so that the return value has the same type of the arguments. Type inference means that you don't even have to tell it which type to use, it just knows from looking at the type of the arguments.

Generics are another example of my preprocessor crimes against humanity trying to hack them into Objective-C, and I'm really glad to have them for real.

Type Inference
Static typing is nice, but it can lead to painful redundancy in code:

    NSString *string = @"hello";
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle...];

The compiler knows the type of these expressions, so why do we have to repeat the information every time? With Swift, we don't:

    let string = "hello"
    let alert = UIAlertView(...)

Despite the superficial appearances to languages like JavaScript, don't be fooled: these are statically typed variables, the type just isn't written out as part of the declaration. If there's ever a case where you really want to make sure that a variable is a certain type (and generate a compiler error if the initializer doesn't match), you can still declare it:

    let string: String = ThisMustReturnAString()

Verbosity in programming can be good to an extent, to help readability. But Objective-C and Cocoa can take it to an absurd extreme in many cases, and it will be great to have the option to cut down on that.

Class-like Structs
Like Objective-C, Swift has both classes and structs. Unlike Objective-C, Swift structs can contain methods. Instead of a massive crowd of functions for operating on a struct, a Swift struct can just contain that code as methods. CGRectGetMaxX(rect) could turn into rect.maxX.

The language also provides a default initializer method if you don't provide one, which saves you the trouble of writing any code for that purpose, and gets rid of ugly functions like CGRectMake.

Furthermore, structs are better integrated into the language. In Objective-C, there's an ugly divide between them. The declaration syntax is different, you can't use them with Cocoa collections without boxing them, and with ARC it becomes extremely inconvenient to have Objective-C objects as struct members.

In Swift, the declaration syntax is the same. Because the collections use generic types, they have no problem containing structs. Object members work without difficulty. They basically become pass-by-value objects rather than a totally different entity.

The result is that small model classes become a lot nicer in Swift. How many times have you used an NSMutableDictionary with a few fixed keys to represent a bag of related data that really should have been a class? If you're like me, the answer is "too many". That's because making a simple Objective-C class is a bit of a pain. This was especially true pre-ARC, but even with ARC it's annoying to make it nice. You can just toss properties into a class and call it a day, of course:

    @interface Person : NSObject
    @property (copy) NSString *name;
    @property NSUInteger age;
    @property (copy) NSString *phoneNumber;
    @end
    @implementation Person
    @end

But now it's mutable, so you have to hope nobody decides to start changing them. And there's no initializer, so you have to set up instances over several lines of code and hope you didn't forget any. If you want a nice immutable model class, you have to manually write out an initializer and keep it in sync with the properties.

With Swift, it's easy:

    struct Person {
        let name: String
        let age: Int
        let phoneNumber: String
    }

This automatically produces an initializer and instances are all immutable. As a bonus, it should be more efficient as well, since structs can potentially be allocated inline rather than requiring allocation on the heap.

Trailing Closures
This is a nifty feature that's simultaneously pointless and really nice.

When the last parameter of a function or method is a closure (i.e. a block), Swift allows you to write the block after the call, outside the parentheses. These two calls are equivalent:

    dispatch_async(queue, {
        println("dispatch!")
    })

    dispatch_async(queue) {
        println("dispatch!")
    }

If the closure is the only parameter, then you don't even need the parentheses:

    func MainThread(block: Void -> Void) {
        dispatch_async(dispatch_get_main_queue(), block)
    }

    MainThread {
        println("hello from the main thread")
    }

This is interesting because it knocks down a visual barrier separating language constructs from library calls. As I discussed way back in 2008, blocks are a great addition to Objective-C because they allow you to write your own control constructs. This showed up in a huge way with GCD, which could provide a ton of useful asynchronous calls that worked a lot like language constructs, but were implemented as library calls. However, with Objective-C, there's still a syntactic difference in how you write calls with blocks compared to how you use built-in language constructs.

For example, Swift (currently, at least) lacks anything like Objective-C's @synchronized statement. Trailing closures mean that you could implement your own and make it look exactly the way it would look if it were built in:

    synchronized(object) {
        ...
    }

If you were doing this in Objective-C, the parentheses couldn't go in the right place and you'd end up with something a little more awkward:

    synchronized(object, ^{
        ...
    });

This is ultimately a really small thing, because this still works just fine and isn't difficult to read at all. But at the same time, it's great to be able to arrange the code in a more natural way.

Operator Overloading
I imagine this one will be controversial. Unfortunately, there's a huge group of programmers who have been scarred for life by being exposed to C++'s terrible and terrifying operator overloading culture. When the language designer thinks it's a fine idea to overload the << and >> bitshifting operators for IO, then you know you're in real trouble. I can't blame people for being scared away.

However, I think that if you look beyond C++, the situation is much better. Operator overloading exists in a lot of other languages and doesn't see the kind of crazy abuse that's so common in C++.

Operator overloading is terrible when people use it just so they can have arbitrary symbols instead of words. It's great when people use it so that the traditional operators can be used for their traditional purposes on new types.

Take a simple Objective-C example:

    NSNumber *count = ...;
    count = @([count intValue] + 1);

You might write code like this if count is being stored in a dictionary or an array somewhere. Dealing with boxing/unboxing just to increment the number is a real pain. It's also somewhat dangerous, since the NSNumber value could potentially be beyond what could be stored in an int. You could write a method to handle that, but it's still not great:

    count = [count add: @(1)];

With operator overloading, you can implement +, +=, and ++ to do the same thing they would do with a regular int. The code would then become:

    NSNumber *count = ...;
    count++;

Of course, generics in Swift mean that NSNumber itself is much less commonly needed, but there are many other potential good uses for operator overloading. A big (pun intended) one would be a bignum type. Swift has no built-in type for integers of arbitrary size, but you could implement one yourself that handles all the standard arithmetic operators.

One really interesting example is creating autolayout constraints, as demonstrated by SwiftAutoLayout. This uses operator overloading to turn expressions like view1.al_left() == view2.al_right() * 2.0 + 10.0 into NSLayoutConstraint instances. This is way better than Apple's cool but crazy visual format language.

In addition to overloading existing operators, Swift allows you to define entirely new operators from a limited character set. If you really want to, you can create an operator called <~^~> and make it do what you want. It will be interesting to see what people do with this, and we'll all have to be really careful not to let this power go to our heads.

Conclusion
Swift is an interesting new language that I'm looking forward to using for real work. It has a lot of features that may seem foreign to someone coming from Objective-C, but I think they ultimately make a lot of sense and will be nice to use.

That's it for today. Come back next time for more goodies. I plan to continue talking about Swift for a while, but topic suggestions are always welcome. If you have something about Swift you'd like to see, great! If it's about something else, I can keep it on file for an appropriate time. Either way, if you have a topic you'd like to see covered, please send it in!

Did you enjoy this article? I'm selling whole books full of them! Volumes II and III are now out! They're available as ePub, PDF, print, and on iBooks and Kindle. Click here for more information.

Comments:

It turns out that contrary to what the Swift manual says, you can use some Unicode symbols for operator overloads. There is a thread on this in the Swift forums.
I was just thinking that these features (or at least the major, non syntactic-sugary ones) are already available in C++11, including to Objective-C developers.

But, I think it's the Obj-C dev culture that one is supposed to despise C++ and like Obj-C even if as a language it was obsolete 10 years ago, nevermind in 2014.

This shows in the operating overloading section, where a minor point (iostreams using >> and <<) is turned into a tirade against operator overloading in C++ while ignoring the majority of the cases where it is actually used for "traditional purposes".

Still, it's nice that Apple platforms have access to a blessed modern language. It would have been even nicer for them to recommend a standardised, cross-platform language, but as mentioned before, the cognitive dissonance might have been too great for the developer community, and one transition à la PowerPC to Intel is enough for a lifetime.
blubby: A "tirade"? There are two sentences. Defensive much?
Note to commenters: arguments about how stupid the Apple community is for rejecting other languages and then embracing Swift do not belong here, and any such comments will be deleted. Take it to Twitter or your own blog or wherever you guys talk about such fluff.
This is a great article. Would love to see your thoughts on enumerations and pattern matching in Swift.
(I think a good case could be made that an even better way to handle error returns would be with an either type. In any case, I look forward to exploring the options.)

Why not go one step further and mention enum's ability to act as Either:

enum Result {
    case Success
    case Error(NSError)
}
Great article, but the intro to Operator Overloading kinda rubs me the wrong way. The problems you described have been known for decades, and I don't think anyone learning C++ in the last 10 years is making those same kinds of mistakes. I'm pretty sure Bjarne doesn't even think operator << for streams is a good idea anymore, but it's what we're stuck with (so many things could be better about C++ if they weren't so married to backwards-compatibility).

Even so, those particular choices had nothing to do with it being C++ and everything to do with the experience (or lack thereof) of the people making those choices. All of those same mistakes could still be made in Swift.

That said, I absolutely love the fact that you can actually create new operator tokens in Swift.

Here's my attempt to do something similar in C++ (yay macro abuse!) https://github.com/cogwheel/IdOp
Along with austinz, I would love to hear your thoughts more on pattern matching in Swift.
The only thing that bums me out is that, as opposed to structs, classes don't have support for enforcing immutability. I would have loved to see C++'s const-correctness.

If we had that, Swift could also almost be described as C++ without the C.
Cowheel: Regardless of who thinks it's a good idea anymore, as far as I know it remains pervasive. As for not having to do with C++, that's exactly my point: it's not the ability that's bad, it's how you use it (or don't). C++ got off on the wrong foot in a serious way and has never really recovered.

Peter: I'm not sure I understand what you're after, exactly. Can't you enforce immutability by simply using let with all your ivars (or whatever we're calling them in Swift)? Or are you talking about being able to use the same class for as both mutable and immutable?
I guess it depends on what you mean by "it remains pervasive" or "so common in C++". I know C++ is a slow-moving behemoth, but things do change over time.

The "OVERLOAD ALL THE THINGS!!" attitude programmers had early on in C++ no longer remains pervasive. Bad uses of operator overloading are only "so common in C++" in the sense that the C++ language and old (but still heavily used) libraries enshrined them long ago. It's not newly overloaded operators that are the problem, it's the fact that people still use old code (again, back to the backwards compatibility issue).

I really don't think it's fair to assert that the C++ community is still somehow in conflict over this. Yes, there are people who are scarred for life, but life has moved on since then.

Sorry for obsessing on this, but it really bothers me to see questionable generalizations trotted out as self-evident truths. I'll leave it alone now :)
Aren't << and >> still used all over the place for IO in C++? That's enough for "pervasive" and "common" for me.
A nice example of function with trailing closure as statement is autoreleasepool(code: () -> ()), which is Swift’s ObjectiveC module equivalent to Objective-C’s @autoreleasepool:

autoreleasepool {
    // code
}
Coming from Ruby, the bit shift operator is used extensively for adding something to the end of something, and is often referred to as the shovel operator. I had no idea this was considered pathological, I wonder if Rubyists who use Swift will accidentally introduce it as a pattern/anti-pattern.
Thanks for the most sensible explanation of Swift I've found so far. As an Obj-C guy a lot of stuff was pretty baffling to me, but now things like the optionals and generics make more sense. I've been working my way through the Swift book and some simple test projects and this post really helps.

I do have one nitpick though. (This is the internet after all.) Your example of how a lack of generics can break dot syntax in Obj-C doesn't really work as - uppercaseString is a instance method on NSString and not a synthesized property or accessor method.
bavarious: Awesome, I didn't realize autoreleasepool was already in there. I was thinking I'd have to build it.

Jake Smith: Interesting! In C++, the two complaints (at least for me) are that the operators already had a long history doing something unrelated, and they have the wrong precedence for IO, meaning that code like cout << x & y needs unfortunate parentheses. Perhaps that's not the case in Ruby? Or, again, a different language culture.
Apparently you can implement synchronized as above like this:
func synchronized(object: AnyObject, closure: () -> ()) {
    objc_sync_enter(object)
    closure()
    objc_sync_exit(object)
}

Looking forward to posts about the Swift implementation details, Mike! Thanks.
All these features allow the language to be pretty lightweight and rely on libraries to do the heavy lifting, which affords a lot of flexibility and utility (for better or worse).. On one end of that spectrum, trailing closures allow for new control flow "keywords" like Perl's unless:

func unless<T: LogicValue>(test: T, clause: () -> ()) {
    if (!test) { clause() }
}

unless (false) {
    println("success!")
}

Mike, great article as usual.

You mentioned the Python with PyObjC code for multiple returns looks like:

    data, error = NSData.dataWithContentsOfFile_options_error_(file, 0, None)
    if not data:
        # handle error

with the native Python version looking like:

    data, error = Data.dataWithContentsOfFile(file, 0)

I'd expect the Python version to be:

  try:
    data = Data.dataWithContentsOfFile(file, 0)
  except IOError as error:
    # Handle the error

Python took the C++/Java path of class-based exceptions, and Objective-C took the C path of error codes and string errors. It looks like that will be continued with Swift, unless the libraries start diverging.

A more Pythonic example of multi-return is the Django ORM function to get an existing item or create a new one:

   obj, was_created = Blog.objects.get_or_create(title='Arguing about Error Handling')

This can trip up developers, who first write it as:

   obj = Blog.objects.get_or_create(title='Arguing about Error Handling')
   # obj is now a tuple (Blog object, boolean)

Does the Swift compiler force you to unpack multiple return items?
Operator overloading will be convenient for some of my model objects. However, I'm not looking forward to homegrown regex literals and other stuff we'll see all over Github.
John Whitlock: Good point on the more natural Python version. I think I just meant that if you wrote the multiple return style in Python, you'd leave out the ugly underscores and redundant None parameter and such. But yes, it's still not entirely natural. And no, Swift does not force you to unpack multiple return items. You'll get the exact same thing in Swift as you do in Python with your example, with the slight improvement that it should be caught at compile time and the error message might (might) help you realize what's gone wrong.

Preston: I don't doubt we'll see plenty of abuse in random third party libraries, but I'm hoping it won't become common in the popular ones, and that it will generally be understood as something to avoid. Think of macro abuse and such in Objective-C now: people do it, sometimes because it's needed, sometimes for no good reason, but it's generally understood as something to avoid if you can.
Last suggestion: I think it would be great to see a discussion of @lazy and @auto-closure, especially because there are some interesting call-by-name semantics you can implement using the latter (if I'm understanding those two annotations correctly).
<I>(Let's ignore for a moment the nonstandard ?: operator which provides this exact behavior.)<I>

Did you mean nonstandard here? The ternary operator has been a standard part of C for as long as I remember. It's even in the 2nd edition of the K&R book.
I'm not actually referring to the ternary operator there, but rather to a binary operator that's defined as x ?: y being the same as x ? x : y except that x is only evaluated once.
As far as Ruby goes << works well because bit shifting is extremely rare and adding to the end is extremely common.

In Ruby "<<" always means add to the end unless contextually it looks like numbers are being bit shifted.

Also in Ruby "<<" isn't an operator, it's just a method that quite a few classes implement.
I'd love to hear your thoughts on the mutability of arrays and dictionaries, specifically how you cannot change the length of a constant array, but you can swap out individual objects.

Documentation says that this is for performance reasons, but there's already some overhead inherent in a Swift array, I don't see how putting restrictions on setting elements would cause significant additional overhead.
Array/dictionary mutability in general seems sensible. It was initially weird to me that it's tied to let and var, but that made sense once I understood that they were structs and what that entailed.

The business where constant arrays still have mutable elements is crazy. Fortunately, I'm pretty sure I heard somewhere that this will be changed.
I can confirm that array semantics are going to change significantly in later seeds, to be more similar to dictionary and strings.
There's a big problem with using trailing closures to implement unless() or synchronized() or the like, as if they were syntax in the langauge.

While you can access most things from the surrounding lexical environment inside the closure, you can't access loop or labeled loops to use "break" or "continue". In the closure body you are not in a loop.

There is another gotcha from using the same syntax for syntax as for closures. Unlike in C/C++/ObjC you can't just casually write a set of braces to delimit a scope for a temporary variable, or just to make code clearer:


let t = ...
...
foo()
...
{
  let x = t + 10
  if x < 100 {
     ...
  }
}


If you do this in Swift you get something like "closure not used".

But if you do something like...


do {
  let x = t + 10
  if x < 100 {
     ...
  }
} while false


.. then it is happy with you. Because *those* { } are just syntax, not a closure.
.@Chris: That's fantastic news. Having truly immutable Swift Arrays will be awesome. Thanks.
@Bruce: you could get around the closure not used problem with

 {
    ...
 }()
macshome: Until Mike Ash completes his articles about Swift, I've written a quick intro for ObjC programmers, including some non-obvious goodies, which should kick-start your Swift skills :-) Please have a look.
Hi, nice article.

I am curious why we can't call Obj-C++ from Swift, is there a technical reason against it?
Will this be added/fixed later on?

(Sure we can write wrappers, but I'd really like to know why it is not supported)
Chris Lattner: I'm really glad to hear that, and it sounds like a lot of other people are too.

Clemens Gruber: There are really two different kinds of "call Obj-C++ from Swift": 1) accessing Objective-C classes, extern "C" functions, constants, etc. that just happen to live within an Objective-C++ file, and 2) accessing C++ classes, functions, templates, etc.

Taking the second one first, the C++ object model is so complex that it's impractical to automatically bridge. Objective-C++ has a ton of dark corner cases because of C++, and this comes from bolting on an extremely simple set of extensions to the language and otherwise leveraging the existing compiler. Getting Swift to deal with it would be a huge task, tantamount to implementing a C++ compiler within the Swift compiler. For a concrete example, consider std::vector, which is implemented entirely in the header file because it's a templated class and templated classes in C++ are often frightening like this. In order to instantiate a std::vector, you have to parse all of its code, specialize it for the type you want it to contain, then turn that all into machine code. Which is to say, you need a C++ compiler. Compare with something like instantiating an NSArray, which exists entirely in a library with a simple interface, so it's just a few calls to objc_msgSend with some obvious parameters. You could skip over anything with header implementations and only allow bridging to C++ classes with prototypes in the headers, but given how common these header-implementations are in C++, you'd severely limit your universe in strange and confusing ways, like not being able to call any function that takes a std::vector or any other STL container.

For the first one, bridging to stuff with C linkage compiled in Objective-C++ files... I actually expect that works now, as long as your headers are compatible with plain Objective-C. Swift shouldn't care about where your implementation lives or how it's built, it'll only care about the headers. It won't be able to deal with C++ constructs in the headers, because that opens the whole can of worms above, but as long as you can present a clean Objective-C interface, an Objective-C++ implementation should be fine. If it doesn't work now for some reason, I would expect it to be made to work before too long, as there shouldn't be any fundamental obstacle.
austinz: You can use @auto_closure for a sort of call by name, which I covered here: http://www.russbishop.net/swift-call-by-name


mike: I've been trying to blog some about interop with C (the docs are extremely thin on that), see below. Perhaps an overview of the various CMutableVoidPointer/COpaquePointer/UnsafePointer/etc would be good?

http://www.russbishop.net/swift-manual-retain-release
http://www.russbishop.net/swift-withunsafepointertoelements
http://www.russbishop.net/swift-pointers-everywhere

Russ Bishop: Nice posts. If I may make a brief off-topic comment, I'd suggest getting rid of the border from your syntax highlighting stylesheet's "err" class, as it's getting annoyed at your @. I ran into the same thing here, once upon a time.
I'm starting to think I have to move platforms; I don't have access to the stylesheets or much else. I originally went with Silvrback because I could get a blog running instantly and my previous experience with Wordpress left me a broken shell of a human being... It's great for being able to just click and start writing, with auto-save, and live previewing of the results but I can't fix the stylesheets, I can't include HTML or any custom markup, etc.

Why do all blog platforms suck?
Russ Bishop: That's why I wrote my own. But it still sucks.
Russ Bishop: WordPress rocks.

Mike thanks for the article, much appreciated. I'm struggling with the concept of... enums with methods. Sounds very, very odd.
Jorge: Enums are indeed odd. I think it's a naming thing more than anything. For those of us coming from C, we should probably think of them as two separate cases. Plain enums which just list a bunch of constants are just like C. Enums with associated values are more like a collection of subclasses, and share nothing in common with C enums except the name. It just happens that Swift lets you do both with the same language construct. It will take some time to get used to the idea of using enum for more than just defining integer constants, and how best to use them.
Rainer Brockerhoff: Thanks for the snippet. This also seems to work for synchronized to return a value and synchronized closures that accept object as input and a return value.

func synchronized<T>(object: AnyObject, closure: () -> T) -> T {
    objc_sync_enter(object)
    let val: T = closure()
    objc_sync_exit(object)
    return val
}

func synchronizedWith<A: AnyObject, T>(object: A, closure: (value: A) -> T) -> T {
    objc_sync_enter(object)
    let val: T = closure(value: object)
    objc_sync_exit(object)
    return val
}
Great post, as always, Mike. I'm curious to hear your thoughts on a thread marshaling operator I invented, if you have a moment.

http://ijoshsmith.com/2014/07/05/custom-threading-operator-in-swift/

Thanks!
Great Post . I think this is one of best post i ever read for swift.

Nicely explain new feature like optional, multi value.

i would like if you share more article about swift.
Just a quick note:
we don't do if(ptr) free(ptr); because we are afraid it might be NULL and break something; Usually AFTER freeing an element you set it to NULL so you don't free it again by mistake later on. The issue is not freeing a NULL pointer but double-freeing a valid one. Objects alleviate this immensely.
Nice Article .
Bolches yarboclos, Batman!

At last I understood this optionals stuff.

Comments RSS feed for this page

Add your thoughts, post a comment:

Spam and off-topic posts will be deleted without notice. Culprits may be publicly humiliated at my sole discretion.

Name:
The Answer to the Ultimate Question of Life, the Universe, and Everything?
Comment:
Formatting: <i> <b> <blockquote> <code>.
NOTE: Due to an increase in spam, URLs are forbidden! Please provide search terms or fragment your URLs so they don't look like URLs.
Code syntax highlighting thanks to Pygments.
Hosted at DigitalOcean.