Archive for the ‘Kotlin’ Category

Erica Knows Nothing About Kotlin: Kotlin collections

Cocoa distinguishes NSArray from NSMutableArray, among many other mutable variations on standard types. In Swift, you var or let a collection and let the compiler handle the rest of the details, whether the outcome is mutable or not. Kotlin follows the Cocoa model. It uses distinct collection types based on mutability.

For example, the listOf function returns a new read-only serializable list of elements.

val myList: List<Double> = listOf(1.0, 2.0, 3.0)

You cannot automatically promote typeless literals the way you can in Swift. In Swift the literal “1” doesn’t have an intrinsic type (although it defaults to Int in the absence of any other context). “1” can represent an integer, a double, a float, and more.

Kotlin does not support literal inference. If you use listOf(1, 2, 3) for the preceding example, Kotlin issues an error: “Type inference failed. Expected type mismatch: inferred type is List<Int> but List<Double> was expected”.

Like Swift, Kotlin’s type inference system permits you to drop the explicit List<Double> type annotation from the myList declaration.  The listOf function still produces the expected type, which the compiler assigns to the constant myList. In this declaration, Kotlin’s val is the same as Swift’s let. It produces a constant rather than a (var) variable.

However, the list you produced is not a value type. Switch the list from immutable to mutable, and you’ll still (like an NSMutableArray reference) be able to add new members:

val myList: MutableList<Double> = mutableListOf(1.0, 2.0, 3.0)
myList.add(4.0)
println(myList) // [1.0, 2.0, 3.0, 4.0]

You won’t be able to re-assign myList to a new list, but as a mutable reference type, the underlying instance can be modified because it is a MutableList<T>.

Kotlin also offers dictionaries, which it calls maps. That’s really not a bad name for a type that performs one-to-one mapping, which is all that key-value lookup really does. The underlying types honor that key/value relation. They’re called Map<K, out V> and MutableMap<K, V>.

val myDictionary = mutableMapOf(
    "cow" to "moo",
    "dog" to "woof",
    "pig" to "oink"
)

println(myDictionary["dog"]) // woof
println(myDictionary["kitten"]) // null

Like Swift, Kotlin returns a “not there” result for a failed map lookup, but the meaning of null is distinct from Swift’s nil. A type must be nullable (sort of but not entirely like Optional) to store a null reference.

var string = "Hello"
println(string)
// string = null 
// error: null can not be a value of a non-null type String

var string2: String? = "Hello"
println(string2) // hello
string2 = null
println(string2) // null

The initial value of string2 is not Optional("hello") or something like that. It feels (at least so far, because I know nothing about Kotlin, see the title of this post) more like the Objective-C nil, that is a null-reference in memory rather than a pointer to a reference type. I’m new to this, so I’m still learning.

Speaking of null, the first string example demonstrates what happens when you assign null to a non-nullable type. You end up with a (more or less) null pointer exception, which is a bad thing.

Getting back to collections, Kotlin also supports sets, both mutable and immutable. All three types: lists (arrays), maps (dictionaries) and sets (sets), inherit from Kotlin Collection, and in turn from Kotlin Iterable. All three types have a way to count the number of elements (or entries), they can be iterated over, and Collection offers many methods that may or may not apply to each type. For example, you don’t use dropWhile on a map/dictionary.

The Collections reference page lists which functions apply to which types. It’s a bit hodgepodge compared to Swift’s cleaner, hierarchical, and protocol-based system. That said, all the things you would expect to do to an array, set, or dictionary in Swift, you can do to a list, set, or map in Kotlin. Have a browse through that Collections page to get a sense of the functionality. It’s all pretty familiar.

If anything, the various subtypes (LongArray, ByteArray, IntArray, etc) feel like overkill and the available functions feel a tiny bit bloated. But that’s me looking at this stuff with Swift-ized eyes.

If you like this series of posts, let me know. Drop a tweet, email, or comment if you’d like me to keep going.

Erica Knows Nothing About Kotlin: Kotlin functions

Yesterday, I got my feet wet creating a simple functional chain to calculate the sum of natural numbers that are multiples of 3 or 5 (thanks Jeff):

var result = (1 .. limit - 1)
    .asSequence()
    .filter { item -> item.divisibleBy(3) || item.divisibleBy(5) }
    .sum()

As you can see, Kotlin looks a lot like Swift. And, like any programming language, you can collect a routine into a function (fun rather than func in Kotlin, which makes Kotlin seem like a very “happy fun™” language) for re-use.

Instead of using a temporary result variable (var, just like in Swift, although let is val) and re-assigning it at each calculation, it’s more elegant to create a reusable component to call for each limit.

The simplest way is to build a function that mimics Swift. You declare fun, the function name, parameters, the return type (with a : token), and use the return keyword to establish the return value:

fun Int.divisibleBy(factor: Int) = this % factor == 0

fun euler1 (limit: Int) : Int {
    return (1 .. limit - 1)
        .asSequence()
        .filter { item -> item.divisibleBy(3) ||item.divisibleBy(5) }
        .sum()
}
println("The sum of these multiples is ${euler1(10)}")
println("The sum of these multiples is ${euler1(1000)}")

I also munged the calls directly into the print string using ${}. This is basically the same as using \() in Swift. The new  euler1 function is now almost indistinguishable from Swift.

Kotlin offers a bit more flexibility in its function declarations. You can skip the braces and use assignment to the compound expression, creating an inferred scope for short expressions:

fun euler1 (limit: Int) : Int = (1 .. limit - 1)
        .asSequence()
        .filter { item -> item.divisibleBy(3) ||item.divisibleBy(5) }
        .sum()

Same results, much streamlined declaration.

Like Swift, you can introduce defaulted arguments into your parameter list. This example can be called with zero or one arguments, allowing the printed phrase to default to “Hello World”.

fun greet(phrase: String = "Hello World") = println(phrase)
greet() // "Hello World"
greet("Hello Sailor") // "Hello Sailor"

You can also create functional closures/lambda expressions and assign them to variables, as you do in Swift. And, as in Swift, that closure can then be treated like a normal function:

var add : (Int, Int) -> Int = {item, increase -> item + increase }
println(add) // Function2<java.lang.Integer, java.lang.Integer, java.lang.Integer>
println(add(2, 3)) // 5

Finally, like Swift, you can create infix functionality, such as exponentiation. The first two examples use the infix form, the second two use a standard function call:

infix fun Int.exp(exponent: Int): Int {
    return (1 .. exponent)
        .asSequence().map { this }
        .fold(1) {current, base -> current * base }
}

println(5 exp 3) // 125
println(2 exp 8) // 256
println(5.exp(3)) // 125
println(2.exp(8)) // 256

Erica Knows Nothing About Kotlin: Installing and using Kotlin from Xcode

Andy Wilkinson wanted some useful tips for Kotlin in the style of my normal blog. I know nothing about Kotlin other than it’s vaguely Swifty and has a little too much Java in it for my decaf tastes. Nonetheless, I decided to oblige.

Here’s what I discovered.

Install Kotlin

Installation couldn’t be simpler. I used brew: brew install kotlin, which installed a copy to /usr/local/bin/kotlin on my first try. Woo!

Say “Hello World”

You run the Kotlin REPL with kotlinc-jvm, which I did not guess on my first try and had to hunt around doing web searches to discover:

Next, I tried to create an app. Once again I discovered that Kotlin is a little less straightforward than Swift in this regard.

Notice that you have to call kotlinc, the command line compiler, not kotlin. Then you can run the  736709-byte large jar results with (ew) java.

Unfortunately, it’s not as simple as one might hope to create a straightforward script:

However if you rename the file from hello2.kt to hello2.kts, you can run it as a command-line script:

Whee.

Hop into Xcode

Create a new Cross-platform Xcode project: File > New > Project > Cross-platform > External Build System > Next. Enter a name, and edit the build tool to kotlinc. Click Next. Navigate to a save location and click Create.

Choose File > New > macOS > Other > Empty. Click Next. Name the file HelloWorld.kts. (See the kts extension? This allows it to be run as a script.)

Edit your Run scheme (Scheme > Edit Scheme or Command-<). Choose the Info tab, select Other from the Executable pop-up list.

Type a forward slash, then continue to navigate to /usr/local/bin. Select kotlinc, uncheck Debug executable, and then click Close.

Next choose the Arguments tab and edit the arguments passed on launch to include both the -script flag and the source file:

You’re now ready to run:

Do something interesting

Now that you have the basics all ready to play with, create a slightly more interesting testing environment. For example, pull up Project Euler and challenge yourself to a few of their ideas:

That Kotlin “Feeling”

As when I played around with Python, I was surprised at Kotlin’s familiarity.

  • The println commands felt quaint and old fashioned like Swift 1.
  • The cascading dot sequence (which I cut and pasted for the second result, and Xcode didn’t automatically indent) felt as fresh as modern Swift. I also felt pretty confident in my overall Swift-influenced style despite jumping into an entirely new language.
  • Extending Int with the divisibleBy function was a little weird and I deliberately used the = syntax to define my function rather than a more familiar brace and return, just so I could say I tried to be more authentically kotlinny.
  • The two dot range did catch me but it was an easy fix from three dots to two.
  • I quite liked using $-delimited variable names compared to Swift’s \() insertion sequence.

Given that other than a few math functions and hello world, this post contains all my Kotlin code to date, I don’t have much more to add about the language similarities and differences, but let me know if you’d be interested in reading more about “Erica learns Kotlin”. Otherwise, I’ll get back to doing other things during this extremely dead week before WWDC starts.