Skip to content

Instantly share code, notes, and snippets.

@MartinRosenberg
Last active June 20, 2019 02:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MartinRosenberg/be255757ad22a02415430739e0039ae6 to your computer and use it in GitHub Desktop.
Save MartinRosenberg/be255757ad22a02415430739e0039ae6 to your computer and use it in GitHub Desktop.
Python vs Scala

Comments

def foo():
    """A multi-line
    docstring.
    """
    pass  # A single-line comment.
/** A multi-line
  * docstring.
  */
def foo(): Unit = ??? // A single-line comment.
// Side note: ??? is Scala for "Not Implemented"; it throws an exception if called

/* A multi-line
comment.
*/

Variables

foo = 1
foo = 2 # this is fine
var foo = 1
foo = 2 // this is fine

val foo = 1
foo = 2 // compiler error; no reassignment to val

If/Else

x = 3
if x == 5:
    print("cool")
elif 1 < x <= 4:
    print("sorta good")
else:
    print("no")
// This is not idiomatic in Scala
val x = 3
// curly braces are optional for any block that only contains one line
if (x == 5) {
  println("cool")
} else if (x > 1 && x <= 4) {
  println("sorta good")
} else {
  println("no")
}

Ternary

x = 3
res = "cool" if x == 5 else "sorta good" if 1 < x <= 4 else "no"
val x = 3
// this can also be inlined, but don't do that
val res =
  if (x == 5) "cool"
  else if (x > 1 && x <= 4) "sorta good"
  else "no"

Pattern matching

thing = "bar"
switch = {
    "foo": 1,
    "bar": 2,
    "quid": 3
}
res = switch[thing]
// you can't tell from this example, but the pattern matching syntax
// is very powerful, and used a LOT
val thing = "bar"
val res = thing match {
  case "foo"  => 1
  case "bar"  => 2
  case "quid" => 3
}

Basic function syntax

def add_int_and_double(a, b):
    return a + b
def addIntAndDouble(a: Int, b: Double): Double = {
  a + b // the last line of a block is automatically returned
}
// as mentioned, the curly braces can be dropped
def addIntAndDouble(a: Int, b: Double): Double = a + b

Lambdas

add = lambda x, y: x + y
val add = (x: Int, y: Int) => x + y
val add: (Int, Int) => Int = (x, y) => x + y
// in most cases, though, the types can be inferred, e.g.:
List(1, 2, 3).map(x => x + 1)

Basic class syntax

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def announce_age:
        print(age)
class Person(name: String, age: Int) {
  def announceAge: Unit = println(age)
}

Ranges

r = range(1, 6, 2)

l = list(range(1, 6, 2))
val r = 1 until 6 by 2
val r = 1.until(6).by(2)
val r = 1 to 5 by 2
val r = 1.to(5).by(2)

val l = (1 to 5 by 2).toList

Mapping

l = [x + 1 for x in range(1, 6, 2)]
l = list(map(lambda x: x + 1, range(1, 6, 2)))
val l = (1 to 5 by 2).map(x => x + 1)
val l = (1 to 5 by 2).map(_ + 1)

for loops

for i in range(0, 5):
    print(i)
    
for i in range(0, 5):
    for k in range(1, 4):
        print(i + k)
(0 to 4).foreach(i => println(i))
// _ does a lot in Scala; here, it's a lambda shorthand
(0 to 4).foreach(println(_))
// because the function already just takes what it's given, you can pass the function directly
(0 to 4).foreach(println)
// `for` is syntactic sugar for `foreach`
for (i <- 0 to 4) {
  println(i)
}
// same as with `if`, you can leave out unnecessary curly braces
for (i <- 0 to 4) println(i)

// reminder: whitespace is not semantic
(0 to 4).foreach(i =>
  (1 to 3).foreach(k =>
    println(i + k)
  )
)
// `for` actually does some pretty interesting shit
// it gets used a lot for fancy/complicated functional stuff
for {
  i <- 0 to 4
  k <- 1 to 3
} {
  println(i + k)
}
// shortened
for (i <- 0 to 4; k <- 1 to 3) println(i + k)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment