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.
var myVariable = 42
myVariable = 50
let myConstant = 42
var myVariable = 42
myVariable = 50
val myConstant = 42
let label = "The width is "
let width = 94
let widthLabel = label + String(width)
val label = "The width is "
val width = 94
val widthLabel = label + width
let apples = 3
let oranges = 5
let fruitSummary = "I have \(apples + oranges) " +
"pieces of fruit."
val apples = 3
val oranges = 5
val fruitSummary = s"I have ${apples + oranges} " +
" pieces of fruit."
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
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
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
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
var shoppingList = ["catfish", "water",
"tulips", "blue paint"]
shoppingList[1] = "bottle of water"
var shoppingList = Array("catfish",
"water", "tulips", "blue paint")
shoppingList(1) = "bottle of water"
var occupations = [
"Malcolm": "Captain",
"Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations"
var occupations = scala.collection.mutable.Map(
"Malcolm" -> "Captain",
"Kaylee" -> "Mechanic"
)
occupations("Jayne") = "Public Relations"
let emptyArray = String[]()
let emptyDictionary = Dictionary<String, Float>()
let emptyArrayNoType = []
val emptyArray = Array[String]()
val emptyDictionary = Map[String, Float]()
val emptyArrayNoType = Array()
func greet(name: String, day: String) -> String {
return "Hello \(name), today is \(day)."
}
greet("Bob", "Tuesday")
def greet(name: String, day: String): String = {
return s"Hello $name, today is $day."
}
greet("Bob", "Tuesday")
def greet(name: String, day: String): String =
s"Hello $name, today is $day."
greet("Bob", "Tuesday")
func getGasPrices() -> (Double, Double, Double) {
return (3.59, 3.69, 3.79)
}
def getGasPrices(): (Double, Double, Double) = {
return (3.59, 3.69, 3.79)
}
def getGasPrices = (3.59, 3.69, 3.79)
func sumOf(numbers: Int...) -> Int {
var sum = 0
for number in numbers {
sum += number
}
return sum
}
sumOf(42, 597, 12)
def sumOf(numbers: Int*): Int = {
var sum = 0
for (number <- numbers) {
sum += number
}
return sum
}
sumOf(42, 597, 12)
Array(42, 597, 12).sum
func makeIncrementer() -> (Int -> Int) {
func addOne(number: Int) -> Int {
return 1 + number
}
return addOne
}
var increment = makeIncrementer()
increment(7)
def makeIncrementer(): Int => Int = {
def addOne(number: Int): Int = {
return 1 + number
}
return addOne
}
var increment = makeIncrementer()
increment(7)
def makeIncrementer: Int => Int =
(number: Int) => 1 + number
var increment = makeIncrementer
increment(7)
var numbers = [20, 19, 7, 12]
numbers.map({ number in 3 * number })
var numbers = Array(20, 19, 7, 12)
numbers.map( number => 3 * number )
func area(#width: Int, #height: Int) -> Int {
return width * height
}
area(width: 10, height: 10)
def area(width: Int, height: Int): Int = {
return width * height
}
area(width = 10, height = 10)
class Shape {
var numberOfSides = 0
func simpleDescription() -> String {
return "A shape with \(numberOfSides) sides."
}
}
class Shape {
var numberOfSides = 0
def simpleDescription(): String = {
return s"A shape with $numberOfSides sides."
}
}
class Shape (var numberOfSides: Int = 0) {
def simpleDescription =
s"A shape with $numberOfSides sides."
}
var shape = Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()
var shape = new Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()
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()
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
var movieCount = 0
var songCount = 0
for item in library {
if item is Movie {
++movieCount
} else if item is Song {
++songCount
}
}
var movieCount = 0
var songCount = 0
for (item <- library) {
if (item.isInstanceOf[Movie]) {
movieCount += 1
} else if (item.isInstanceOf[Song]) {
songCount += 1
}
}
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)'")
}
}
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}'")
}
}
for object in someObjects {
let movie = object as Movie
println("Movie: '\(movie.name)', dir. \(movie.director)")
}
for (obj <- someObjects) {
val movie = obj.asInstanceOf[Movie]
println(s"Movie: '${movie.name}', dir. ${movie.director}")
}
protocol Nameable {
func name() -> String
}
func f<T: Nameable>(x: T) {
println("Name is " + x.name())
}
trait Nameable {
def name(): String
}
def f[T <: Nameable](x: T) = {
println("Name is " + x.name())
}
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"
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"
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.