Skip to content

Scala for Python Developers by Kevin Stanton

| scala | python | vs | comparison |

Reference


1. Classes

Python

class Dog(object):
    def __init__(self, name):
        print 'This line runs upon instantiation'
        self.name = name
    def speak(self):
        print '%s: Bark!' % self.name
    def command(self, cmd):
        print '%s ::%s::' % (self.name, cmd)
dog = Dog('Rover')
dog.speak()
dog.command('sit')

Scala

class Dog(name: String) {
  /*
  The body of the class can contain code for the primary constructor, instead
  of an explicitly defined constructor method like in Java or Python. Also,
  note that the parameters for the constructor are in the class definition
  portion at the top. Scala automatically places them in fields named after
  the parameter name. Less boilerplate!
   */
  println("This line runs upon instantiation")

  /*
  Notice how there is no equals sign on the speak method, that's because it
  doesn't return anything. Technically, it returns Unit, which is like Java's
  void and Python's None.
   */
  def speak() { println(this.name + ": Bark!") }

  def command(cmd: String) = {
    println(name + " ::" + cmd + "::")
  }
}

val dog = new Dog("Rover")
// This line runs upon instantiation of a Dog, it is the primary constructor
// dog: Dog = Dog@11727596

dog.speak()
// Rover: Bark!

dog.command("sit")
// Rover ::sit::

2. Dictionaries and Maps

Python

>>> x = {"dog": "Woof", "cat": "Meow"}
>>> for k, v in x.items():
...   print "%s=%s" % (k, v)
...
dog=Woof
cat=Meow
>>> print "the dog says " + x["dog"] + " and the cat says " + x["cat"]
the dog says Woof and the cat says Meow
>>> print x.get("duck", "quack")
quack
>>> x['fox'] = '??????'
>>> print "what does the fox say: " + x['fox']
what does the fox say: ??????

Scala

var x = Map("dog" -> "Woof", "cat" -> "Meow")
for ((k, v) <- x)
  printf("%s=%s\n", k, v)
// dog=Woof
// cat=Meow

println("the dog says " + x("dog") + " and the cat says " + x("cat")) // like lists, note parens..not brackets
// the dog says Woof and the cat says Meow

println(x.getOrElse("duck", "quack"))
// quack

x += ("fox" -> "??????")

println("what does the fox say: " + x("fox"))
// what does the fox say: ??????

3. IO and Files

Python

import sys
if len(sys.argv) > 0:
    for line in open(sys.argv[1]):
        print line.rstrip('\r\n') # scala.io.Source removes line terminators
else:
    sys.stderr.write('Please enter filename')

Scala

import scala.io.Source

if (args.length > 0) {
  for (line <- Source.fromFile(args(0)).getLines)
    println(line)
} else {
  Console.err.println("Please enter filename")
}

4. For Comprehensions

Python

Python
l = [1, 2, 3, 4, 5, 6]
evens = [n for n in l if n % 2 == 0]

Scala

val l = List(1, 2, 3, 4, 5, 6)
val evens = for (n <- l if n % 2 == 0) yield n

5. Function literals

Python

# Python does not have a function literal syntax per se, but functions are first

# class objects and you can treat them in similar ways in Scala.

greeting = lambda name: "Hello " + name
print greeting("world")

def greet(name): return "Hello " + name

greeting = greet
print greeting("world")

Scala

var greeting = (name: String) => "Hello " + name
println(greeting("world"))

def greet(name: String) = "Hello " + name
greeting = greet
println(greeting("world"))

6. Functions one-liner

Python

def max2(x, y): return x if x > y else y
>>> max2(17, 19)
19
>>> max2(19, 17)
19

Scala

// scala, function definition (brief)
def max2(x: Int, y: Int) = if (x > y) x else y

max2(17, 19)
// res2: Int = 19
max2(19, 17)
// res3: Int = 19

7. Functions

Python

def max(x, y):
  if x > y:
    return x
  else:
    return y

Scala

def max(x: Int, y: Int): Int = {
  if (x > y) x
  else y
}

/*
Note that type information is present in the function definition. Scala is a
statically-typed language. But it's type system is advanced, and usually it can
infer the type. So you can leave some type information off for improved
readability.
 */

def max(x: Int, y: Int) = {
  if (x > y) x
  else y
}

/*
Seen in the second form, Scala can usually infer the return type. So you can
leave it off. In some cases it can't infer the return type, i.e. recursion.
Also, note how there is no explicit return statement in the functions. In Scala,
the last statement executed in the body of a function becomes the return value.
 */

def max(x: Int, y: Int): Int = {
  if (x > y) return x
  else return y
}
/*
You can use return statements, but if you do, Scala's compiler cannot infer
the return type so you must specify it.
http://stackoverflow.com/questions/2209179/type-inference-on-method-return-type
*/

8. Java interop

Python

This isn’t for Python programmers, but it is pretty cool to see how seamlessly Java code can be used in Scala. The entire world of existing Java libraries can be leveraged.

Scala

import java.io.{FileReader, BufferedReader, IOException}

if (args.length > 0) {

  try {
    val reader = new BufferedReader(new FileReader(args(0)))

    var done = false
    while (!done) {
      val line = reader.readLine
      if (line == null) done = true else println(line)
    }

  } catch {
    case ioe: IOException => println("ERROR: IOException")
  }

} else {
  println("ERROR: no file specified")
}

9. Lists

9.1. Overview

Python

l = ["one", "two", "three"]
print l[0]
for a in l:
  print a
*/

Scala

val l = List("one", "two", "three")
println(l(0))
for (a <- l)
  println(a)

Note how the list is indexed with parens, not square brackets. This is because you’re actually making a method call.

println(l(0)) <– outputs “one” println(l.apply(0)) <– outputs “one”

9.2. Concatenating lists

Python

list1 = [1, 2]
list2 = [3, 4]
biglist = list1 + list2

Scala

// scala concatenating lists
val list1 = List(1, 2)
val list2 = List(3, 4)
val biglist = list1 ::: list2

Note: In Scala, Lists are immutable. Python’s lists, however, are mutable. Arrays, on the other hand, are mutable.

scala, prepend an element (using the “cons” operator, ::) to an existing list will generate a new list:

val list3 = List(2, 3)
val newlist = 1 :: list3

In python, you would do this using concatenation and a temporary list of length 1:

list1 = [2, 3]
newlist = [1] + list1

Or you could prepend the 1 to the existing list at the front, but this would be inefficient:

list1.insert(0, 1)

9.3. Sorting a list

Python

alist = [7, 2, 18, 3, 6]
sorted(alist) # returns a new list, sorted
alist.sort() # sorts the list in place

Scala

val alist = List(7, 2, 18, 3, 6)
println(alist.sorted)

10. Looping range and notes on operators

10.1. Loop over range of numbers

Python

for i in range(0, 5):
    print i

Note, last number printed is 4.

Scala

// Scala is inclusive over the range, last number printed is 5
for (i <- 0 to 5)
  println(i)

// interesting to note, this code is equivalent:
for (i <- 0.to(5))
  println(i)
// because "to" is actually not an operator, but a method on Int, see:
0.to(5)
// res16: scala.collection.immutable.Range.Inclusive = Range(0, 1, 2, 3, 4, 5)

0 to 5
// res17: scala.collection.immutable.Range.Inclusive = Range(0, 1, 2, 3, 4, 5)

10.2. Operators

This may seem somewhat odd, but it actually is similar (at least to my non-expert eye) to how operators are implemented in languages like Python and PHP, e.g.

Python

>>> x = 5
>>> x.__add__
<method-wrapper '__add__' of int object at 0x7fc339c10788>
  >>> x.__add__(2)
7
>>> x + 2
7

Scala

val x = 5
// x: Int = 5

x.+(2)
// res20: Int = 7

x + 2
// res21: Int = 7

11. Sets

Python

>>> basket1 = set(["apple", "pear"])
>>> basket1.add("strawberry")
>>> basket2 = set(["grape", "apple", "starfruit"])
>>> print "common to both: %s" % (basket1 & basket2)
common to both: set(['apple'])
>>> print "in either basket: %s" % (basket1 | basket2)
in either basket: set(['strawberry', 'grape', 'apple', 'pear', 'starfruit'])

Scala

var basket1 = Set("apple", "pear")
// basket1: scala.collection.immutable.Set[String] = Set(apple, pear)
basket1 += "strawberry"
var basket2 = Set("grape", "apple", "starfruit")
// basket2: scala.collection.immutable.Set[String] = Set(grape, apple, starfruit)
println("common to both: " + (basket1 & basket2))
// common to both: Set(apple)
println("in either basket: " + (basket1 | basket2))
// in either basket: Set(grape, apple, pear, strawberry, starfruit)

// If you needed a mutable set:
import scala.collection.mutable
val mutableSet = mutable.Set("a", "b")
mutableSet += "c"

// or maybe an immutable HashSet?
import scala.collection.immutable.HashSet
var hashSet = HashSet(1, 2, 3)

12. Tuples

Python

>>> pair = (1, "foo")
>>> print pair[0]
1
>>> print pair[1]
foo

Scala

val pair = (1, "foo")
// pair: (Int, String) = (1,foo)
println(pair._1)
// 1
println(pair._2)
// foo

Scala has tuples too (yay, no JavaBean silliness for returning multiple values of varied types!)

Both Scala and Python tuples are immutable, but Scala’s are type safe, hence the strange accessing mechanism (pair._1 vs. pair[0]).

Scala actually defines multiple tuple types, up to Tuple22, to achieve this.