Friday, December 10, 2021

Kotlin: My first impressions, via days 1-3 of Advent of Code 2021

While working on Ruby solutions to this year's Advent of Code programming challenges, my attention was caught by one of the sponsored messages running in the site's sidebar, from JetBrains:

Get ready to jingle with Advent of Code in Kotlin! Have fun, learn new things, and win prizes. Believe in magic with Kotlin. Happy holidays! https://jb.gg/AoC

That link redirected to a post on the JetBrains / Kotlin blog inviting developers to try out the Kotlin language via the Advent of Code (AoC) problems, and providing a nice Kotlin AoC GitHub template as a starting point.

I'd never worked with Kotlin before, but I have used AoC to try out new programming languages before. Serendipitously, I had some time available today, and so I decided to give it a go!

In the time I had, I wound up solving the first 3 days of AoC 2021 in Kotlin.  Here's a quick write-up of my very first impressions of Kotlin!

What I liked!

Good out of the box support in the IntelliJ IDE (which I downloaded for the first time today), including suggestions for more idiomatic Kotlin syntax. (Which makes sense, as JetBrains provides both the IntelliJ IDE and the Kotlin language itself!)  I was saved from some instances of typical "trying to write language X as if it were language Y" newbie mistakes by warnings/suggestions in the IDE.

IntelliJ displays, inline in loop declarations, whether the lower and upper bounds are inclusive of exclusive. This made it easy for me to understand whether, in a Kotlin until loop over an array, I needed to use myArray.length or myArray.length - 1 as the upper bound of the loop. (The former!)

I found the data class syntax to be a nice succinct and readable way for a method to return some related values. In a method in one of my Ruby AoC solutions where I was returning two values just wrapped together in an array, it was easy in the Kotlin equivalent to declare a one-liner data class, and then have my method return an instance of that class, to make what was being returned much more obvious to readers.

If ... else in Kotlin is an expression, not a statement. While looking up an equivalent for the typical ? : ternary expression syntax, I actually enjoyed discovering that ? : is actually not supported in Kotlin, and an inline if ... else should be used instead.

Support for ".."-syntax ranges like in Ruby (e.g. (5..15) to represent the set of integers 5 through 15, inclusive) was fun to see in a C-like language.

The variable-declaration keywords val and var, similar to let and const in JavaScript ES6, to respectively declare immutable and immutable variables.

The ability to pass a function "pointer" as a parameter to a function -- something both the Ruby and Kotlin variations of my Day 3 solution actually made use of.

 

What I maybe didn't like so much

I actually wasn't aware of this ahead of time, but Kotlin is built on top of Java. (Or perhaps it's more accurate to say that Kotlin, like Java, is a language that runs on the JVM?) The first time I became aware of this was when my program threw an exception... and there was a mix of Java and Kotlin code in the call stack. I have no idea to what extent aspects of Java poke their heads up while working in Kotlin... but it's something that I'd want to understand more about before committing to using Kotlin for a real project, versus other available languages where that kind of thing is much more of a non-issue.

JetBrains' Kotlin template for AoC helpfully included a check call to test each problem's provided sample answer against the corresponding sample input. What wasn't so helpful was that a failure of the test just resulted in a generic java.lang.IllegalStateException : Check failed -- with no accompanying mention of the check's expected or actual values. I had to manually add a print statement to find out what the failure was. Maybe I was just missing something?

I ran into some trouble using the built-in pow to raise 2 to the power of a particular variable:

  • It took me a little while to figure out why I was getting an Unresolved reference: pow.  I ended up googling for that exact phrase, while led me to discover that an import kotlin.math.* is needed. Not surprising in retrospect, but it would have been nice to a a prompt in Kotlin's error message about an import/reference possibly being needed. (I believe C# does this, probably among others.)
  • The pow method (as of the current version, 1.6) can't be used on integers. After a little more confusion, I figured out that I had to use the literal 2.0 (instead of just 2), and then manually convert the result back to an Int after getting my result. Why make developers do that?

 

Verdict

Verdict? It's much too early for a verdict! I only worked with Kotlin for a few hours, on some toy problems, on my own! 

It was fun, though, to get to play with a new language! Kudos to the Kotlin team at JetBrains for their combination of the Advent of Code sponsored message, their blog post, and the Kotlin Advent of Code GitHub template, which taken together, were enough to get me to take a look at Kotlin!

And if you're a developer but have never taken a look at Advent of Code before, I strongly recommend checking it out! The event is extremely well crafted and executed each year. It's worth your time!

No comments:

Post a Comment

Non-spammers: Thanks for visiting! Please go ahead and leave a comment; I read them all!

Attention SPAMMERS: I review all comments before they get posted, and I REPORT 100% of spam comments to Google as spam! Why not avoid getting your account banned as quickly -- and save us both a little time -- by skipping this comment form and moving on to the next one on your list? Thanks, and I hope you have a great day!