01. Basics - RobertMakyla/scalaWiki GitHub Wiki

Console uses read-eval-print loop (REPL) Scala is 'the REPL' working on JVM

Ctrl + Enter : evaluates scala console

Value (constant)

val two = 1 + 1    // In scala you are ENCOURAGED to use VALUES
val four = two * 2
four = 0           // error : reassignment to val
val four = 0       // OK    : it's a new value

Variable (can be reassigned)

var i = 0             // In scala you are discouraged to use VARIABLES
i = i + 1

Semicolons (;) are required only if you have many statement in one line There's no need to specify type of var/val. But when re-assigning var, the type must be the same (otherwise: i="no more 1" --> error: type mismatch)

It's an error to declare var/val without initializing it ( var/val myV --> error: '=' expected) If I want to, I can specify type:

val greeting: String = ???
val greeting: String = null
val greeting: Any = "Hello"
val myStrOne, myStrTwo: String = "Hello"
val myValOne, myValTwo: Any = "Hello"

There is no distinction between primitives and classes

1.toString   --> res0: java.lang.String = 1

Scala wraps it automatically (programmer doesn't have to do it)

Types

  • Byte - 8 bits
  • Short - 16 bytes ( - 2^15 -> 2^15 - 1 )
  • Char - 16 bytes ( 0 to 2^16 -1 )
  • Int - 32 bytes ( - 2^31 to 2^31 - 1 )
  • Long - 64 bytes

Converters

Scala converts all Strings or "anything" into StringOps objects :

"123".intersect("345") // "4"

Scala converts all Int/Double/Char into RichInt/RichDouble/RichChar objects. E.g. RichInt class :

1.to(10)  // Range (1,2,3,4,5,6,7,8,9,10)
1 to 10   // Range (1,2,3,4,5,6,7,8,9,10)

Digital/String converters - in Scala we use methods, not casts

99.44.toInt --> 99
99.toChar --> 'c'
"99.44".toDouble --> 99.44
"99.44".toInt --> java.lang.NumberFormatException

##Operators - in scala they are methods

1 + 2                    - is a shorthand for method 1.+(2)
2 * 2                    - is a shorthand for method 2.*(2)

(any symbol in method's name is accepted)

1 toString               - it's 1.toString or 1.toString   // "1"
1 toString()                                               // "1"
1.toString                                                 // "1"
1.toString()                                               // "1"

(The API dictates that StringOps.toString has parentheses, but since we don't provide any argument, we can skip it)

"hello" distinct         // "helo"
"hello".distinct         // "helo"
"hello" distinct()       // error: The API says that StringOps.distinct
"hello".distinct()       //        has no parentheses

###RULE OF THUMB : Parameterless methods that don't modify the objects, have no parentheses

"123" intersect "345"     //  "123".intersect("345")       (result: "3")
"" + 123 intersect "345"  //  (""+123).intersect("345")    (result: "3")

counter += 1             - instead of counter++, which does not exist in scala
counter -= 1             - instead of counter--, which does not exist in scala

##Scala over Java

val x: BigInt = 1234567890
x * x * x                - no need to  x.multiply(x).multiply(x)
x pow 3                  - no need to  x.pow(3)

Functions

pow(2,2)    // 4        - no need for: BigInteger.pow(2,2)
min(3, Pi)  // 3
"0123"(2)   // char '2'

All these functions are in scala.math package (import scala.math._ or import math._) Without such import I can still call: scala.math.power(2,2) or just math.pow(2,2)

##Singleton Objects

Scala does not not have static methods, but it has Singleton objects - discussed later

##Methods

The apply method - common Scala idiom for constructing objects. No need to use "new" keyword in Scala

"012345"(4)   - it's "012345".apply(4)
                     "012345" apply(4)
                     "012345" apply 4

              - StringOps API:  def apply(index: Int): Char
                Return element at index n

              - BigInt API:     def apply(x: String): BigInt
                Translates the decimal String into a BigInt.

Exercises:

 res - results are values, not variables, because if I try to reassign other value, I get error
 "hi"*3 --> "hihihi"   because StringOps API:   def *(n: Int): String
                                                Return the current string concatenated n times.

 scala.util.Random.nextInt(100)               --> random 0-99

 12345 : BigInt           --> res: BigInt = 12345        (In Java: (BigInteger) 12345)
 val myb : BigInt = 12345 --> myb: BigInt = 12345        (In Java: BigInteger myb = ...)

 "012345"(0)                   - it's like "012345" head or "012345".head
 "012345"("012345".length -1)  - it's like "012345" last or "012345".last

 "0123456789" head             -->   0
 "0123456789" tail             -->   123456789

 "0123456789" take 2           -->   01
 "0123456789" drop 2           -->   23456789

 "0123456789" takeRight 2      -->   89
 "0123456789" dropRight 2      -->   01234567