Kotlin: A Fun Lan­guage for An­droid App De­vel­op­ment

Kotlin is a stat­i­cally typed pro­gram­ming lan­guage for mod­ern multi-plat­form ap­pli­ca­tions. It is 100 per cent in­ter­op­er­a­ble with Java. Ex­ist­ing li­braries and frame­works in Java can di­rectly be run on Kotlin, which also hap­pens to be open source and freely

OpenSource For You - - Contents -

Kotlin is a stat­i­cally typed open source mod­ern pro­gram­ming lan­guage tar­get­ing JVM, An­droid and even JavaScript. It is named af­ter the Rus­sian is­land called Kotlin, just as Java is named af­ter the In­done­sian is­land. It works ev­ery­where where Java works – on the server side, the desk­top, An­droid, and other places.

The big­gest sell­ing point of Kotlin is its 100 per cent in­ter­op­er­abil­ity with Java. So in­stead of throw­ing away or re-writ­ing all your li­braries in Kotlin, you can use all your ex­ist­ing Java li­braries and frame­works di­rectly with it. Due to this char­ac­ter­is­tic, you can grad­u­ally adopt

Kotlin in your Java code base.

Kotlin has been cre­ated by JetBrains, the maker of In­tel­liJ, An­droid Stu­dio and other amaz­ing IDEs.

It is open source and has been re­leased un­der the

Apache li­cence.

Why you should use Kotlin

The big­gest rea­son to learn Kotlin is that at Google I/O 17, Google an­nounced first-class sup­port for Kotlin for An­droid. So now you can ex­pect full sup­port from Google, like doc­u­men­ta­tion to write An­droid apps in Kotlin.

An­other rea­son is that it’s an amaz­ing lan­guage and many de­vel­op­ers (es­pe­cially An­droid de­vel­op­ers like me) are in love with it and have fun writ­ing code in it. Peo­ple who are tired, or in some cases ir­ri­tated with Java, will def­i­nitely find Kotlin con­cise and fun to work with.

Prob­lems and is­sues with Java and the An­droid plat­form

Let’s start with the cur­rent prob­lems with Java that are usu­ally faced by de­vel­op­ers com­ing from other lan­guages.

Java is ex­tremely old. It’s been around for more than 20 years. It doesn’t have the mod­ern higher or­der func­tions and fea­tures that newer lan­guages like Swift or Golang ship with. Though Java 8 is try­ing to bring out some good stuff, it still is ver­bose, which means that to per­form even small tasks, we end up writ­ing a lot (se­ri­ously, a lot) of code. It also ships with Nul­lPoin­t­erEx­cep­tion, which I’m pretty sure scares you and your cus­tomers.

Let’s dive deeper into the prob­lems in the Java-An­droid world, which are much worse.

An­droid de­vel­op­ers are stuck be­tween Java 6 and 7. This means that we don’t have fea­tures like Lamb­das, higher

or­der func­tions, and Java Time APIs. We can get these fea­tures by tar­get­ing higher ver­sions of An­droid, which is not a fea­si­ble so­lu­tion. This prob­lem can also be solved us­ing third party li­braries like RetroLambda, RxJava, etc, which is ac­cept­able.

There are also re­stric­tions to adding func­tion­al­ity to An­droid APIs. I’m sure you might have felt like adding a par­tic­u­lar fea­ture such as be­ing able to check if a string is an email or not, but you were re­stricted from do­ing so. Due to such re­stric­tions, we end up mak­ing lots of ‘Util’ classes to solve the prob­lem.

More­over, An­droid loves in­her­i­tance; it re­quires ex­tend­ing things like Ac­tiv­ity, etc, which is not to­tally bad but lim­its flex­i­bil­ity.

In An­droid, we need to write a lot of boil­er­plate code to achieve some­thing. For ex­am­ple, if you want to write a model POJO class, you end up writ­ing 40-50 lines of code, depend­ing upon the num­ber of at­tributes you add. In Java, all the empty values are set as null for ef­fi­ciency. An­droid tries to be ef­fi­cient by set­ting ‘null’ as the de­fault value ev­ery­where, which again comes with NPEs and more in­stances of the app crash­ing.

And there’s a lot more.

Some big play­ers us­ing Kotlin in pro­duc­tion

JetBrains is al­ready us­ing Kotlin to build its IDEs. Its new IDE Rider is com­pletely writ­ten in Kotlin while new fea­tures in older IDEs are also writ­ten in it. Pin­ter­est, Cours­era, At­las­sian, Ever­note, Base­camp and many more play­ers are us­ing Kotlin in their An­droid apps, ei­ther par­tially or fully. Gra­dle is in­tro­duc­ing Kotlin as a lan­guage for writ­ing build scripts, in­stead of Groovy.

Syn­tax of Kotlin

Let’s take a crash course in the ba­sic syn­tax of Kotlin. We won’t cover all of it; hence, I rec­om­mend go­ing to the Kotlin web­site and read­ing the doc­u­men­ta­tion, which is pretty good, and also try­ing out the Kotlin Koans — they are very in­ter­est­ing and help you learn faster.

Declar­ing vari­ables

Declar­ing vari­ables in Kotlin is sim­ple; you ei­ther write ‘val’ or ‘var’ and the name of the vari­able. Then the type of the vari­able which is op­tional pro­vided that the com­piler is able to fig­ure it out.

// String (Im­plic­itly in­ferred) val spell = “Lu­mos”

// Int val num­ber = 74

The type can be ex­plic­itly spec­i­fied af­ter the vari­able name with a colon (:). // Ex­plicit type var spells: List<String> = Ar­rayList()

Did you no­tice there is no ‘new’ key­word? That is be­cause there is no ‘new’ key­word in Kotlin.

As we dis­cussed ear­lier, there are two ways to de­clare vari­ables in Kotlin:

1. val

2. var

In Kotlin, im­mutable values are pre­ferred when­ever pos­si­ble. The fact that most parts of our pro­gram are im­mutable pro­vides lots of ben­e­fits, such as a more pre­dictable be­hav­iour and thread safety.

Func­tions

fun add(a: Int, b: Int): Int { re­turn a + b }

This is how we write func­tions in Kotlin. The func­tions start with a ‘fun’ key­word (ex­pect­ing the func­tion to be fun to write for you), the pa­ram­e­ters are re­versed, and the re­turn is typed at the end af­ter the colon ‘:’. Pretty sim­ple, right?

You can even cut the code of the func­tion to this, as fol­lows:

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

And you can add de­fault values to the func­tion, as shown be­low:

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

You also get a named ar­gu­ment! Did you no­tice that there is no semi-colon in the re­turn state­ment? That’s be­cause Kotlin is a semi-colon free lan­guage.

Let’s look at what makes Kotlin so in­ter­est­ing.

Null safety

One of the com­mon rea­sons for An­droid apps to crash is ‘Nul­lPoin­t­erEx­cep­tion’. A lot of time is wasted de­bug­ging an is­sue and solv­ing it. The great thing about Kotlin is that it comes with null safety, which helps in catch­ing nulls at the com­pile time rather than dur­ing a run­time crash. The fol­low­ing code shows how this is done:

// Com­pile time er­ror val spell: String = null

// OK val spell: String? = null

In Kotlin, by de­fault, all vari­ables are marked as ‘not null’ un­less you ex­plic­itly tell the com­piler that the vari­able can be null with a ques­tion mark (?) op­er­a­tor. This means that in or­der to de­clare a null vari­able, you need to add ‘?’ at the end of the vari­able type.

Even if you try to set a non-null vari­able to null, the com­piler will ‘yell’ at you.

// Com­pile time er­ror var spell: String = “Lu­mos” spell = null

// OK var spell: String? = “Lu­mos” spell = null

Us­ing null vari­ables

Di­rectly ac­cess­ing null vari­ables re­sults in com­pile time er­ror, un­less pro­tec­tion has been cast be­fore us­ing these vari­ables. If the null is safely han­dled then the com­piler is smart enough to know that the vari­able (the ‘spell’ vari­able, in our case) won’t show an er­ror on us­ing it fur­ther in the if block.

// Com­pile time er­ror val spell: String? = null val length = spell.length

// OK val spell: String? = null if (spell != null) { // Smart cast val length = spell.length }

The id­iomatic way is as fol­lows:

// Safe val spell: String? = null val length = spell?.length

// Safe with else val length = spell?.length ?: -1

In the first case, if the value for spell ex­ists then the length will be re­turned, else null will be re­turned with­out any ex­cep­tion. A point to note over here is the ‘val length’ will be a nul­lable value, which means the com­piler will force you to check for null value in case of the ‘length’ vari­able.

The sec­ond case is pretty straight­for­ward. Un­like the first case, the ‘val length’ won’t be nul­lable over here be­cause we have han­dled it us­ing the else con­di­tion.

String in­ter­po­la­tion

String in­ter­po­la­tion is a nifty fea­ture, which makes your code cleaner. It makes it eas­ier to build long strings.

fun sayHello(mes­sage: String) { println(“Wel­come $mes­sage”) }

fun sayTime() { println(“Time: ${Sys­tem.cur­ren­tTimeMil­lis()}”) }

Us­ing $ al­lows you to avoid String con­cat or StringBuilder. You can ex­e­cute a small piece of code us­ing ${}. In­ter­nally, it uses StringBuilder for per­for­mance on the JVM level.

Lambda ex­pres­sions

Lambda ex­pres­sions are anony­mous func­tions, which can be passed as ar­gu­ments to other func­tions. For peo­ple who are not aware about Lambda ex­pres­sions, I rec­om­mend they read more about them.

// Java mBut­ton.setOnClick­Lis­tener(new OnClick­Lis­tener() { pub­lic void onClick(View v) {

// Your logic }

});

// Kotlin mBut­ton.setOnClick­Lis­tener {

// Your logic }

mBut­ton.setOnClick­Lis­tener { // Us­ing the view pa­ram­e­ter v -> v.vis­i­bil­ity = GONE }

Higher or­der func­tions

Kotlin sup­ports Higher or­der func­tions which means func­tions can be passed to an­other func­tion as pa­ram­e­ters.

An ex­am­ple is given be­low:

fun con­sume(f: () -> Unit): Boolean { f() re­turn true }

The ugly part of re­ceiv­ing func­tions as ar­gu­ments is that the com­piler needs to cre­ate classes for them, which can im­pact per­for­mance. But in Kotlin, this can be eas­ily solved by us­ing the key­word in­line. An in­line func­tion will have less im­pact on per­for­mance, be­cause it will sub­sti­tute the call to the func­tion with its code in com­pi­la­tion time. So it won’t

re­quire the use of an ex­tra ob­ject for this.

in­line fun con­sume(f: () -> Unit): Boolean { f() re­turn true }

Ex­ten­sion func­tions

All of us, at some stage, want to add a new func­tion to an ex­ist­ing class but this means mod­i­fy­ing the orig­i­nal class and do­ing some more work on the code. This is where ex­ten­sion func­tions come to our res­cue. As the name sug­gests, they are used to in­ject func­tion­al­ity to al­ready ex­ist­ing classes with­out mod­i­fy­ing the orig­i­nal class. Peo­ple who know C# may be aware of this fea­ture. These func­tions elim­i­nate the need for cre­at­ing ‘Util’ classes.

Here is an ex­am­ple:

fun String.isE­mail(): Boolean { re­turn Pat­terns.EMAIL_ADDRESS.matcher(this).matches() }

The us­age is as fol­lows:

val email = “go.kotlin@an­droid.com” if (email.isE­mail()) {

// Do lo­gin

}

Ex­ten­sion func­tion with re­ceiver

This fea­ture is unique to Kotlin, and is like a com­bi­na­tion of an ex­ten­sion func­tion and a higher or­der func­tion whereby you pass an ex­ten­sion func­tion as a pa­ram­e­ter to an­other ex­ten­sion func­tion.

in­line fun SharedPref­er­ences.edit(func: SharedPref­er­ences. Ed­i­tor.() -> Unit) { val ed­i­tor = edit() ed­i­tor.func() ed­i­tor.ap­ply() }

//Us­age val pref = Pref­er­enceMan­ager.getDe­fault­SharedPref­er­ences(con

Newspapers in English

Newspapers from India

© PressReader. All rights reserved.