Swift is a lot like Scala
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.
Basics
Variables And Constants
SWIFT
var myVariable = 42 myVariable = 50 let myConstant = 42
SCALA
var myVariable = 42 myVariable = 50 val myConstant = 42
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")
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) }
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)
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)
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 )
Named Arguments
SWIFT
def 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." } }
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) test.area() test.simpleDescription()
SCALA
<code>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 } }
Downcasting
SWIFT
for object in someObjects { let movie = object as Movie println("Movie: '\(movie.name)', dir. \(movie.director)") }
SCALA
<code>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"
Leave a Reply
You must be logged in to post a comment.