Deprecated: Creation of dynamic property wpdb::$categories is deprecated in /var/www/twodee/blog/wp-includes/wp-db.php on line 668

Deprecated: Creation of dynamic property wpdb::$post2cat is deprecated in /var/www/twodee/blog/wp-includes/wp-db.php on line 668

Deprecated: Creation of dynamic property wpdb::$link2cat is deprecated in /var/www/twodee/blog/wp-includes/wp-db.php on line 668

Deprecated: Return type of WP_Theme::offsetExists($offset) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-theme.php on line 554

Deprecated: Return type of WP_Theme::offsetGet($offset) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-theme.php on line 595

Deprecated: Return type of WP_Theme::offsetSet($offset, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-theme.php on line 535

Deprecated: Return type of WP_Theme::offsetUnset($offset) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-theme.php on line 544

Deprecated: Return type of WP_REST_Request::offsetExists($offset) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/rest-api/class-wp-rest-request.php on line 960

Deprecated: Return type of WP_REST_Request::offsetGet($offset) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/rest-api/class-wp-rest-request.php on line 980

Deprecated: Return type of WP_REST_Request::offsetSet($offset, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/rest-api/class-wp-rest-request.php on line 992

Deprecated: Return type of WP_REST_Request::offsetUnset($offset) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/rest-api/class-wp-rest-request.php on line 1003

Deprecated: Return type of WP_Block_List::current() should either be compatible with Iterator::current(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 151

Deprecated: Return type of WP_Block_List::next() should either be compatible with Iterator::next(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 175

Deprecated: Return type of WP_Block_List::key() should either be compatible with Iterator::key(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 164

Deprecated: Return type of WP_Block_List::valid() should either be compatible with Iterator::valid(): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 186

Deprecated: Return type of WP_Block_List::rewind() should either be compatible with Iterator::rewind(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 138

Deprecated: Return type of WP_Block_List::offsetExists($index) should either be compatible with ArrayAccess::offsetExists(mixed $offset): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 75

Deprecated: Return type of WP_Block_List::offsetGet($index) should either be compatible with ArrayAccess::offsetGet(mixed $offset): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 89

Deprecated: Return type of WP_Block_List::offsetSet($index, $value) should either be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 110

Deprecated: Return type of WP_Block_List::offsetUnset($index) should either be compatible with ArrayAccess::offsetUnset(mixed $offset): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 127

Deprecated: Return type of WP_Block_List::count() should either be compatible with Countable::count(): int, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /var/www/twodee/blog/wp-includes/class-wp-block-list.php on line 199

Deprecated: Creation of dynamic property Automattic\Jetpack\Connection\Manager::$error_handler is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/vendor/automattic/jetpack-connection/src/class-manager.php on line 91

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Instagram_Gallery::$is_wpcom is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-instagram-gallery.php on line 23

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Mailchimp::$wpcom_is_wpcom_only_endpoint is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-mailchimp.php on line 17

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Tweetstorm_Gather::$wpcom_is_wpcom_only_endpoint is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-tweetstorm-gather.php on line 21

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Tweetstorm_Gather::$is_wpcom is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-tweetstorm-gather.php on line 22

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Gutenberg_Available_Extensions::$wpcom_is_site_specific_endpoint is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/gutenberg-available-extensions.php on line 20

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Memberships::$wpcom_is_wpcom_only_endpoint is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/memberships.php on line 23

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Memberships::$wpcom_is_site_specific_endpoint is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/memberships.php on line 24

Deprecated: Creation of dynamic property WPCOM_REST_API_V2_Endpoint_Subscribers::$wpcom_is_wpcom_only_endpoint is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/subscribers.php on line 15

Deprecated: Creation of dynamic property Automattic\Jetpack\Sync\Queue::$random_int is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/vendor/automattic/jetpack-sync/src/class-queue.php on line 38

Deprecated: Creation of dynamic property Automattic\Jetpack\Sync\Queue::$random_int is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/vendor/automattic/jetpack-sync/src/class-queue.php on line 38

Deprecated: Creation of dynamic property WPCOM_Widget_Goodreads::$shelves is deprecated in /var/www/twodee/blog/wp-content/plugins/jetpack/modules/widgets/goodreads.php on line 33

Deprecated: DateTime::__construct(): Passing null to parameter #1 ($datetime) of type string is deprecated in /var/www/twodee/blog/wp-includes/script-loader.php on line 348

Deprecated: Creation of dynamic property Advanced_Editor_Tools::$toolbar_classic_block is deprecated in /var/www/twodee/blog/wp-content/plugins/tinymce-advanced/tinymce-advanced.php on line 347

Deprecated: Creation of dynamic property Advanced_Editor_Tools::$toolbar_block is deprecated in /var/www/twodee/blog/wp-content/plugins/tinymce-advanced/tinymce-advanced.php on line 349

Deprecated: Creation of dynamic property Advanced_Editor_Tools::$toolbar_block_side is deprecated in /var/www/twodee/blog/wp-content/plugins/tinymce-advanced/tinymce-advanced.php on line 350

Deprecated: Creation of dynamic property Advanced_Editor_Tools::$panels_block is deprecated in /var/www/twodee/blog/wp-content/plugins/tinymce-advanced/tinymce-advanced.php on line 351

Deprecated: Creation of dynamic property Advanced_Editor_Tools::$used_block_buttons is deprecated in /var/www/twodee/blog/wp-content/plugins/tinymce-advanced/tinymce-advanced.php on line 354

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /var/www/twodee/blog/wp-includes/class-wp-block-type.php on line 333

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /var/www/twodee/blog/wp-includes/class-wp-block-type.php on line 333

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /var/www/twodee/blog/wp-includes/class-wp-block-type.php on line 333

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /var/www/twodee/blog/wp-includes/class-wp-block-type.php on line 333

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /var/www/twodee/blog/wp-includes/class-wp-block-type.php on line 333

Deprecated: Creation of dynamic property WP_Block_Type::$plan_check is deprecated in /var/www/twodee/blog/wp-includes/class-wp-block-type.php on line 333

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198

Deprecated: Creation of dynamic property WP_Term::$object_id is deprecated in /var/www/twodee/blog/wp-includes/class-wp-term.php on line 198
» SENG 440: Lecture 2 – Conditionals, Functions, and Classes

teaching machines

SENG 440: Lecture 2 – Conditionals, Functions, and Classes

February 20, 2019 by . Filed under
Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383

Deprecated: Creation of dynamic property WP_Term::$cat_ID is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 378

Deprecated: Creation of dynamic property WP_Term::$category_count is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 379

Deprecated: Creation of dynamic property WP_Term::$category_description is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 380

Deprecated: Creation of dynamic property WP_Term::$cat_name is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 381

Deprecated: Creation of dynamic property WP_Term::$category_nicename is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 382

Deprecated: Creation of dynamic property WP_Term::$category_parent is deprecated in /var/www/twodee/blog/wp-includes/category.php on line 383
lectures, semester1-2019, seng440.

Dear students,

Last time we introduced Kotlin as our tool for developing Android apps this semester. This time we continue that discussion but raise the complexity a couple of notches. We’ll look at conditional statements to choose between values and code, functions and classes to manage complexity, and lambdas to pass code around to other code.

Before we forget, here’s your TODO list for next time:

One more thing. Why do want to learn about mobile computing? What’s a goal you are aiming to reach with the opportunities that this class presents?

Here’s my goal: I want to be able to make apps that help me or my children grow, learn, and create in the “small” minutes of the day.

Conditional Statements

Conditional statements in Kotlin look very much like Java’s:

if (conditionA) {
  // A
} else if (conditionB) {
  // B
} else {
  // C
}

However, conditional statements are actually conditional expressions. They can yield a value and be embedded any place a value is expected: on the right-hand side of variable assignment or as an actual parameter in a function call. For example:

val direction = if (Random.nextBoolean()) {
  "L"
} else {
  "R"
}
println(direction)

For single-statement blocks, we can eliminate the braces and see that if statements are a lot like the ternary operators we’ve seen in other languages:

println(if (Random.nextBoolean()) "L" else "R")

The blocks can have multiple statements. The value that the if yields to its context comes from the last statement only. For example, we could add some counters to examine the fairness of random direction generator:

var nLefts = 0
var nRights = 0

for (value in 1..100) {
  val direction = if (Random.nextBoolean()) {
    ++nLefts
    "L"
  } else {
    ++nRights
    "R"
  }
  println(direction)
}

println(nLefts)
println(nRights)

When we get more than two conditions in our conditional statements, the syntax-to-logic ratio boils over to unhealthy levels. Kotlin’s solution is the when statement, which comes in two forms. The first behaves much like a switch statement that doesn’t need breaks to prevent fall-through. Let’s try this out to determine what animal represents this year in the Chinese zodiac:

val zodiac = when (year % 12) {
  0 -> "Monkey"
  1 -> "Rooster"
  2 -> "Dog"
  3 -> "Pig"
  else -> "Quokka"
}

For this particular example, an array would probably be a better choice. But we can do things with when that arrays can’t do so easily, like combine cases:

val nDays = when (month) {
  1, 3, 5, 7, 8, 10, 12, -> 31
  2 -> 28
  else -> 30
}

Or check ranges:

val generation = when (year) {
  in 1981..1996 -> "Millenial"
  in 1946..1964 -> "Baby Boomer"
  else -> "?"
}

The second form is a generalization of an if ladder, allowing arbitrary boolean expresssions for each case.

val quadrant = when {
  x > 0 && y > 0 -> "I"
  x < 0 && y > 0 -> "II"
  x < 0 && y < 0 -> "III"
  x > 0 && y < 0 -> "IV"
  else -> "None"
}

Functions

Functions in Kotlin have this general structure:

fun name(param1: Type, param2: Type, ...): ReturnType {
  // body
}

We’ll be writing a lot of functions in this class, so let’s ground ourselves in this structure with an exercise:

Write a function getRingArea that computes the area of the shaded region—which is called an annulus. What parameters do you need? What kind of return value? How do you compute it?

Function definitions can be shortened sometimes. If the function doesn’t return a value, its return type can be omitted. (We say that the function returns Unit, which is like void in other languages.) If a function has a body that is a single expression, we can replace braces with =, omit the return type, and omit the return keyword. For example:

fun roll2d6() = Random.nextInt(6) + Random.nextInt(6) + 2

Classes

When writing a new class in most object-oriented programming languages, we have three things to think about:

We’ll find that Kotlin makes some of these tasks much simpler than their Java counterparts.

Basic Kotlin classes have this form:

class Model(param1: Type, ...) {
  val prop1: Float = ... // read-only property
  var prop2: String = ... // read-write property

  fun method(...) {
    ...
  }
}

Based on this structure, let’s model a Point together. Let’s start with just the state:

class Point(x: Float, y: Float) {
  var x: Float = x
  var y: Float = y
}

If this were Java, we would have written this:

class Point {
  private float x;
  private float y;

  public Point(float x, float y) {
    this.x = x;
    this.y = y;
  }
}

In Kotlin, we tend not write constructors. Instead, we do direct assignments at the time we declare instance variables. If the initialization requires some extra computation like a loop, we’ll use an init block, which we’ll discuss as the need arises.

The Java constructor feels really redundant. But the Kotlin version also has some awkwardness with name shadowing. But good news! JetBrains recognized how often we turn constructor parameters into instance variables, and they decided to coalesce the parameters, instance variable declarations, and initializations into an easier syntax. We just move the val or var onto the parameter declaration:

class Point(var x: Float, var y: Float) {
}

Let’s test it with a main. To construct an object, we simply invoke the class name as if it were a function. We do not use the keyword new:

fun main(args: Array<String>) {
  val p = Point(3, 4)
  println(p)
}

Does this work? No. Just as in Java, this implicitly calls the toString method of the superclass Any, which yields the class name and hashcode. Let’s override the toString method:

class Point(var x: Float, var y: Float) {
  override fun toString = "($x, $y)"
}

We will about inheritance and properties later.

Lambdas

While we lived under the hysteria of object-oriented programming, we believed that everything had to be an object. To respond to mouse clicks, you had to create a mouse listener object. To influence sorting criteria, you had to create a comparator object. Thankfully these days are behind us. Our modern languages allow us to pass functions around with first having to wrap them in an object. We don’t have to even name the function. Such function literals are called lambdas.

Functions have this syntactical structure:

fun name(param1: Type, param2: Type, ...): ReturnType {
  body
}

And lambdas have this syntactical structure:

{ param1: Type, param2: Type2 ->
  body
}

The return type is inferred from the last statement of body. And usually the parameter types can be inferred as well, so we are more likely to write this:

{ param1, param2 ->
  body
}

Suppose we want to print every element of an array. We could use Array.forEach and pass it a lambda like so:

val xs = intArrayOf(1, 2, 3, 4, 5, 6, 7)
xs.forEach({ x -> println(x) })

We can improve the syntax. If the lambda is the last parameter, we can move it outside the parentheses:

xs.forEach() { x -> println(x) }

And if the lambda is the only parameter, we can omit the parentheses entirely:

xs.forEach { x -> println(x) }

Now let’s solve some problems together using lambdas:

That’s enough for today. See you next time!

Sincerely,

P.S. It’s time for a haiku!

Old seems right to us Till New comes and gives us choice Then they both seem wrong