# Conditional Expressions

• An `if` expression has a value:
`if (x > 0) 1 else -1`
Like `x > 0 ? 1 : -1` in Java/C/C++.
• Type is the common supertype of the branches:
`if (x > 0) "positive" else -1 // Type is Any`
• Scala `Unit` type is similar to `void`, but it has one value, denoted `()`.
• Missing `else` has value `Unit`:
`if (x > 0) 1`
is the same as
`if (x > 0) 1 else ()`

# Block Expressions

• Value of block is the value of the last expression:
```val distance = {
val dx = x - x0
val dy = y - y0
sqrt(dx * dx + dy * dy)
}```
• If the last expression is an assignment, the block value is `()`:
```while (n > 0) {
i += 1
n = n / 2
}```

# For Loops

• No three-part loop `for (i = 1; i <= n; i++)`.
• Use “for each” loop instead:
```for (i <- 1 to n)
```
(Note: No `val`/`var` before `i`)
• Works for any collection:
`for (ch <- "Hello"`
• Multiple “generators”:
`for (i <- 1 to 3; j <- 1 to 3) print((10 * i + j) + " ")`
• Guards:
`for (i <- 1 to 3; j <- 1 to 3 if i != j) print((10 * i + j) + " ")`
• Collecting results:
`for (i <- 1 to 10) yield i % 3`

# Functions

• To define a function, specify name, parameters, body:
`def abs(x: Double) = if (x >= 0) x else -x`
• Return type is inferred unless the function is recursive:
`def fac(n: Int): Int = if (n <= 0) 1 else n * fac(n - 1)`
• If you omit the `=`, the function doesn't return a value:
```def box(s: String) { // Look carefully: no =
val border = "-" * s.length + "--\n"
println(border + "|" + s + "|\n" + border)
}```
• Caution—easy to accidentally omit the `=` symbol:
```def fac(n: Int) { // Probably an error
var r = 1
for (i <- 1 to n) r = r * i
r
}```

# Named and Default Arguments

• “Named” argument is useful for greater clarity:
`regionMatches(`ignoreCase = `true, ...)`
• Default arguments let you omit argument values:
```def decorate(str: String, left: String = "[", right: String = "]") =
left + str + right```
• Here, defaults are used for both `left` and `right`:
`decorate("Hello") // [Hello]`
• Default is only used for `right`:
`decorate("Hello", ">>>[") // >>>[Hello]`
• Default is only used for `left`, named parameter for `right`:
`decorate("Hello", right = "]<<<") // [Hello]<<<`

# Varargs

• Variable number of arguments indicated with `*` after type:
```def sum(args: Int*) = { // args is a Seq[Int]
var result = 0
for (arg <- args) result += arg
result
}```
• Can call with any number of arguments:
`val s = sum(1, 4, 9, 16, 25)`
• If you already have a `Seq[Int]`, need decoration to pass it:
```val s = sum(1 to 5: _*)
```
• Needed in recursive calls:
```def recursiveSum(args: Int*): Int = {
if (args.length == 0) 0
else args.head + recursiveSum(args.tail : _*)
}```

# Vowels

1. Write a function that tests whether a character is a vowel (for now, a lowercase `aeiou`).
`def isVowel(ch: Char) = ...`
2. Did you use an `if` statement? If so, write it without an `if`. (Hint: `contains`)
3. Write a function that, given a string, returns a string of all of its vowels. Use `isVowel`. Use a `for` loop.
```def vowels(s: String) = ...
```
4. Repeat with a `for ... yield` loop. (Hint: Guards)
5. Repeat with a recursive solution.
6. Repeat with a `while` loop.
7. Pick your favorite version. Add a parameter `vowelChars` with default `"aeiuo"` and a parameter `ignoreCase` with default `true`.
8. Call it to find all vowels in the German word `"Übeltätergehör"`. (Yes, those things with dots are vowels in German.)