The Programmers Guide To Kotlin - The Basics
The Programmers Guide To Kotlin - The Basics
Monday, 12 June 2017
Article Index
The Programmers Guide To Kotlin - The Basics
Declaring a variable

There is renewed interest in Kotlin, the open source Java replacement language pioneered by JetBrains, now that Google has decided to support it as the third official Android development language. What better time could there be to find out what it is and how to use it. 

Programmer's Guide To Kotlin

cover

Contents

  1. What makes Kotlin Special (Book Only)
  2. The Basics: Variables, Primitive Types and Functions
  3. Control
  4. Strings and Arrays
  5. The Class & The Object
  6. Inheritance
  7. The Type Hierarchy (Coming soon!)
  8. Generics
  9. Collections, Iterators, Sequences & Ranges
  10. Advanced functions
  11. Anonymous, Lamdas & Inline Functions
  12. Data classes, enums and destructuring
  13. Exceptions, Annotations & Reflection
  14. Working with Java

In this Programmers Guide to Kotlin it is assumed that you are a programmer and know a standard object-oriented language such as C# or, of course, Java. In this case Java is particularly appropriate because Kotlin is a Java replacement. It is a JVM language that can be easily mixed with Java. It can be used from Java and Kotlin can use compiled Java libraries. You could call Kotlin a better Java and certainly if you are working on a Java project there is a lot of scope for using it to make coding easier. 

To get started with Kotlin the simplest thing to do is to download the Community Edition of IntelliJ. You can also use Android Studio; while trying out some of the standalone examples might be more difficult, the general principles still hold. 

Rather than being a complete reference guide, - there is one of those on the JetBrain's website - or a complete course this programmers guide is exactly that, a guide. It explains what is puzzling and or new to a programmer getting started with Kotlin.

In this part we look at functions, basic variables and class.

Functions

The first thing that you notice is that Kotlin has functions that just float about. This isn't the way Java works as any functions you write have to be part of a class. In other words, in Java all functions are methods.

In Kotlin you can define package level functions. 

For example, the simplest hello world is: 

fun main(args:Array<String>){
 println("Hello World")
}

You can see that we define a function using fun and curly brackets. You can also see that :type is how you define the type of a variable. Kotlin is strongly typed, but the compiler uses a lot of type inference and you can leave out type declarations a lot of the time. Most Java programmers moving to Kotlin don't. 

All is simple so far, but how can Kotlin support package level functions and still be compatible with Java and the JVM?

Easy, they aren't really naked functions. The compiler translates them to static methods of a java class called packagename.filename where filename is the name of the file including the Kt. So, if the hello world was stored in a file called Hello.kt, the class is demo.HelloKt assuming the package is called demo.

This means that to call main from a Java program you would use:

demo.main();

You can change the name of the default class using an annotation:

@file:JvmName("class name")

This use of a default class is how Kotlin implements all other instances of functions that don't seem to belong to a class. 

Once you have seen how to declare a function, you can almost guess the rest. You can specify a return type or Unit if it doesn't return a value.

You can use a single expression to define a function:

fun sum(a: Int, b: Int): Int =a+b

and as long as the return type is obvious you don't need to declare it. You always need to declare it if the function has a body.

You can use default and named arguments:

fun sum(a: int,b: Int=1): Int{
 return a+b
}

You can call the function using:

sum(1) 

to get the result 2. Use 

sum(a=1,b=2)

to get the result 3. 

Don't use named parameters to call Java functions. 

Lambdas

As in Java 8 you can use lambda functions. There are various ways to define a lambda. The simplest is to write the parameters complete with types on the left of -> and the result on the right. The type of the result will be inferred:

val sum = { a: Int, b: Int -> a + b }
println(sum(1,2))

You can also define the type of the lambda as in:

val sum:(Int,Int)->Int = { a: Int, b: Int -> a + b }
println(sum(1,2))

This is the same as the first, but now we have defined sum as of type (Int,Int)->Int i.e. function that takes two Ints and returns an Int. In this case we don't need the type declarations in the body of the lambda:

 val sum:(Int,Int)->Int = { a, b ->  a + b }

The body of a lambda can have more than one expression and only the last is treated as the result. For example:

val sum:(Int,Int)->Int = { a, b ->
 println(a)
 println(b)
 a+b
}
println(sum(1,2))

prints 3.

As well as lambda functions you can also use anonymous functions i.e. a standard function but without a name. For example:

fun(a: Int, b: Int): Int = a+b

or

fun(a: Int, b: Int): Int{
 return a+b
}

The whole point of lambdas and anonymous functions is that they can be passed as parameters to higher order functions. To do this you have to specify the parameter type as a function. For example

val sum = { a: Int, b: Int -> a + b }fun

fun doArithmetic(operation: (Int,Int)->Int){
 println(operation(1,2))
}

doArithmetic(sum)

The do Arithmetic function accepts a single parameter of function type which accepts to Int parameters and returns a single Int. 

Notice you can only pass a lambda or an anonymous function. You can't pass a standard function even if it has the same type.

There are lots more things to discover about functions including closure, inlining and destructuring. 

Infix Function calls

Another nice feature is the ability to call functions using infix or operator notation.  If you precede a function with infix then you can call it as if it was an operator:

object1 function object2

is translated to

object1.function(object2)

For example is you have a function defined as a method of Myclass:

  class MyClassA { 
       infix fun myFunc1(a: Int) {
            println(a)
        }
    }

var myObject: MyClassA

then you can call is using the traditional: 

myObject.myFunc1(3)   

or using infix notation:

myObject myFunc1 3

Of course this example isn't particularly sensible as infix operation usually involve the object on the right and the left. All of the standard operators in Kotlin are implemented as infix functions. For example you can write

2+3

or

2.plus(3)

If you are worried about efficiency considerations it is worth knowing that the compiler translates these function calls to standard JVM operators.

You can also override the functions that define the existing operators.

The ability to create new infix operators presents an opportunity for writing things in very different ways in Kotlin.



Last Updated ( Tuesday, 13 June 2017 )
 
 

   
Banner
RSS feed of all content
I Programmer - full contents
Copyright © 2017 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.