5 Reasons Why Rubyist Will Love Swift

Written by Matt Sears

At Littlelines, we are very excited by Apple's announcment last week of their brand new programming language for building iOS and Mac apps called Swift. As developers, we get very curious when new languages are announced and this was no exception. For the past week, I've been buried in books, articles, and screencasts on all things Swift. Along the way, I've recognized a few things about Swift that I really like and they just so happen to be some of the same things I love about Ruby.

1. String Interpolation

Oh how we love our string interpolation in Ruby. Anything we can do to avoid concatenate strings together with plus(+) signs - we'll do.

name = "Matt"
puts "Hello there, #{name}."

#=> Hello there, Matt."

In Swift we can do the same thing by wrapping our variables or constants in parenthesis and escaping it with a backslash e.g. \(variable). Swift also supports expressions inside the parenthesis as well.

let name = "Name"
println("Hello there, \(name).")

//=> Hello, there Matt.

2. Optional Binding & Implicit Returns

We've long enjoyed using optional binding in Ruby to check if our variable contains a value before using it in our if block for example. This is a great way to maintain clean control flow in our code.

if current_user = find_current_user
   notify_user(current_user)
end

In Swift, we can do something very similar by extracting the value into a constant or variable in a single action.

if let currentUser = findCurrentUser() {
   notifyUser(currentUser)
}

3. Keyword Arguments

Keyword arguments were introduced in Ruby in version 2.0. Before the version 2.0 released, we had to "emulate" keyword arguments by passing a hash of arguments like this:

def foo(options = {})
  options = {bar: 'bar'}.merge(options)
  puts "#{options[:bar]} #{options[:buz]}"
end

If you have been coding Ruby for a while, you probably saw something like this a lot. But, it's not a very clean solution and we can't easily set default values. So, in version 2.0, keyword were introduced add now we can write something like this:

def say_hello(name: "Matt")
  puts "Hello there, #{name}"
end

Much better.This is a nice improvement and we can do the same thing in Swift. In addition, we can assure the arguments are of a specific type (more on that later). For example, we can force the arguments to be a String. If we pass anything other than a String, the compiler will flag an error.

func sayHello(name: String) {
  printlin("Hello there, \(name)")
}

sayHello("Matt")

//=> "Hello there, Matt"

4. Type Inference

Ruby is a dynamic type language so we can assign a variable anything we want: strings, integers, floats, it doesn't matter.

name = "Matt"
name = 23
name = 45.00

Swift is a type safe language. So if your code expects a string and you pass it an integer, the compiler will complain. However, Swift doesn't require us to specify a type. With Swift's type inference, much of the work of specifying the type is done for us. For example, take the following snippet:

var name = "Matt"
name = 3.14159  //=> Compiler Error: Can't convert!

Since we assigned the name constant a literal value of "Matt", Swift infers the constant to be of type String. If we try to assign a value to the name variable that is not a String, the compiler will flag it.

5. Closures

As Rubyist, we love closures and use them a lot. Ruby provides many ways for us to use closures e.g. Procs, Lambdas, and Blocks in particular. Let's take blocks for example:

def say_hello(&block)
  block.call
end

say_hello { puts "Hello there" }

#=> "Hello there"

This is just one example closures in Ruby. We're simply passing a self-contained block of functionality that the closure can capture and store a reference to. This is know has closing over, hence the name "closures". In the above, Ruby example, we're passing the puts statement to the closure, but puts isn't being called until inside the block. In Swift, it looks very similar:

func sayHello(task: () -> ()) {
   task()
}

sayHello { println("Hello there.") }

//=> "Hello there."

Again, we're passing the println statement, but it won’t be called until it's inside the sayHello function.

In addtion, Swift also allows us to remove a lot of the syntactic noise (which we love in Ruby). Take for example, the sort function:

var fruits = ["Orange", "Apple", "Banana"]

fruits.sort({(a: String, b: String ) -> Bool in
    return a < b
})

//=> ["Apple", "Banana", "Orange"]

We can accomplish the same thing with the help of type inference and implicit returns that we touch on before:

fruits.sort({a, b in a < b })

Swift also has implicit arguments so we can accomplished the same sort with even less code:

fruits.sort{ $0 < $1 }

So there you have it. Hopefully, I've illustrated how we can enjoy writing Swift the same way we enjoy writing Ruby. I encourage you to checkout the official Swift Language Guide, available for free on iBooks. There are also quite a few videos on Swift available on Apple from the WWDC14 event this past week.