Fork me on GitHub

A new programming language called Swift was announced at WWDC'14. Here's a source-to-source comparison of Swift and Scala using the examples given in "The Swift Programming Language" book published by Apple in the iTunes Store.

I suspect the two are related ;-) Syntacticly, it's fair to say that Swift is a dialect of Scala. Swift inherits from Scala most of the "banner" features listed by Apple: Type Inference, Closures, Tuples, Protocols, Extensions, Generics, Read-Eval-Print-Loop, etc.

Despite their syntactic similarity, Swift's runtime environment is quite distinct from Scala's, and is perhaps the most interesting aspect of the new language. Scala compiles to the JVM, uses garbage collection, and its object model transparently integrates with Java. Swift compiles to native code, uses automatic reference counting, and its object model transparently integrates with Objective-C. Thus, the similarity between the two languages does not extend much below the surface.

Den Shabalin provides another excellent point-by-point comparison.

p.s. Don't take this code too seriously! Most of it is rote, minimalistic translation of the Swift examples given by Apple. I give a handful of more idiomatic Scala translations. Feel free to submit a GitHub issue/pull request if you find anything unbearably crass.

Your search didn't match any comparisons.

Basics

Hello World

SWIFT

println("Hello, world!")

SCALA

println("Hello, world!")

Variables And Constants

SWIFT

var myVariable = 42
myVariable = 50
let myConstant = 42

SCALA

var myVariable = 42
myVariable = 50
val myConstant = 42

Explicit Types

SWIFT

let explicitDouble: Double = 70

SCALA

val explicitDouble: Double = 70

Type Coercion

SWIFT

let label = "The width is "
let width = 94
let widthLabel = label + String(width)

SCALA

val label = "The width is "
val width = 94
val widthLabel = label + width

String Interpolation

SWIFT

let apples = 3
let oranges = 5
let fruitSummary = "I have \(apples + oranges) " + 
                   "pieces of fruit."

SCALA

val apples = 3
val oranges = 5
val fruitSummary = s"I have ${apples + oranges} " +
                   " pieces of fruit."

Range Operator

SWIFT

let names = ["Anna", "Alex", "Brian", "Jack"]
let count = names.count
for i in 0..count {
    println("Person \(i + 1) is called \(names[i])")
}
// Person 1 is called Anna
// Person 2 is called Alex
// Person 3 is called Brian
// Person 4 is called Jack

SCALA

val names = Array("Anna", "Alex", "Brian", "Jack")
val count = names.length
for (i <- 0 until count) {
    println(s"Person ${i + 1} is called ${names(i)}")
}
// Person 1 is called Anna
// Person 2 is called Alex
// Person 3 is called Brian
// Person 4 is called Jack

Inclusive Range Operator

SWIFT

for index in 1...5 {
    println("\(index) times 5 is \(index * 5)")
}
// 1 times 5 is 5
// 2 times 5 is 10
// 3 times 5 is 15
// 4 times 5 is 20
// 5 times 5 is 25

SCALA

for (index <- 1 to 5) {
    println(s"$index times 5 is ${index * 5}")
}
// 1 times 5 is 5
// 2 times 5 is 10
// 3 times 5 is 15
// 4 times 5 is 20
// 5 times 5 is 25

Collections

Arrays

SWIFT

var shoppingList = ["catfish", "water",
    "tulips", "blue paint"]
shoppingList[1] = "bottle of water"

SCALA

var shoppingList = Array("catfish",
    "water", "tulips", "blue paint")
shoppingList(1) = "bottle of water"

Maps

SWIFT

var occupations = [
    "Malcolm": "Captain",
    "Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations"

SCALA

var occupations = scala.collection.mutable.Map(
    "Malcolm" -> "Captain",
    "Kaylee" -> "Mechanic"
)
occupations("Jayne") = "Public Relations"

Empty Collections

SWIFT

let emptyArray = String[]()
let emptyDictionary = Dictionary<String, Float>()
let emptyArrayNoType = []

SCALA

val emptyArray = Array[String]()
val emptyDictionary = Map[String, Float]()
val emptyArrayNoType = Array()

Functions

Functions

SWIFT

func greet(name: String, day: String) -> String {
    return "Hello \(name), today is \(day)."
}
greet("Bob", "Tuesday")

SCALA

def greet(name: String, day: String): String = {
    return s"Hello $name, today is $day."
}
greet("Bob", "Tuesday")

IDIOMATIC SCALA

def greet(name: String, day: String): String =
    s"Hello $name, today is $day."

greet("Bob", "Tuesday")

Tuple Return

SWIFT

func getGasPrices() -> (Double, Double, Double) {
    return (3.59, 3.69, 3.79)
}

SCALA

def getGasPrices(): (Double, Double, Double) = {
    return (3.59, 3.69, 3.79)
}

IDIOMATIC SCALA

def getGasPrices = (3.59, 3.69, 3.79)

Variable Number Of Arguments

SWIFT

func sumOf(numbers: Int...) -> Int {
    var sum = 0
    for number in numbers {
        sum += number
    }
    return sum
}
sumOf(42, 597, 12)

SCALA

def sumOf(numbers: Int*): Int = {
    var sum = 0
    for (number <- numbers) {
        sum += number
    }
    return sum
}
sumOf(42, 597, 12)

IDIOMATIC SCALA

Array(42, 597, 12).sum

Function Type

SWIFT

func makeIncrementer() -> (Int -> Int) {
    func addOne(number: Int) -> Int {
        return 1 + number
    }
    return addOne
}
var increment = makeIncrementer()
increment(7)

SCALA

def makeIncrementer(): Int => Int = {
    def addOne(number: Int): Int = {
        return 1 + number
    }
    return addOne
}
var increment = makeIncrementer()
increment(7)

IDIOMATIC SCALA

def makeIncrementer: Int => Int = 
    (number: Int) => 1 + number

var increment = makeIncrementer
increment(7)

Map

SWIFT

var numbers = [20, 19, 7, 12]
numbers.map({ number in 3 * number })

SCALA

var numbers = Array(20, 19, 7, 12)
numbers.map( number => 3 * number )

Sort

SWIFT

sort([1, 5, 3, 12, 2]) { $0 > $1 }

SCALA

Array(1, 5, 3, 12, 2).sortWith(_ > _)

Named Arguments

SWIFT

func area(#width: Int, #height: Int) -> Int {
    return width * height
}

area(width: 10, height: 10)

SCALA

def area(width: Int, height: Int): Int = {
    return width * height
}

area(width = 10, height = 10)

Classes

Declaration

SWIFT

class Shape {
    var numberOfSides = 0
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}

SCALA

class Shape {
    var numberOfSides = 0
    def simpleDescription(): String = {
        return s"A shape with $numberOfSides sides."
    }
}

IDIOMATIC SCALA

class Shape (var numberOfSides: Int = 0) {
    def simpleDescription =
        s"A shape with $numberOfSides sides."
}

Usage

SWIFT

var shape = Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()

SCALA

var shape = new Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()

Subclass

SWIFT

class NamedShape {
    var numberOfSides: Int = 0
    var name: String

    init(name: String) {
        self.name = name
    }

    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}

class Square: NamedShape {
    var sideLength: Double

    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 4
    }

    func area() -> Double {
        return sideLength * sideLength
    }

    override func simpleDescription() -> String {
        return "A square with sides of length
                \(sideLength)."
    }
}

let test = Square(sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription()

IDIOMATIC SCALA

class NamedShape(var name: String,
                 var numberOfSides: Int = 0) {
    def simpleDescription =
        s"A shape with $numberOfSides sides."
}

class Square(var sideLength: Double, name: String)
    extends NamedShape(name, numberOfSides = 4) {
    def area = sideLength * sideLength
    override def simpleDescription =
        s"A square with sides of length $sideLength."
}

val test = new Square(5.2, "my test square")
test.area
test.simpleDescription

Checking Type

SWIFT

var movieCount = 0
var songCount = 0
 
for item in library {
    if item is Movie {
        ++movieCount
    } else if item is Song {
        ++songCount
    }
}

SCALA

var movieCount = 0
var songCount = 0
 
for (item <- library) {
    if (item.isInstanceOf[Movie]) {
        movieCount += 1
    } else if (item.isInstanceOf[Song]) {
        songCount += 1
    }
}

Pattern Match

SWIFT

var movieCount = 0
var songCount = 0

for item in library {
  switch item {
    case let movie as Movie:
      ++movieCount
      println("Movie: '\(movie.name)', dir. \(movie.director)")
    case let song as Song:
      ++songCount
      println("Song: '\(song.title)'")
  }
}

SCALA

var movieCount = 0
var songCount = 0

for (item <- library) {
  item match {
    case movie: Movie =>
      movieCount += 1
      println(s"Movie: '${movie.name}', dir. ${movie.director}")
    case song: Song =>
      songCount += 1
      println(s"Song: '${song.title}'")
  }
}

Downcasting

SWIFT

for object in someObjects {
    let movie = object as Movie
    println("Movie: '\(movie.name)', dir. \(movie.director)")
}

SCALA

for (obj <- someObjects) {
    val movie = obj.asInstanceOf[Movie]
    println(s"Movie: '${movie.name}', dir. ${movie.director}")
}

Protocol

SWIFT

protocol Nameable {
    func name() -> String
}

func f<T: Nameable>(x: T) {
    println("Name is " + x.name())
}

SCALA

trait Nameable {
    def name(): String
}

def f[T <: Nameable](x: T) = {
    println("Name is " + x.name())
}

Extensions

SWIFT

extension Double {
    var km: Double { return self * 1_000.0 }
    var m: Double { return self }
    var cm: Double { return self / 100.0 }
    var mm: Double { return self / 1_000.0 }
    var ft: Double { return self / 3.28084 }
}
let oneInch = 25.4.mm
println("One inch is \(oneInch) meters")
// prints "One inch is 0.0254 meters"
let threeFeet = 3.ft
println("Three feet is \(threeFeet) meters")
// prints "Three feet is 0.914399970739201 meters"

SCALA

object Extensions {
    implicit class DoubleUnit(d: Double) {
        def km: Double = { return d * 1000.0 }
        def m: Double = { return d }
        def cm: Double = { return d / 100.0 }
        def mm: Double = { return d / 1000.0 }
        def ft: Double = { return d / 3.28084 }
    }
}

import Extensions.DoubleUnit

val oneInch = 25.4.mm
println(s"One inch is $oneInch meters")
// prints "One inch is 0.0254 meters"
val threeFeet = 3.ft
println(s"Three feet is $threeFeet meters")
// prints "Three feet is 0.914399970739201 meters"

IDIOMATIC SCALA

object Extensions {
    implicit class DoubleUnit(d: Double) {
        def km = d * 1000.0
        def m = d
        def cm = d / 100.0
        def mm = d / 1000.0
        def ft = d / 3.28084
    }
}

import Extensions.DoubleUnit

val oneInch = 25.4.mm
println(s"One inch is $oneInch meters")
// prints "One inch is 0.0254 meters"
val threeFeet = 3.ft
println(s"Three feet is $threeFeet meters")
// prints "Three feet is 0.914399970739201 meters"

2014 July 16 - Added additional comparisons to 'idiomatic' Scala usage.

2014 July 16 - Pattern match example from Fredrik Ekholdt.

2014 June 4 - Cleanup of Subclass from Gerald Loeffler.

2014 June 4 - Added typecasting, protocols, and extensions.