Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Swift, functional programming, and the future of Objective-C

Swift, functional programming, and the future of Objective-C

I gave this talk at NSMeetup in San Francisco, shortly after the Swift language was announced. It points out the language's many roots in functional programming languages, and considers what this means.

Time has marched onwards. If you want to hear about Swift from an FP perspective, there are now entire books in it!

Presented at NSMeetup in San Francisco on 2014-07-02

Alexis Gallagher

July 02, 2014
Tweet

More Decks by Alexis Gallagher

Other Decks in Technology

Transcript

  1. Swift,
    functional programming,
    & the future of Objective-C
    Alexis Gallagher
    @alexisgallagher
    Part of a talk delivered on 2014-07-02

    View Slide

  2. Ques%ons
    1. What's)new)in)Swi.?
    2. Is)Swi.)a)func5onal)programming)language?
    • And)what)is)"func5onal",)anyway?)Who)cares?
    3. Is)ObjC)going)away?
    • And)so,)is)everything)easier)now?

    View Slide

  3. What's'hardly'new'in'Swi,?

    View Slide

  4. Objective-C
    • classes
    • methods
    • protocols
    • categories
    • functions
    • ARC
    • blocks
    • Cocoa values 

    & collections

    View Slide

  5. Objective-C
    Swift
    • classes
    • methods
    • protocols
    • extensions
    • functions
    • ARC
    • closures
    • Cocoa values 

    & collections

    View Slide

  6. just%syntax,%almost
    ObjC:
    // Foo.h
    @interface Foo : UIView
    @property (nonatomic,weak) UIView * myView
    @end
    @implementation Foo
    - (CGFloat) addAtX:(CGFloat) x andY:(CGFloat) y {
    UIView * v = [[UIView alloc] initWithFrame:CGRectMake(x,y,10,10)];
    [self addSubview:v];
    self.myView = v;
    return x + y;
    }
    @end

    View Slide

  7. just%syntax,%almost
    Swi$:
    class Foo: UIView {
    weak var myView:UIView?
    func addAt(#x:CGFloat, y:CGFloat) -> CGFloat {
    let v = UIView(frame:CGRectMake(x,y,10,10))
    self.addSubview(v)
    self.myView = v
    return x + y
    }
    }

    View Slide

  8. blocks'(closures)
    ObjC:
    NSInteger (^increment)(NSInteger) = ^NSInteger (NSInteger x) {
    return x+1;
    }
    Swi$:
    let increment = {
    (x:NSInteger) -> NSInteger in
    return x+1
    }

    View Slide

  9. What's'a'bit$new'in'Swi,?

    View Slide

  10. Objective-C
    • structs
    • namespaces
    • operator
    overloading
    • ObjC interop
    • Swift values &
    collections
    Swift
    +
    Swift
    • classes
    • methods
    • protocols
    • extensions
    • functions
    • ARC
    • closures
    • Cocoa values 

    & collections

    View Slide

  11. structs&are&peers&to&classes
    ObjC:
    CGRect r = [view frame];
    CGFloat intTopY = CGRectGetMinY(CGRectIntegral(r));
    Swi$:
    extension CGRect {
    func intTopY() -> CGFloat {
    return CGRectGetMinY(CGRectIntegral(self))
    }
    }
    let r = view.frame;
    let intTopY = r.intTopY;

    View Slide

  12. What's'really&new'in'Swi,?

    View Slide

  13. Objective-C
    • enums with associated values
    • option types
    • pattern matching
    • generics
    • type inference
    • immutability supports
    • tuples
    Swift
    +
    • structs
    • namespaces
    • operator
    overloading
    • ObjC interop
    • Swift values &
    collections
    Swift
    +
    Swift
    • classes
    • methods
    • protocols
    • extensions
    • functions
    • ARC
    • closures
    • Cocoa values 

    & collections

    View Slide

  14. Objective-C
    • enums with associated values
    • option types
    • pattern matching
    • generics
    • type inference
    • immutability supports
    • tuples
    Swift
    +
    • structs
    • namespaces
    • operator
    overloading
    • ObjC interop
    • Swift values &
    collections
    Swift
    +
    Swift
    • classes
    • methods
    • protocols
    • extensions
    • functions
    • ARC
    • closures
    • Cocoa values 

    & collections

    View Slide

  15. Every “really new” part of Swift
    originated in a functional programming
    language of the 1980s or earlier.

    View Slide

  16. FP

    View Slide

  17. No#ma&er#what#language#you#work#
    in,#programming#in#a#func7onal#style#
    provides#benefits.#You#should#do#it#
    whenever#it#is#convenient....
    —"John"Carmack,"2012.

    View Slide

  18. JavaScript*is*brilliant*and*is*
    succeeding*...*and*I*think*it's*because*
    of*the*func:onal*stuff.
    —"Douglas"Crockford,"2014

    View Slide

  19. a"programming"style
    trea%ng(the
    func%on
    as#the#primary#unit#of#abstrac2on

    View Slide

  20. t0 = 5
    f(t0) = 50
    NSNumber * t0 = @5;
    NSNumber * pos = f(t0);
    pos; // => 50
    f(t0) = 50 pos = f(t0);
    pos; //=> 100; (surprise!)
    computational functions

    do things
    mathematical functions
    establish true relations
    which remain true

    View Slide

  21. mathematical variables
    are names
    we give to values
    t0 = 5
    t0 = 5
    t0 = 6
    computational variables
    are like names for places,
    whose contents can change
    NSNumber * five = @5;
    five = @6; // ?!
    five = @7;
    [five setIntegerValue:8]; // ?! ?!

    View Slide

  22. FP style boils down to
    • Restrictions to emulate the
    predictability of mathematical
    functions and variables
    • Idioms to use functions for all
    abstraction — in defining other
    functions, in hiding information, etc.
    • (Sometimes) type systems to
    provide compile-time checks on the
    values moving through functions

    View Slide

  23. • purity and immutability guarantees


    • function literals
    • function closures
    • functions as first-class values

    • enums (aka, sum types, tagged unions)
    • algebraic data types
    • type inference
    • fancy types: first-order, recursive, 

    dependent, higher-kinded, constrained, 

    etc..
    FEATURES
    • Idioms
    • combine, pass, & return

    functions like other values
    • Restrictions
    • pure functions
    • immutable data
    • Type systems (sometimes)
    • to check valid values
    STYLE supported by

    View Slide

  24. Haskell (1988)
    Scheme (1975)
    SML (1984)
    ML (1973)
    Scala (2003)
    OCaml (1996)
    Clojure (2009)
    F# (2005)
    Erlang (1986)
    dynamic static
    Coq, Agda, Idris

    View Slide

  25. So is Swift “functional”?

    View Slide

  26. Haskell SML Scheme Clojure Swift ObjC
    purity & immutability help Yes, very. Y Y Y Y meh
    function literals, closures,
    first-classness
    Y Y Y Y Y meh
    expression-oriented Y Y Y Y N N
    proper tail calls Y Y Y N ? ?
    memory management Y Y Y Y meh meh
    generics Y Y N N Y N
    enum types Y Y N N Y N
    type inference Y Y N N Y N
    algebraic data types Y Y N N ? N
    super DUPER fancy types Y ? N N N N

    View Slide

  27. If this were 1998 

    Swift would be a
    niche functional language

    View Slide

  28. If this were 1998 

    Swift would be a
    niche functional language
    … but maybe we’re all functional now? or could be?

    View Slide

  29. Should we care?

    View Slide

  30. functional Swift: 

    (embarrassingly trivial) HOFs

    View Slide

  31. Higher'order*func/ons:*filter
    ObjC:
    NSArray * inArray = @[@"Hello",@"Ciao"];
    NSArray * outArray = [inArray filteredArrayUsingPredicate:
    [NSPredicate predicateWithBlock:
    ^BOOL(NSString * item, NSDictionary *bindings) {
    return [item hasPrefix:@"Hello"];
    }]];
    Swi$:
    let inArray = ["Hello","Ciao"];
    let outArray = inputArray.filter({ $0.hasPrefix("Hello") })

    View Slide

  32. Higher'order*func/ons:*map
    ObjC:
    NSArray * inArray = @[@"John Appleseed", @"Sally Appleseed"];
    NSMutableArray * outArray = [NSMutableArray array];
    for (NSString * name in inArray) {
    [outArray addObject:[name componentsSeparatedByString:@" "][0]];
    }
    Swi$:
    let inArray = ["John Appleseed", "Sally Appleseed"];
    let outArray = inArray.map({ $0.componentsSeparatedByString(" ")[0] })

    View Slide

  33. Higher'order*func/ons:*reduce
    reduce!is!a!HOF!for!processing!a!collec1on!into!a!single!value.
    Swi$:
    let x = [1,2,3,4]
    let sum = x.reduce(0, +);
    sum // => 7
    let product = x.reduce(1, *);
    product //=> 24

    View Slide

  34. Closures: variable capture on purpose
    func makeCounter() -> (() -> NSInteger) {
    var x = 0
    func increment() -> NSInteger {
    x = x + 1;
    return x;
    }
    return increment;
    }
    var counter1 = makeCounter()
    var counter2 = makeCounter()
    counter1() //=> 1
    counter1() //=> 2
    counter1() //=> 3
    counter2() //=> 1

    View Slide

  35. functional Swift: 

    JSON as ADT

    View Slide

  36. JSON
    NSJSONSerialization Class Reference

    An object that may be converted to JSON must have the following
    properties:
    •The top level object is an NSArray or NSDictionary.
    •All objects are instances of NSString, NSNumber, NSArray,
    NSDictionary, or NSNull.
    •All dictionary keys are instances of NSString.
    •Numbers are not NaN or infinity.
    Other rules may apply. Calling isValidJSONObject: or attempting a
    conversion are the definitive ways to tell if a given object can be
    converted to JSON data.

    View Slide

  37. JSON%as%algebraic%data%type
    Enumera(on*with*associated*values
    enum JSONValue {
    case JNumber(NSNumber)
    case JString(String)
    case JBool(Bool)
    case JNull
    case JArray(Array)
    case JObject(Dictionary)
    case JInvalid(NSError)
    // ...
    }
    Source:(h*ps:/
    /github.com/lingoer/Swi7yJSON

    View Slide

  38. functional Swift: 

    Improving on NSError

    View Slide

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

    View Slide

  40. Either'type
    Swi$:
    enum DataResult {
    case Success(NSData)
    case Error(NSError)
    // ...
    }
    switch NSData(contentsOfFile:file, options:0) {
    case .Success(let data):
    // handle data here then return
    case .Error(let error):
    // handle error here then return
    }

    View Slide

  41. SwiftZ (by maxpow4h)
    Either and Result:
    // Result represents something that could work or be an NSError.
    // Say we have 2 functions, the first fetches from a web services,
    // the second decodes the string into a User.
    // Both *could* fail with an NSError, so we use a Result.
    func getWeb() -> Result {
    var e: NSError?
    let str = doStuff("foo", e)
    return Result(e, str)
    }
    func decodeWeb(str: String) -> Result {
    var e: NSError?
    let user = decode(str, e)
    return Result(e, user)
    }
    // We can compose these two functions with the `>>=` function.
    let getUser: Result = getWeb() >>= decodeWeb
    switch (getUser) {
    case let .Error(e): println("NSError: \(e)")
    case let .Value(user): println(user.name)

    View Slide

  42. Is ObjC going away? 

    Is it “easier” now?

    View Slide

  43. Objective-C
    • enums with associated values
    • option types
    • pattern matching
    • generics
    • type inference
    • immutability supports
    • tuples
    Swift
    +
    • structs
    • namespaces
    • operator
    overloading
    • ObjC interop
    • Swift values &
    collections
    Swift
    +
    Swift
    • classes
    • methods
    • protocols
    • extensions
    • functions
    • ARC
    • closures
    • Cocoa values 

    & collections

    View Slide

  44. –"Advanced Swift Debugging in LLDB", WWDC2014, session 410, 20m—28m.
    “Objective-C isn't really going anywhere.... Even if you start a
    brand new Swift app for the first time today after this session,
    you're going to use Cocoa, or Cocoa Touch. You're going to
    import Foundation. You're going to import UIKit. Those
    frameworks are written in Objective-C. That means, wherever you
    look around, there's going to be Objective-C in the picture.
    And you're going to have to deal with debugging mixed Swift /
    Objective-C situations..”

    View Slide

  45. Canaries in the ObjC coal mine
    • Swift achieves genuine C-like performance
    • Swift-only types appearing at public API boundaries
    • Deprecation of the ObjC runtime’s more dynamic features

    View Slide

  46. • GitHub RAC devs (jspahrsummers, joshaber, & others)
    • ReactiveCocoa. This work is indirectly influenced by typed FP.


    • Maxwell Swadling
    • SwiftZ. Currently translating lots of typed FP idioms into a Swift library. 


    • David Nolen.
    • Om. Functional approach to writing GUIs in the browser, using ClojureScript with
    Facebook’s React, leveraging CSP-style concurrency. Untyped FP.


    • Upcoming book from ObjC.io authors.

    View Slide

  47. View Slide

  48. @end

    View Slide

  49. • Videos, notes, and exercises from the Coursera “Programming
    Languages” course, a great intro to Scheme, SML, and Ruby.


    • Interesting way to do SICP: http://understudyapp.com
    • The talks by Rich Hickey (inventor of Clojure) are very rich

    View Slide