summaryrefslogtreecommitdiffhomepage
path: root/scala.html.markdown
blob: 8bcb59751f6134e37e46a89284fc91e308862900 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
---
language: Scala
contributors:
    - ["George Petrov", "http://github.com/petrovg"]
filename: learn.scala
---

Scala - the scalable language

```c



/*
  Set yourself up:

  1) Download Scala - http://www.scala-lang.org/downloads
  2) unzip/untar in your favourite location and put the bin subdir on the path
  3) Start a scala REPL by typing scala. You should see the prompt:

  scala>

  This is the so called REPL. You can run commands in the REPL. Let's do just that:
*/

println(10) // prints the integer 10

println("Boo!") // printlns the string Boo!


// Evaluating a command gives you the type and value of the result

1 + 7

/* The above line results in:

  scala> 1 + 7
  res29: Int = 8

  This means the result of evaluating 1 + 7 is an object of type Int with a value of 8

  1+7 will give you the same result
*/


// Everything is an object, including a function. Type these in the REPL:

7 // results in res30: Int = 7 (res30 is just a generated var name for the result)

// The next line gives you a function that takes an Int and returns it squared
(x:Int) => x * x    

// You can assign this function to an identifier, like this:
val sq = (x:Int) => x * x

/* The above says this
   
   sq: Int => Int = <function1>	

   Which means that this time we gave an explicit name to the value - sq is a function that take an Int and returns Int.

   sq can be executed as follows:
*/

sq(10)   // Gives you this: res33: Int = 100. The result is the Int with a value 100



// Data structures

val a = Array(1, 2, 3, 5, 8, 13)
a(0)
a(3)
a(21)    // Throws an exception

val m = Map("fork" -> "tenedor", "spoon" -> "cuchara", "knife" -> "cuchillo")
m("fork")
m("spoon")
m("bottle")       // Throws an exception

val safeM = m.withDefaultValue("no lo se")
safeM("bottle")

val s = Set(1, 3, 7)
s(0)
s(1)

/* Look up the documentation of map here - http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map 
 * and make sure you can read it
 */


// Tuples

(1, 2)

(4, 3, 2)

(1, 2, "three")

(a, 2, "three")

// Why have this?
val divideInts = (x:Int, y:Int) => (x / y, x % y)

divideInts(10,3) // The function divideInts gives you the result and the remainder

// To access the elements of a tuple, use _._n where n is the 1-based index of the element
val d = divideInts(10,3)

d._1

d._2



// Combinators

s.map(sq)

val sSquared = s. map(sq)

sSquared.filter(_ < 10)

sSquared.reduce (_+_)


// For comprehensions

for { n <- s } yield sq(n)

val nSquared2 = for { n <- s } yield sq(n)

for { n <- nSquared2 if n < 10 } yield n

for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared

/* NB Those were not for loops. The semantics of a for loop is 'repeat', whereas a for-comprehension
   defines a relationship between two sets of data. Research this further  */



// Loops and iteration

1 to 5
val r = 1 to 5
r.foreach( println )

r foreach println     
// NB: Scala is quite lenien when it comes to dots and brackets - study the rules separately. This 
// helps write DSLs and APIs that read like English

(5 to 1 by -1) foreach ( println )

var i = 0
while (i < 10) {  println("i " + i); i+=1  }

while (i < 10) {  println("i " + i); i+=1  }   // Yes, again. What happened? Why?

i    // Show the value of i. Note that while is a loop in the classical sense - it executes
     // sequentially while changing the loop variable. while is very fast, faster that Java
     // loops, but using the combinators and comprehensions above is easier to understand
     // and parallelize

// Tail recursion is an idiomatic way of doing things in Scala. Recursive functions need an 
// explicit return type, the compile can't infer it. Here it's Unit.
def showNumbersInRange(a:Int, b:Int):Unit = { print(a); if (a < b) showNumbersInRange(a+1, b)  }



// Conditionals

val x = 10

if (x == 1) println("yeah")
if (x == 10) println("yeah")
if (x == 11) println("yeah")
if (x == 11) println ("yeah") else println("nope")

println(if (x == 10) "yeah" else "nope")
val text = if (x == 10) "yeah" else "nope"

var i = 0
while (i < 10) { println("i " + i); i+=1  }

// Object oriented features



// Case classes

case class Person(name:String, phoneNumber:String)

Person("George", "1234") == Person("Kate", "1236")




// Pattern matching

val me = Person("George", "1234")

me match { case Person(name, number) => "We matched someone : " + name + ", phone : " + number }

me match { case Person(name, number) => "Match : " + name; case _ => "Hm..." }

me match { case Person("George", number) => "Match"; case _ => "Hm..." }

me match { case Person("Kate", number) => "Match"; case _ => "Hm..." }

me match { case Person("Kate", _) => "Girl"; case Person("George", _) => "Boy" }

val kate = Person("Kate", "1234")

kate match { case Person("Kate", _) => "Girl"; case Person("George", _) => "Boy" }



// Regular expressions

val email = "(.*)@(.*)".r          // The suffix .r invokes method r on String, which makes it a Regex

val email(user, domain) = "henry@zkpr.com"

"mrbean@pyahoo.com" match {
  case email(name, domain) => "I know your name, " + name
}



// Strings

println("ABCDEF".length)
println("ABCDEF".substring(2, 6))
println("ABCDEF".replace("C", "3"))

val n = 45
println(s"We have $n apples")

val a = Array(11, 9, 6)
println(s"My second daughter is ${a(2-1)} years old")

// Some characters need to be 'escaped', e.g. a double quote inside a string:
val a = "They stood outside the \"Rose and Crown\""

// Triple double-quotes allow for strings to span multiple rows and contain funny characters
val html = """<form id="daform">
                <p>Press belo', Joe</p>
             |  <input type="submit">
              </form>"""


// Input and output


```

## Further resources

[Scala for the impatient](http://horstmann.com/scala/)

[Twitter Scala school(http://twitter.github.io/scala_school/)

[The scala documentation]

Join the [Scala user group](https://groups.google.com/forum/#!forum/scala-user)