Swift Today, Swift Tomorrow

I’m primarily a Javascript developer. I’ve written servers in Node.js for years, made small and big front-end apps, (mostly in React.js, of course) and written plugins for Atom and Visual Studio Code.

Yet, even after living and breathing Javascript for years now, I’ve never been quite content. I’ve always wanted something a little more functional. Javascript (I’m talking ES6) does great in many respects. It has first-class functions, tail call optimization. But it still lacks immutable data structures or a powerful type system. I’ve tried to fix these problems. I end up using Immutable.js for most of my projects, and I don’t write Javascript without flow anymore. Immutable is great, and flow is constantly getting better.

Yet, I like languages and I learn languages. I spent time learning the basics of Haskell and Elm. I can read OCaml. I’ve tried to get comfortable reading lisp (read Clojure). On the other hand, I’ve worked with Java, learnt some Scala and I play around with Swift on a regular basis.

Now, most ‘functional’ developers would talk about languages like Elm, Haskell, OCaml, Clojure, F# or, recently, Elixir. These are all great languages, and I would recommend learning at least 2 of them. But I like to bring Swift to this discussion. ‘Pure’ functional languages are great for building resilient programs, the learning curve remains steep. And the fact remains that developers coming from languages like Java, C++ et al have an extremely hard time adapting.

Swift seemed like the perfect language for such a use case. It has a strong static type system. It’s fast. And it covertly brings many functional concepts to a language that looks object-oriented on the surface. While, like Javascript, I would say it has good parts, by which I mean functional parts. Classes in Swift remain a necessary evil to make it backwards compatible with Objective C.

That said, here are some of the highlights of Swift for me:

Overall Swift seems great, but I think it could be improved a lot. Swift 3 is just around the corner, but it’s mostly a stability release, so here’s my wish list for Swift 4:

1. Bring back the currying syntax. #

The Currying Syntax was the best idea I had seen to bring a syntax that works well for currying in a C-like language.

func add(a: Int)(_ b: Int) -> Int {
  return a + b
}

add(1)(2)

I would almost say that all functions should be written like this. There should be no functions with multiple arguments. Yet, somehow, Apple and the community decided to remove this syntax from the language in Swift 3.0.
I’m not holding my breath, but I would love to get this feature back.

2. Generic type aliases #

Swift has a simple keyword for declaring types:

typealias Model = Int

Now this is well and good, but it would be great to get a way to declare generic types.

For example, you can easily write generic functions.

func maybe<T>(a: T)-> T? {
    if (arc4random_uniform(10) > 5) {
        return a
    } else {
        return nil
    }
}
func identity<T>(a: T)-> T? {
        return a
}

This is great. identity and maybe both have the same type. One of them will always return the value, while the other one will return it about half the time. Plus, the compiler will help us avoid any null-pointers.

But it’s impossible to give this type of functions a name. While I can do this:

func filterUsing<T>(arr: [T], _ fn: (T) -> T?) -> [T] {
    return arr.filter({ x in
        if fn(x) != nil {
            return true
        } else {
            return false
        }
    })
}

This is illegal in Swift:

typealias Maybe<T> = (T) -> T?
func filterUsing<T>(arr: [T], _ fn: Maybe<T>) -> [T] {
    return arr.filter({ x in
        if fn(x) != nil {
            return true
        } else {
            return false
        }
    })
}

This may not be a great example, but writing long type signatures over and over can get annoying, and being able to give it a name would be a big improvement. Further, since this feature would have no runtime cost so it will make developers faster without a penalty.

3. Union Types #

This is something I learnt to love after using Flow, and playing with languages like Elm, Haskell, OCaml, Purescript.

In Swift, you can already do some workarounds to have union types using Enums and Structs, it’s often noisy.

enum IntOrString {
    case Num(Int)
    case Str(String)
}

func add(a: IntOrString, b: IntOrString) -> String {
    switch (a, b) {
    case (.Str(let sa), .Str(let sb)):
        return sa + sb
    case (.Str(let sa), .Num(let sb)):
        return sa + String(sb)
    case (.Num(let sb), .Str(let sa)):
        return sa + String(sb)
    case (.Num(let sb), .Num(let sa)):
        return String(sa) + String(sb)
    }
}

Wouldn’t it be much better to just be able to to this:

func add(a: Int | String, b: Int | String) -> String {
    return String(a) + String(b)
}

This is common pattern in all the functional languages and even the type systems for Javascript like Flow and Typescript.

Further, there shouldn’t be a run-time cost to this either as Swift clearly already has a union type built-in: Optional.

 
0
Kudos
 
0
Kudos

Now read this

Ideas on Improving Error Handling in Javascript

I like Javascript. I like it a lot. But of late, I’m really annoyed by the state of Error Handling in the language. There are some tools that improve the situation some of the times. Promises and Reactive Extensions both give you a... Continue →