Skip to content

Instantly share code, notes, and snippets.

@phipsgabler
Last active March 16, 2017 08:37
Show Gist options
  • Save phipsgabler/084fa1d84511eb52abf0ea7861658f8d to your computer and use it in GitHub Desktop.
Save phipsgabler/084fa1d84511eb52abf0ea7861658f8d to your computer and use it in GitHub Desktop.
// TO SEE THE PRINTLN'S, RUN `showExamples` IN THE CONSOLE
package object example {
def showExamples(): Unit = {
// # Basics
// > Goal of language: modular, functional, OO (+ Java interop)
// > Sophisticated hierarchies, type system, and flexible syntax
// # Classes
// ## Normal & abstract ones
abstract class A {}
// This gives `B` a constructor and private field `i`
class B(i: Int) extends A {}
println(new B(234))
// ## Traits (like interfaces, but better)
// can hold abstract and concrete methods, as well as fields
trait Foo {
val x = 42
}
// mixin inheritance:
val bla = new B(3) with Foo
println(bla.x)
// ## Case classes: automatic implementation of boilerplace code
// E.g. toString, hashCode, equals, canEqual, getters for members, ...
// Provide a "factory constructor", ie. no `new` required:
case class Bla(n: Int)
println(Bla(10))
// contrary to Java, `==` works if `equals` is implemented:
println(Bla(10) == Bla(10))
// ## Objects (like singletons, for static members)
object Stuff {
val PI = 3.0
}
println(Stuff.PI)
// ## Everything is an object (Any, Nothing, null)
println(implicitly[B <:< A])
println(implicitly[Int <:< Any])
println(implicitly[Bla <:< Any])
println(implicitly[Nothing <:< Int])
// `null` still exists (has type `Null`), but only works for
// subtypes of `AnyRef`. It should be avoided as a relict of the JVM.
// # Values
// As we have seen, `val` is used for constants (can only be set once).
// `val`s are like fields in Java, they are initialized once at construction.
// (There is also `var` for mutable variables, but that is not needed here)
// Scala has local type inference, ie., types don't have to be written down, usually:
val t = "bla"
// But they can be annotated:
val t2: String = "bla"
// # `def` and functions
// Methods can be defined using `def`, with types ascribed using colons.
// Note the equals sign!
def fact(n: Int): Int = if (n == 0) 1 else n * fact(n - 1)
// There is no need for `return` -- we just deal with pure expressions!
// As you can see, `if`s are also expressions.
// We can use blocks (with braces), too -- but they are also just expressions:
val x = {
println("hi")
3
}
println(x == 3)
def fact2(n: Int): Int = {
if (n == 0) {
1
} else {
val previous = fact(n - 1)
n * previous
}
}
println(fact(10))
// Of course, stuff can be nested:
def makeAdder(a: Int): Int => Int = {
def addA(b: Int): Int = a + b
return addA
}
val addFour = makeAdder(4)
println(addFour(6))
// This also holds for most other sensible combinations of classes,
// methods, and objects.
// ## Difference between `val` and `def`:
// Speaking in Java terms, `val` corresponds to a field of a class, which
// is initialized at construction, or a local variable.
// `def`, on the other hand, at class level creates a class method, even
// if we leave out the method parameters (then we get something like a
// getter).
class C {
val x = {
println("x")
10
}
def y = {
println("y")
10
}
}
println("creating c")
val c = new C()
println("getting x")
println(c.x)
println("getting x again")
println(c.x)
println("getting y")
println(c.y)
println("getting y again")
println(c.y)
// We can also do the opposite thing, and assign a function object to
// a `val`:
val successor: Int => Int = n => n + 1
println(successor(10))
// The difference is that a `def` is a class method at JVM level,
// while `successor` is a member of a function object type,
// `Function1[Int, Int]`, for which // the notation `Int => Int` is just
// syntactic sugar.
// Methods are easily convertible into function objects.
// While we are at syntactic sugar: methods can have (almost) arbitrary
// operator names:
case class Blub(m: Int) {
def +++(b: Blub): List[Blub] = {
val Blub(n) = b
List(Blub(m), Blub(n), Blub(m + n))
}
}
println(Blub(1) +++ Blub(2))
// equal to
println(Blub(1).+++(Blub(2)))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment