swift vs scala 2.11
TRANSCRIPT
Swift vs Scala 2.11
Denys Shabalin
June 2014
Control FlowSwift Scala
for-infor i in 1…5 { println(“i = \(i)”) }
for (i <- 1 to 5) { println(s”i = $i”) }
for-yield N/A for (i <- 1 to 5) yield i^2
for-increment
for var i = 0; i < 3; ++i { println(“i = \(i)”) }
N/A
while while cond { … } while(cond) { … }
do-while do { … } while cond do { … } while(cond)
Control FlowSwift Scala
if-then if cond { … } if (cond) { … }
if-then-else if cond { … } else { … } if (cond) { … } else { … }
switchswitch value { case pattern where cond: … }
value match { case pattern if cond => … }
control transfer
continue, break, fallthrough N/A
labels label: while cond { … } N/A
ExpressionsSwift Scala
unary op!expr * customizable
!expr !* limited to !, ~, +, -
binary op a + b a + b
postfix op a++ a++
assign a = b (a, b) = (1, 2)
a = b N/A
is a is T a.isInstanceOf[T]
as a as T a as? T
a.asInstanceOf[T] N/A
ExpressionsSwift Scala
literals 1, 1.0, “foo” 1, 1.0, “foo”
interpo-lation
“\(x) + \(y) = \(x + y)” !* not extensible
s”$x + $y = ${x + y}” !* extensible
array literal [a, b, c] Array(a, b, c)
(mutable) map literal [a: b, c: d]
s.c.m.Map(a -> b, c -> d) !* scala.collection.mutable.Map
ExpressionsSwift Scala
selfself self.foo self[foo] self.init(foo)
this this.foo this(foo) // in exprs this(foo) // in ctors
supersuper.foo super[foo] super.init(foo)
super.foo super(foo) N/A
closure
{ (params) -> ret in … } !* ret can be inferred
{ (params) => … }
place-holders f { $0 > $1 } f { _ > _ }
implicit membership .foo N/A
Expressions
Swift Scala
block { … } { … }
return return foo return foo
throw N/A throw expr
try N/Atry expr catch { … } finally { … }
importsimport foo.bar import class foo.bar N/A
import foo.bar N/A import foo._
DeclarationsSwift Scala
letlet x: T = expr let y = 2 let (x, y) = (1, 2) @lazy let z = f()
val x: T = expr val y = 2 val (x, y) = (1, 2) lazy val z = f()
var var x: T = expr …
var x: T = expr …
propertyvar name: T { get { stats1 } set(v) { stats2 } }
def name: T = stats1 def name_=(v: T) = stats2
observersvar name: T = expr { willSet { stats1 } didGet(v) { stats 2 } }
N/A !* can be emulated via macro annotations
DeclarationsSwift Scala
typealias typealias T = … type T = …
methods
func f(x: A) -> B { … } func g(x: A) { … } func h<T>(x: T) -> T { … } func k<T: A>(x: T) -> T { … } func m(x: Int = 0) { … } func n(x: A)(y: B) -> C { … }
def f(x: A): B = … def g(x: A) { … } def h[T](x: T): T = … def k[T <: A](x: T): T = … def m(x: Int = 0) { … } def n(x: A) = { (y: B) => … }
subscripts
subscript(key: A) -> B { get { stats1 } set(value) { stats2 } }
def apply(key: A): B = { stats1 } def update(key: A, value: B): Unit = { stats2 }
DeclarationsSwift Scala
enum case
enum Foo { case A(x: Int) case B(y: Int) }
sealed abstract class Foo final case class A(x: Int) extends Foo final case class B(x: Int) extends Foo
enum with raw cases
!enum Foo { case A, B = 1, 2 }
// roughly but not really class Foo private(value: Int) extends AnyVal object Foo { val (A, B) = (new Foo(1), new Foo(2)) }
struct
struct Foo { … } !* alocated on stack
N/A !* multi-parametric value classes?
DeclarationsSwift Scala
class with explicit and
convenience inits
class Foo { let x: Int init(x: Int) { self.x = x } convenience init(x: String) { self.x = x.toInt() } } Foo(0) Foo(“1”)
class Foo(val x: Int) { def this(x: String) = this(x.toInt) } new Foo(0) new Foo(“1”)
struct with default init
struct Foo { let x = 0 } Foo() Foo(x: 1)
class Foo(val x: Int = 0) new Foo() new Foo(x = 1)
DeclarationsSwift Scala
protocol
protocol Nameable { func name() -> String } !func f<T: Nameable> (x: T) { … }
trait Nameable { def name(): String } !def f[T <: Nameable](x: T) { … }
extensionsextension Foo: Nameable { func name() -> String { … } }
implicit class RichFoo(foo: Foo) extends Nameable { def name(): String = … }
DeclarationsSwift Scala
prefix operator
operator prefix + {} func +(x: T) {} !* extensible
// this: T def unary_+ = … !* not extensible
postfix operator
operator postfix ++ {} func ++(x: T) { … }
// this: T def ++ = …
infix operator
operator infix + { precedence 100 associativity left } func +(left: A, right: B) { … }
// this: A def +(value: B) = … !* associativity and precedence via convention
PatternsSwift Scala
wildcard case _: case _ =>
binding case let x: case x =>
tuple case let (a, b): case (a, b) =>
enum case Foo(let a): case Foo(a) =>
is/as case x is Int: case x as Int:
case x: Int => not sure
expressioncase “foo”: case x: case 2 + 2:
case “foo” => case `x` => N/A !* limited subset of expressions
extractor
N/A case B: !* you can emulate nullary extractors that return booleans via custom comparator and expression patterns
case A(x) => case B() =>
TypesSwift Scala
identifier A N/A * swift types aren’t nullable
tuple (A, B) (x: A, y: B)
(A, B) N/A * but similar to { def x: A; def y: B }
function A -> B A => B
array A[] Array<A> Array[A]
optional A? Optional<A>
Option[A] !* doesn’t directly map as swift types aren’t nullable by default
implicitly unwrapped
optionalA! ImplicitlyUnwrappedOptional<A> A
protocol composition protocol<A, B> A with B
metatype A.Type B.Protocol N/A