1 of 46

1

Lesson 2: Functions

This work is licensed under the Apache 2 license.

Android Development with Kotlin v1.0

This work is licensed under the Apache 2 license.

2 of 46

About this lesson

Lesson 2: Functions

2

Android Development with Kotlin

This work is licensed under the Apache 2 license.

3 of 46

Programs in Kotlin

3

Android Development with Kotlin

This work is licensed under the Apache 2 license.

4 of 46

Setting up

  • Create a file in your project
  • Create a main() function
  • Pass arguments to main()(Optional)
  • Use any passed arguments in function calls (Optional)
  • Run your program

4

Before you can write code and run programs, you need to:

Android Development with Kotlin

This work is licensed under the Apache 2 license.

5 of 46

Create a new Kotlin file

In IntelliJ IDEA's Project pane, under Hello World, right-click the src folder.

  • Select New > Kotlin File/Class.
  • Select File, name the file Hello, and press Enter.

5

Android Development with Kotlin

This work is licensed under the Apache 2 license.

6 of 46

Create a Kotlin file

You should now see a file in the src folder called Hello.kt.

6

Android Development with Kotlin

This work is licensed under the Apache 2 license.

7 of 46

Create a main() function

In the Hello.kt file:

fun main(args: Array<String>) {

println("Hello, world!")

}

7

The args in the main() function are optional.

main() is the entry point for execution for a Kotlin program.

Android Development with Kotlin

This work is licensed under the Apache 2 license.

8 of 46

Run your Kotlin program

To run your program, click the Run icon ( ) to the left of the main() function.

IntelliJ IDEA runs the program, and displays the results in the console.

8

Android Development with Kotlin

This work is licensed under the Apache 2 license.

9 of 46

Pass arguments to main()

Select Run > Edit Configurations to open the Run/Debug Configurations window.

9

Android Development with Kotlin

This work is licensed under the Apache 2 license.

10 of 46

Use arguments in main()

Use args[0] to access the first input argument passed to main().

10

fun main(args: Array<String>) {

println("Hello, ${args[0]}")

}

⇒ Hello, Kotlin!

Android Development with Kotlin

This work is licensed under the Apache 2 license.

11 of 46

(Almost) Everything has a value

11

Android Development with Kotlin

This work is licensed under the Apache 2 license.

12 of 46

(Almost) Everything is an expression

12

val temperature = 20

val isHot = if (temperature > 40) true else false

println(isHot)

⇒ false

In Kotlin, almost everything is an expression and has a value. Even an if expression has a value.

Android Development with Kotlin

This work is licensed under the Apache 2 license.

13 of 46

Expression values

Sometimes, that value is kotlin.Unit.

13

⇒ This is an expression

kotlin.Unit

val isUnit = println("This is an expression")

println(isUnit)

Android Development with Kotlin

This work is licensed under the Apache 2 license.

14 of 46

Functions in Kotlin

14

Android Development with Kotlin

This work is licensed under the Apache 2 license.

15 of 46

About functions

  • A block of code that performs a specific task

15

  • Breaks a large program into smaller modular chunks

  • Declared using the fun keyword
  • Can take arguments with either named or default values

Android Development with Kotlin

This work is licensed under the Apache 2 license.

16 of 46

Parts of a function

Earlier, you created a simple function that printed "Hello World".

16

fun printHello() {

println("Hello World")

}

printHello()

Android Development with Kotlin

This work is licensed under the Apache 2 license.

17 of 46

Unit returning functions

If a function does not return any useful value, its return type is Unit.

17

fun printHello(name: String?): Unit {

println("Hi there!")

}

Unit is a type with only one value: Unit.

Android Development with Kotlin

This work is licensed under the Apache 2 license.

18 of 46

Unit returning functions

18

The Unit return type declaration is optional.

fun printHello(name: String?) {

println("Hi there!")

}

fun printHello(name: String?): Unit {

println("Hi there!")

}

is equivalent to:

Android Development with Kotlin

This work is licensed under the Apache 2 license.

19 of 46

Function arguments

  • Default parameters
  • Required parameters
  • Named arguments

19

Functions may have:

Android Development with Kotlin

This work is licensed under the Apache 2 license.

20 of 46

Default parameters

fun drive(speed: String = "fast") {

println("driving $speed")

}

20

Default values provide a fallback if no parameter value is passed.

drive() ⇒ driving fast

drive("slow") driving slow

drive(speed = "turtle-like") ⇒ driving turtle-like

Use "=" after the type

to define default values

Android Development with Kotlin

This work is licensed under the Apache 2 license.

21 of 46

Required parameters

If no default is specified for a parameter, the corresponding argument is required.

21

fun tempToday(day: String, temp: Int) {

println("Today is $day and it's $temp degrees.")

}

Required parameters

Android Development with Kotlin

This work is licensed under the Apache 2 license.

22 of 46

Default versus required parameters

Functions can have a mix of default and required parameters.

Pass in required arguments.

22

fun reformat(str: String,

divideByCamelHumps: Boolean,

wordSeparator: Char,

normalizeCase: Boolean = true){

Has default value

reformat("Today is a day like no other day", false, '_')

Android Development with Kotlin

This work is licensed under the Apache 2 license.

23 of 46

Named arguments

To improve readability, use named arguments for required arguments.

reformat(str, divideByCamelHumps = false, wordSeparator = '_')

23

It's considered good style to put default arguments after positional arguments, that way callers only have to specify the required arguments.

Android Development with Kotlin

This work is licensed under the Apache 2 license.

24 of 46

Compact functions

24

Android Development with Kotlin

This work is licensed under the Apache 2 license.

25 of 46

Single-expression functions

Compact functions, or single-expression functions, make your code more concise and readable.

25

fun double(x: Int): Int {

x * 2

}

fun double(x: Int):Int = x * 2

Complete version

Compact version

Android Development with Kotlin

This work is licensed under the Apache 2 license.

26 of 46

Lambdas and higher-order functions

26

Android Development with Kotlin

This work is licensed under the Apache 2 license.

27 of 46

Kotlin functions are first-class

27

  • Kotlin functions can be stored in variables and data structures
  • They can be passed as arguments to, and returned from, other higher-order functions
  • You can use higher-order functions to create new "built-in" functions

Android Development with Kotlin

This work is licensed under the Apache 2 license.

28 of 46

Lambda functions

var dirtLevel = 20

val waterFilter = {level: Int -> level / 2}

println(waterFilter(dirtLevel))

⇒ 10

28

A lambda is an expression that makes a function that has no name.

Function arrow

Code to execute

Parameter and type

Android Development with Kotlin

This work is licensed under the Apache 2 license.

29 of 46

Syntax for function types

val waterFilter: (Int) -> Int = {level -> level / 2}

29

Kotlin's syntax for function types is closely related to its syntax for lambdas. Declare a variable that holds a function.

Data type of variable

(function type)

Variable name

Function

Android Development with Kotlin

This work is licensed under the Apache 2 license.

30 of 46

Higher-order functions

Higher-order functions take functions as parameters, or return a function.

30

fun encodeMsg(msg: String, encode: (String) -> String): String {​

return encode(msg)

}

The body of the code calls the function that was passed as the second argument, and passes the first argument along to it.

Android Development with Kotlin

This work is licensed under the Apache 2 license.

31 of 46

Higher-order functions

To call this function, pass it a string and a function.

31

val enc1: (String) -> String = { input -> input.toUpperCase() }

println(encodeMsg("abc", enc1))

Using a function type separates its implementation from its usage.

Android Development with Kotlin

This work is licensed under the Apache 2 license.

32 of 46

Passing a function reference

Use the :: operator to pass a named function as an argument to another function.

32

fun enc2(input:String): String = input.reversed()

The :: operator lets Kotlin know that you are passing the function reference as an argument, and not trying to call the function.

encodeMessage("abc", ::enc2)

Passing a named function,

not a lambda

Android Development with Kotlin

This work is licensed under the Apache 2 license.

33 of 46

Last parameter call syntax

Kotlin prefers that any parameter that takes a function is the last parameter.

33

encodeMessage("acronym", { input -> input.toUpperCase() })

You can pass a lambda as a function parameter without putting it inside the parentheses.

encodeMsg("acronym") { input -> input.toUpperCase() }

Android Development with Kotlin

This work is licensed under the Apache 2 license.

34 of 46

Using higher-order functions

Many Kotlin built-in functions are defined using last parameter call syntax.

34

inline fun repeat(times: Int, action: (Int) -> Unit)

repeat(3) {

println("Hello")

}

Android Development with Kotlin

This work is licensed under the Apache 2 license.

35 of 46

List filters

35

Android Development with Kotlin

This work is licensed under the Apache 2 license.

36 of 46

List filters

36

Get part of a list based on some condition

red

red-orange

dark red

orange

bright orange

saffron

red

red-orange

dark red

Apply filter() on list

Condition: element contains “red”

Android Development with Kotlin

This work is licensed under the Apache 2 license.

37 of 46

Iterating through lists

If a function literal has only one parameter, you can omit its declaration and the "->". The parameter is implicitly declared under the name it.

37

val ints = listOf(1, 2, 3)

ints.filter { it > 0 }

ints.filter { n -> n > 0 }

ints.filter { n: Int -> n > 0 }

OR

Filter iterates through a collection, where it is the value of the element during the iteration. This is equivalent to:

Android Development with Kotlin

This work is licensed under the Apache 2 license.

38 of 46

List filters

val books = listOf("nature", "biology", "birds")

println(books.filter { it[0] == 'b' })

38

⇒ [biology, birds]

The filter condition in curly braces {} tests each item as the filter loops through. If the expression returns true, the item is included.

Android Development with Kotlin

This work is licensed under the Apache 2 license.

39 of 46

Eager and lazy filters

  • Lazy: occurs only if necessary at runtime

39

  • Eager: occurs regardless of whether the result is ever used

Lazy evaluation of lists is useful if you don't need the entire result, or if the list is exceptionally large and multiple copies wouldn't wouldn't fit into RAM.

Evaluation of expressions in lists:

Android Development with Kotlin

This work is licensed under the Apache 2 license.

40 of 46

Eager filters

Filters are eager by default. A new list is created each time you use a filter.

40

val instruments = listOf("viola", "cello", "violin")

val eager = instruments.filter { it [0] == 'v' }

println("eager: " + eager)

⇒ eager: [viola, violin]

Android Development with Kotlin

This work is licensed under the Apache 2 license.

41 of 46

Lazy filters

Sequences are data structures that use lazy evaluation, and can be used with filters to make them lazy.

41

⇒ filtered: kotlin.sequences.FilteringSequence@386cc1c4

val instruments = listOf("viola", "cello", "violin")

val filtered = instruments.asSequence().filter { it[0] == 'v'}

println("filtered: " + filtered)

Android Development with Kotlin

This work is licensed under the Apache 2 license.

42 of 46

Sequences -> lists

Sequences can be turned back into lists using toList().

42

val newList = filtered.toList()

⇒ new list: [viola, violin]

val filtered = instruments.asSequence().filter { it[0] == 'v'}

println("new list: " + newList)

Android Development with Kotlin

This work is licensed under the Apache 2 license.

43 of 46

Other list transformations

val numbers = setOf(1, 2, 3)

println(numbers.map { it * 3 })

=> [3, 6, 9]

val numberSets = listOf(setOf(1, 2, 3), setOf(4, 5), setOf(1, 2))�println(numberSets.flatten())

=> [1, 2, 3, 4, 5, 1, 2]

43

  • map() performs the same transform on every item and returns the list.
  • flatten() returns a single list of all the elements of nested collections.

Android Development with Kotlin

This work is licensed under the Apache 2 license.

44 of 46

Summary

44

Android Development with Kotlin

This work is licensed under the Apache 2 license.

45 of 46

Summary

45

In Lesson 2, you learned how to:

Android Development with Kotlin

This work is licensed under the Apache 2 license.

46 of 46

Pathway

Practice what you’ve learned by�completing the pathway:

Lesson 2: Functions

46

Android Development with Kotlin

This work is licensed under the Apache 2 license.