Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Filburt Shellbach
Nov 6, 2007

Apni tackat say tujay aaj mitta juu gaa!
Haven't finished reading the book yet... is there a way to inspect the type of a variable or constant in the playground? like ghc's :t

Adbot
ADBOT LOVES YOU

Filburt Shellbach
Nov 6, 2007

Apni tackat say tujay aaj mitta juu gaa!

Meat Street posted:

Kind of a hack, but if you have the value as a variable and start typing its name, the autocomplete indicates its type.

Thanks, this worked well enough that I figured out where my problem was.

If you do a range subscript on an Array, you don't get an Array back. You get a Slice. They're not freely interchangeable. So if you want an Array, convert it with Array(names[0..5])

Filburt Shellbach
Nov 6, 2007

Apni tackat say tujay aaj mitta juu gaa!
Are there any documentation playgrounds in the shipping Xcode beta? I couldn't find the NSDateFormatter one mentioned in SotU.

Filburt Shellbach
Nov 6, 2007

Apni tackat say tujay aaj mitta juu gaa!
Yep, though I think it was mentioned in the book that String[] is the preferred style.

Filburt Shellbach
Nov 6, 2007

Apni tackat say tujay aaj mitta juu gaa!
In addition to a metaobject protocol I wish that Swift offered traits (aka roles) as well. On the surface they're like protocols that can provide default implementations of some of its methods (usually building on other methods that the trait requires). At a deeper level they become a very attractive way to decompose your problems into fundamental building blocks.

Here's a motivating example of where I would have used roles in Objective-C, if I had them.

I'm writing a 2D tile-based game. I have an Action base class with dozens and dozens of subclasses. Many, but not all, Actions have an Actor. So I have a generic ActionWithActor subclass that provides an actor property and related methods, etc. Many, but not all, Actions have a Direction. So I have an ActionWithDirection subclass that provides a direction property and related methods, etc. (You can imagine that I have other reusable components like Origin, Target, Magic, Instant, etc)

Some actions have both an Actor and a Direction. Now what do I do? No way I want to go anywhere near multiple inheritance. At best I can subclass ActionWithActor and reimplement the direction parts. That works well enough except the compiler can get grumpy about those direction-based methods.



Of course, I'd face the same exact problems if I were to subclass ActionWithDirection and reimplement the actor parts.

The alternative, more Cocoa-ish way might be to use protocols for ActorAction and DirectionAction. That would be enough to satisfy the compiler that my types are well-formed, but now I'm back to square one for code reuse. Every single one of these Action subclasses need to reimplement these actor- and direction-related properties and methods. At that point the protocols are really only there to satisfy the compiler. They don't work for me.

Traits offer a robust, solution to these problems without compromising type safety. We use them in the Perl/Moose world extensively and it's one of the two things (along with the MOP) that make modern Perl even remotely usable.

rjmccall: Would you like me to continue? Or has your team already evaluated and rejected traits as a feature for Swift? Or are protocols that much beefier than Objective-C's that I've already got what I want? If this is new to you I'm more than happy to start filing radars loaded with citations both for their theoretical and practical value!

Filburt Shellbach fucked around with this message at 22:49 on Jun 4, 2014

Filburt Shellbach
Nov 6, 2007

Apni tackat say tujay aaj mitta juu gaa!

rjmccall posted:

I think that what you're doing in your wall o' text can be reasonably modeled with just default implementations in protocols, which is something we want to do.

Excellent. That would indeed be enough for me. Default implementations get you the most useful 80% of traits.

The other 20% of the traits paper is still useful, if you want more ideas on how to take protocols further, or for insight into the new problems that might arise when you have protocols providing implementations.

For example, what if a class consumes two protocols which provide different implementations of a method with the same signature? (It's not that outlandish to think, say, position could have more than one meaning). Traits offer a solution: that situation becomes a compile-time error that is resolved by adjusting the class consuming the composite trait. The class can either exclude the method from one of the traits (so the other is included as normal), or offer its own implementation of that method, which can call the two conflicting trait methods as it wishes. Which is as simple as calling the fully-qualified method names of each trait, which is familiar in Swift.

The traits design came from a team working in Smalltalk, and they have a case study in refactoring the Smalltalk collection class hierarchy to use traits. tl;dr, it went extremely well.

quote:

The traits that we have written will also allow us to construct new kinds of collection in the future, simply by composing the necessary traits and implementing a few glue methods. For example, we can build a class PluggableBag by using the trait TPluggableAdaptor in a subclass of Bag, and we can create immutable variants of collections by omitting the mutable interface traits. In addition, the availability of these traits frees the implementors of the collections framework from the need to ship pre-built collection classes for rarely used special cases.

There are a couple other features that are useful when you have all the other pieces. before/after/around method hooks (a generalization of willSet and didSet that can fire off any method - see CLOS) amplify the power of what traits can do (and are convenient for subclasses too). Applying traits at runtime to create one-off subclasses of existing classes, usually for an individual object, is useful for debugging or constructing classes a la carte. Going perhaps a bit too far, there are also parameterized roles which generate traits at runtime.

If you have all three of these pieces, you could write, say, a reasonable approximation of KVO, in userspace, as a single, well-defined module. Here's a rough sketch:

code:
protocol KVO(properties: String[]) { // this protocol takes an array of properties to observe
    // conceptually, the body of the protocol is executed for each class that consumes the protocol
    // so we can loop over the parameters and generate hooks for each one
    // it's not *that* different from Swift's enum with associated values

    for property in properties {
        // generate before and after hook methods for each property in the array
        // these methods names of course can't be hardcoded,
        // since each consumer of the protocol chooses its own properties

        before "set\(property)" { publish("will-set-\(property)") }
        after "set\(property)" { publish("did-set-\(property)") }
    }
}


// this creates a one-off subclass of myView
// wraps the setBounds and setCenter methods with before- and after-hooks
// then changes the class of myView to that subclass
myView.meta.applyProtocol(KVO(["bounds", "center"]))
// note that this is happening at runtime


// could also inspect all objects that are, or descend from, a particular class
UIView.meta.apply(KVO["bounds", "center"]))


// this instance of the KVO protocol observes these different properties instead
myModel.meta.applyProtocol(KVO(["firstName", "lastName", "email"])
I'm pretty enthusiastic about traits because experience shows again and again they're a natural fit for so many problems.

*mic drop*

Filburt Shellbach fucked around with this message at 03:23 on Jun 5, 2014

Filburt Shellbach
Nov 6, 2007

Apni tackat say tujay aaj mitta juu gaa!
The Advanced talk was great. I'm glad the syntax mungling examples were tempered by words of caution.

Generics are fantastic. Can't believe the code you guys had on screen for the memoization example. There's a whole class of young programmers who are going to be introduced to FP through Swift.

Adbot
ADBOT LOVES YOU

Filburt Shellbach
Nov 6, 2007

Apni tackat say tujay aaj mitta juu gaa!
Mike Ash wrote up an in-depth article recently about the tricks dispatch_once uses.

  • Locked thread