Learning Kotlin: The For Loop

Submitted by Robert MacLean on Wed, 08/15/2018 - 09:00

More Information

  • This is the 20th post in a multipart series.
    If you want to read more, see our series index

Kotlin has two loops, while and for. When I started I was like, "yup, I know those..." - except I didn't. while works the way I expected it would but for it is something else.

First Kotlin does not have a traditional for loop, eg for (var i =0;i< max; i++)... the for loop in Kotlin is closer to the iterator foreach loop in C#.

Basic

Let's start with the basics, how do I run a loop, say 10 times where we print out 0, 1, 2, 3, 4, 5, 6, 7, 8, 9:

  1. fun main(args:Array<String>) {
  2.     for(i in 0..9) {
  3.         println(i)
  4.     }
  5. }

In this, we use a ClosedRange (0..9) to state the start and end of the loop. This would be the same as for (var i=0; i< 10; i++).

Now, normally we want to loop over an array of items, so we can do this in two ways. First the equivalent of the C# for iterator/JS for of:

  1. fun main(args:Array<String>) {
  2.     val a = arrayOf("The","Quick","Brown","Fox")
  3.     for(i in a) {
  4.         println(i)
  5.     }
  6. }

and if we do the older style of using a normal for loop and using the index we have:

  1. fun main(args:Array<String>) {
  2.     val a = arrayOf("The","Quick","Brown","Fox")
  3.     for(i in 0 until a.size) {
  4.         val value = a[i]
  5.         println(value)
  6.     }
  7. }

What is awesome in the above is the Range, rather than having the inclusive lower and inclusive upper bounds of the .. range we using the keyword until which gives us an exclusive upper bound.

Kotlin is all about helpers, and last time we looked at destructuring so it shouldn't be a surprise we can use that to have BOTH the index and the value in the for loop.

  1. fun main(args:Array<String>) {
  2.     val a = arrayOf("The","Quick","Brown","Fox")
  3.     for((i, value) in a.withIndex()) {
  4.         println("$i is $value")
  5.     }
  6. }

Extras

The for loop has two additional options worth knowing; the first is downTo which loops from largest to smallest. This example which print 4321):

  1. for (i in 4 downTo 1) print(i)

The second is step which allows you to control how many steps to take when moving to the next item, for this example we will get 42:

  1. for (i in 4 downTo 1 step 2) print(i)

Operator

Adding support for this to our own classes is trivial, we merely need to add the interface Iterator<T> to our class. This adds two methods, fun next():T which should return the next value in the collection and fun hasNext():Boolean which should return true if there is another value available. Let us look at doing this with a class of prime numbers but for our example, we will add one condition since there are infinite primes we will have a top bound so it eventually ends - this is stored in the maxToHunt variable.

In the code our next function not only returns the next value, it calculates the NEXT NEXT value too which lets us set if there are more primes left if next is called again.

  1. class PrimeNumbers : Iterator<Int> {
  2.     var currentPrime = 1;
  3.     val maxToHunt = 100;
  4.     var morePrimesToFind = true;
  5.  
  6.     override fun next():Int {
  7.         val result = this.currentPrime;
  8.  
  9.         this.currentPrime += 1;
  10.         while(this.currentPrime < this.maxToHunt) {
  11.             var primeFound = true
  12.             for(divisor in this.currentPrime-1 downTo 2) {  
  13.                 if (this.currentPrime % divisor == 0) {
  14.                     this.currentPrime += 1
  15.                     primeFound = false
  16.                     break
  17.                 }
  18.             }
  19.  
  20.             if (primeFound) {
  21.                 break
  22.             }
  23.         }
  24.  
  25.         this.morePrimesToFind = this.currentPrime < this.maxToHunt
  26.         return result
  27.     }
  28.  
  29.     override fun hasNext() = this.morePrimesToFind
  30. }
  31.  
  32. fun main(args:Array<String>) {
  33.     for (i in PrimeNumbers()) {
  34.         println("$i is prime")
  35.     }
  36. }

Learning Kotlin: Destructuring

Submitted by Robert MacLean on Tue, 08/14/2018 - 09:00

More Information

  • This is the 19th post in a multipart series.
    If you want to read more, see our series index

Learning a new language seems is an experience you do to

  1. change jobs
  2. cause your boss made you do it
  3. cause you are a nerd

The thing I forget each time I learn a new language is that the act of learning a new language helps me be a better software developer in my own primary language (the secret fourth option). Going through Kotlin has been a similar experience, and nothing jumped out more than object destructuring.

The simple use for object destructuring is to be able, in a single line and assign multiple variables from an object. Let's look at this example:

  1. data class Person(val firstName: String, val surname: String, val age: Int)
  2.  
  3. fun name(person: Person) {
  4.     println("Hi ${person.firstName}")
  5. }
  6.  
  7. fun name2(person: Person) {
  8.     println("Hi ${person.firstName} ${person.surname}")
  9. }
  10.  
  11. fun main(args:Array<String>) {
  12.     val frank = Person("Frank", "Miller", 61)
  13.     val alan = Person("Alan", "Moore", 64)
  14.  
  15.     name(frank)
  16.     name2(frank)
  17.     name(alan)
  18.     name2(alan)
  19. }

In each of the name and name2 I am working with the Person object but all I want are the names. I never care about the age of the people.

We could add a function now, which pulls out just the strings we want and modify everything else to work with JUST the data it needs,

  1. data class Person(val firstName: String, val surname: String, val age: Int)
  2.  
  3. fun name(firstName: String) {
  4.     println("Hi $firstName")
  5. }
  6.  
  7. fun name2(firstName: String, surname: String) {
  8.     println("Hi $firstName $surname")
  9. }
  10.  
  11. fun print(person: Person) {
  12.     val (firstName, surname) = person
  13.     name(firstName)
  14.     name2(firstName, surname)
  15. }
  16.  
  17. fun main(args:Array<String>) {
  18.     val frank = Person("Frank", "Miller", 61)
  19.     val alan = Person("Alan", "Moore", 64)
  20.  
  21.     print(frank)
  22.     print(alan)
  23. }

Line 12 is the magic, that is the Object Destructuring. Rather than having two lines where we assign a variable to firstName and surname we can assign them both in one line so long as they are wrapped in parenthesis and match the names of the properties of the object.

So, why is this useful for other languages? Cause in JavaScript you have the same thing! The only difference is { and } rather than parenthesis and since learning it in Kotlin I've found that I use it in my main more too.

VS Code Extension of the Day: Paste JSON as code

Submitted by Robert MacLean on Fri, 08/10/2018 - 09:00

More Information

  • This is the 8th post in a multipart series.
    If you want to read more, see our series index

You have some data in JSON. You want a class to work with it in your TypeScript, Python, Go, Ruby, C#, Java, Swift, Rust, Kotlin, C++, Flow, Objective-C, JavaScript, Elm code or you want JSON Schema. What do you do?

You could do it by hand, or you get this extension which does it for you. And if you don’t use VSCode (why are you here), they also have a website which can do this for you too.

Learn more and download it

VS Code Extension of the Day: Settings Sync

Submitted by Robert MacLean on Wed, 08/08/2018 - 09:00

More Information

  • This is the 7th post in a multipart series.
    If you want to read more, see our series index

Settings sync is the first extension I always install as it allows me to restore my settings AND extensions. It uses GitHub gists to store the config, so you have a slightly annoying setup process initially but once done, each time you change a setting or extension it updates it to the gist. Then when you get a new install, it pulls down the settings and installs all the extensions you had and you can get everything setup really easily and quickly.

Learn more and download it

VS Code Extension of the Day: Editor Config

Submitted by Robert MacLean on Tue, 08/07/2018 - 09:00

More Information

  • This is the 6th post in a multipart series.
    If you want to read more, see our series index

If you work in a team where choice is important, you may find everyone has a different editor. Today our team uses VSCode, Atom & IntelliJ. Editor Config is a set of extensions for many editors which tries to unify things like tab vs. spaces, trailing spaces, empty lines at the end etc… Think of this as your editor linting as you go. Unfortunately, support is limited for what can be done, but a lot of editors and IDEs are supported.

Learn more and download it

VS Code Extension of the Day: Dracula Official

Submitted by Robert MacLean on Mon, 08/06/2018 - 09:00

More Information

  • This is the 5th post in a multipart series.
    If you want to read more, see our series index

So not an extension so much as a theme, Dracula is a great dark theme for Code. It is a little more playful in its colours too which is a plus but what makes it stand out is the Dracula community

There are tons of extensions to add Dracula to everything. I have my slack, terminal.app and IntelliJ all configured as well. It is really great to have the consistency everywhere.

Learn more and download it

VS Code Extension of the Day: Code Runner

Submitted by Robert MacLean on Fri, 08/03/2018 - 09:00

More Information

  • This is the 4th post in a multipart series.
    If you want to read more, see our series index

Code Runner is a lightweight code execution tool. I think of it as the middle ground between a REPL environment and actually running code normally. So you can execute a single file or even highlight specific lines and execute just them. It supports an amazing array of languages C, C++, Java, JavaScript, PHP, Python, Perl, Perl 6, Ruby, Go, Lua, Groovy, PowerShell, BAT/CMD, BASH/SH, F# Script, F# (.NET Core), C# Script, C# (.NET Core), VBScript, TypeScript, CoffeeScript, Scala, Swift, Julia, Crystal, OCaml Script, R, AppleScript, Elixir, Visual Basic .NET, Clojure, Haxe, Objective-C, Rust, Racket, AutoHotkey, AutoIt, Kotlin, Dart, Free Pascal, Haskell, Nim, D

I personally use it all the time with JS & Kotlin. I haven’t needed to change any settings, though code-runner.runInTerminal sounds interesting.

Download it here

VS Code Extension of the Day: Bracket Pair Colorizer

Submitted by Robert MacLean on Thu, 08/02/2018 - 09:00

More Information

  • This is the 3rd post in a multipart series.
    If you want to read more, see our series index

Initially, this extension allows your brackets, {} [] (), to be set to a unique colour per pair. This makes it really easy to spot when you are goofed up and removed a closing bracket. Behind the obvious is a lot of really awesome extras in it. You can have the brackets highlight when you click on them when you click on one the pair with bracketPairColorizer.highlightActiveScope and you can also add an icon to the gutter of the other pair bracketPairColorizer.showBracketsInGutter which makes it trivial to work our the size of the scope.

It also adds a function bracket-pair-colorizer.expandBracketSelection which is unbound by default but will allow you to select the entire area in the current bracket selection. Do it again, and it will include the next scope. For example, you can select the entire function, then the entire class.

Learn more and download it

VS Code Extension of the Day: Bookmarks

Submitted by Robert MacLean on Wed, 08/01/2018 - 09:00

More Information

  • This is the 2nd post in a multipart series.
    If you want to read more, see our series index

The bookmarks extension adds another feature from Fat VS to code, the ability to bookmark to a place in a document/file/code and be able to quickly navigate backwards and forwards to it. One important setting that I think you should change is bookmarks.navigateThroughAllFiles - set that to true and you can jump to any bookmark in your project, with false (the default) you can only navigate to bookmarks in the current file.

Learn more and download it

Learning Kotlin: Operators don't need to mean one thing

Submitted by Robert MacLean on Tue, 07/31/2018 - 21:59

More Information

  • This is the 18th post in a multipart series.
    If you want to read more, see our series index

Following on from the previous post we looked at operators and being able to use them yourself by implementing the relevant operator methods. The first part I want to cover in this second post is the Unary operators +, -, and !.

When I was learning this, the term unary jumped out as one I did not immediately recognise, but a quick Wikipedia read it became clear. For example, if you use a negative unary with a positive number, it becomes a negative number... It is primary school maths with a fancy name.


One thing to remember about operators is it is totally up to you what they mean, so, for example, let's start with a simple pet class to allow us to define what type of pet we have.

  1. package blogcode
  2.  
  3. enum class animal {
  4.     dog,
  5.     cat
  6. }
  7.  
  8. data class pet(val type: animal);
  9.  
  10. fun main(args: Array<String>) {
  11.   val myPet = pet(animal.dog)
  12.   println(myPet)
  13. }

this produces pet(type=dog)

Now, maybe in my domain, the reverse of a dog is a cat, so I can do this to make this reflect my domain:

  1. package blogcode
  2.  
  3. enum class animal {
  4.     dog,
  5.     cat
  6. }
  7.  
  8. data class pet(val type: animal) {
  9.     operator fun not() : pet = when(this.type) {
  10.         animal.cat -> pet(animal.dog)
  11.         animal.dog -> pet(animal.cat)
  12.     }
  13. }
  14.  
  15. fun main(args: Array<String>) {
  16.   val myPet = pet(animal.dog)
  17.   println(!myPet)
  18. }

This produces pet(type=cat)

And this is the core thing, that while a Unary has a specific purpose normally you can totally use it the way that makes sense. This is really awesome and powerful but it doesn't stop there.

Normally when we think of something like the Unary not with a boolean, it goes from true to false (or vice versa), but it remains a boolean. There is nothing stating it has to be that way:

  1. package sadev
  2.  
  3. enum class animal {
  4.     dog,
  5.     cat
  6. }
  7.  
  8. data class pet(val type: animal) {
  9.     operator fun not() :String = "BEN"
  10. }
  11.  
  12. fun main(args: Array<String>) {
  13.   val myPet = pet(animal.dog)
  14.   val notPet = !myPet
  15.   println("myPet is ${myPet::class.simpleName} with a value of ${myPet}")
  16.   println("notPet is ${notPet::class.simpleName} with a value of ${notPet}")
  17. }

In the above, the output is

myPet is pet with a value of pet(type=dog)
notPet is String with a value of BEN

In short, the not of a dog pet is actually a string with the value of ben. I have no idea how this is useful to real development, but it is amazing that Kotlin is flexible enough to empower it.