The documentation for Kotlin is now located on the new site. This page is kept for historical reasons

Skip to end of metadata
Go to start of metadata

The documentation for Kotlin is now located on the new site. This page is kept for historical reasons

This page gives some very basic examples of Kotlin syntax.

Simplest version

package demo 
fun main(args : Array<String>) { 
  println("Hello, world!") 

Line 1 is the optional package header.
Then we declare a package-level function main which returns Unit and takes an Array of strings as a parameter.

Note that semicolons are optional.

Reading a name from the command line

fun main(args : Array<String>) { 
  if (args.size == 0) { 
    println("Please provide a name as a command-line argument") 
  println("Hello, ${args[0]}!") 

Line 6 demonstrates string templates and array access.

Reading many names from the command line

fun main(args : Array<String>) { 
  for (name in args) 
    println("Hello, $name!") 

Line 2 demonstrates the for-loop, that would have been called "enhanced" if there were any other for-loop in Kotlin (smile)

An "object-oriented" Hello

class Greeter(val name : String) { 
  fun greet() { 
    println("Hello, ${name}"); 
fun main(args : Array<String>) { 

Here we have a class with a primary constructor and a member function.
Note that there's no new keyword used to create an object.

A multi-language Hello

fun main(args : Array<String>) { 
  val language = if (args.size == 0) "EN" else args[0] 
  println(when (language) { 
    "EN" -> "Hello!" 
    "ES" -> "¡Hola!" 
    "RU" -> "Привет!" 
    else -> "Sorry, I can't greet you in $language yet" 

In this example, val denotes a declaration of a read-only local variable, that is assigned an if-expression. Then we use very basic pattern matching expression.

Extension function hello()

fun String.hello() { 
  println("Hello, $this!") 
fun main(args : Array<String>) { 
  "world".hello() // prints 'Hello, world!' 

In this snippet, we define an extension function hello() for the type String that uses this in a string template. And then we call this function on a string "world", i.e. we pass this string as the receiver-argument (this-argument) to hello().

LINQ-like Hello

fun main(args : Array<String>) { 
  args filter {it.length() > 0} forEach {print("Hello, $it!")} 

Here we first called the filter() higher-order function to select only those string from the args array that have non-zero length. To do this, we passed a function literal that checks the length of its parameter. the name it is the default name of a parameter for a function literal.

Filter created a collection for us, and we called foreach() on that collection, passing in a function literal to be executed for each element. And that function literal just prints a greeting with the passed string.

What's next

  • No labels


  1. Anonymous

    While I quite like String templates (I use them a lot in my Groovy development), there is the possibility of string template injection attacks to worry about. Have you considered any language features to minimize the security risk of using string templates?

    1. It's a statically typed language, no injections are possible.

  2. Anonymous

    Is it indeed 'val', not 'var' to declare language variable? 

    1. Anonymous

      It's same as Scala - "var" declares a mutable variable, "val" an immutable one.

      1. Anonymous

        Indeed, it is like Scala... everything, except for the subletest differences, i.e. "fun" instead of "def", <> instead of [] for generics, even higher-order functions. The only thing that sets it apart from Scala in these examples is the pretty simple way of adding additional functions to types, afair that needs implicits in Scala.

        To get to the point: I'm sorry, but why do we need another Scala? I'm perfectly happy with Scala and I really don't see (yet) how exactly this language is different enough to be worth considering.

        1. You might be interested in reading the Comparison to Scala page

          1. Anonymous

            Why? It lists features.

            The point above was that you copied the scala syntax and changed fun for def and <> for [] and other minor things...

        2. Anonymous

          Because Scala fails to scale on compiling!

  3. Anonymous

    I agree with "it's like Scala" Can you please try to make the language more "user friendly"? Python invested a lot of time and effort into creating something that makes it harder to write incomprehensible code. For example the ternary if:

    Next, there are those odd ":" between the name and the type. Surely you don't need that?

    val/var ... in 2011, compilers aren't smart enough to distinguish between constants and variables? We still have to *declare* variables? What for? To make sure to catch typos? Code completion and unit tests already take care of that.

    Why not use convention over configuration and say "lower case -> variable, upper case -> constant"? Or how about creating a language which allows developers to have preferences. Some people don't need/want to declare everything. Add an annotation/compiler switch for them.

    But if you can't create a language that allows to write more compact and expressive code without using all the special characters on the keyboard, why invent another language?

    1. Anonymous

      how about this?

      1. Anonymous

        No way. || is a boolean operation :-)

    2. Anonymous

      I can't agree with you on the desire to not declare variables. I have used languages in which variable declarations were not needed and found it to be a rich source of bugs. Also, in a strongly typed language like Kotlin it creates logistical difficulties since there's no authoritative place to determine where the type of the variable is defined.

      As far as the colons, I think it is fairly useful for reducing ambiguity. The colon reads as it does in Pascal, as "of type". So if you say "val a : Integer = 5" then you are really saying "The value a, of type Integer, is 5". The colons also make it easier for a compiler to parse things unambiguously.

      In C, C++, and Java, upper case is usually reserved for compile-time constants (public static final variables), not run-time constants like 'val' declarations, so this could get confusing unless the same convention was used here.

      With the above said, I'm not especially fond of "val/var". The names are too similar. I'd rather see "set/var" or "let/var". It seems like it would reduce typos and aid in code review.

      1. Anonymous

        My point is that in 2011, we should start about thinking of ways to make code more expressive instead of doing a simple search'n'replace of keywords. The language has some good points but I don't see why we can't have that with a modern syntax or maybe even a way for developers to specify preferences. Languages which try to use as much of the special characters on the keyboard as possible turn me off.

        So "int a = 5" is much more compact and as easy to parse as "val a : Integer = 5" But it's much less to type and to read. In Groovy, there is "def" if we want the compiler to figure it out. So my suggestion would be:

        Another point against Pascal/Oberon/Delphi: It's dead, Jim.

        As for "rich source of bugs": Were those projects with a low or a high test coverage? If I have to test it anyway, what's the point in having to specify it in two places?

        1. Anonymous

          The ": Integer" is usually not needed in Kotlin. It's just there if you need to, or want to, explicitly specify the type, presumably because it's different from what the type of the right-hand expression is. In most cases it can be implicitly determined from whatever is on the right side of the =. So in general you can write:

          val a = 5

          As far as the "rich source of bugs", a lot of the problems I experienced occurred because a variable name would either be mistyped somewhere (provoking no compile-time errors because of course there was no variable declaration for it to disagree with), or because an identically named variable appeared unexpectedly in an outer scope as well, and so the language just "assumed" that they were meant to refer to the same variable, because there was no shadowing inner variable declaration. This was a Very Large legacy software system, with many different authors over time, and it was extremely difficult to be sure that a variable name was actually not used in an outer scope somewhere, by somebody. This problem had the tendency to promote local variables into being class variables or global variables unexpectedly. That's a hard case to test for since when you write the test to test individual methods, the test passes fine. There is just unexpected "crosstalk" between different methods in different modules that were supposed to be independent. To defend against this, people were starting to use unique prefixes on their local variable names, which made the code hard to read. It was a mess. In my opinion, avoiding variable declarations is a hack, which works fine in small programs and scripts, but doesn't scale well at all to large software systems written by many people.

          You are missing my point about ambiguity.

          Knowing whether what it is about to parse is a type name or not (as opposed to, for instance, an variable on the left side of assignment statement) simplifies the compiler's job considerably. It is helpful if the compiler can distinguish the two without having to compare what it is parsing against the entire set of type names that may be in scope, and the entire set of variable names, to determine if what it is about to parse is a declaration or a statement. This problem in C++ eventually became severe enough to force the creation of the rather awkward "typename" keyword (google it), because sometimes there was simply no way to tell if a declaration was supposed to be a type declaration or not without knowing whether the identifiers mentioned in it named actual types. In general, knowing if something is a type name or not is not even possible when parsing, for instance, a C++ template declaration. On the other hand, if the compiler knows from the structure of the language when to expect a type name, it can use an LL(k) parser with no backtracking (big performance increase!). Also, this language structure allows an IDE to parse individual files for syntax checking, syntax highlighting, etc. without having to first collect the full set of types that might be in scope from all of the files that they depend on. Another huge performance win.

          I'm all for testing, but I think that writing tests for things that could have been detected automatically at compile time is an enormous waste of time. The whole point of using a statically typed language (which Groovy is not) is to cut down on the number of tests that have to be manually written, by making certain kinds of problems the compiler's responsibility to detect, rather than the tester's. My experience has been that people who are used to writing in dynamically typed languages often end up much more comprehensive unit tests than those who write in statically typed languages, but that a large percentage of those tests end up basically duplicating what a statically typed compiler would check automatically. So the code written is smaller, but the tests for it are larger, and on the whole, it's somewhat of a wash.

          Note that Kotlin, unlike Groovy, is a statically typed language, so different design criteria apply. Lots of Groovy features and development practices just don't make sense in a statically typed language. You may think of this as "modern syntax", but I think of it as "dynamic syntax", which is appropriate in a dynamic language, but not necessarily in a static language.

          Not that I personally use it, but your comment on Pascal being dead made me smile. You might be interested to see this:


          Note that Delphi is #14 on the list, and Groovy didn't even make it into the top 100. Admittedly, Delphi mindshare is declining over time, but it's a reasonably nice, mature, object-oriented language, with a pretty decent development environment, and there's a LOT of legacy Delphi code out there. Borland was, after all, once a major power in the world of compilers. And, believe it or not, there are still some features in the Pascal/Delphi family of languages that are easier to use than the corresponding features in the C family of languages.

          1. Anonymous

            Variable shadowning: Errors of this type can only be solved when users start to write smaller methods which is a good thing. Also which programming language can "leak" a local variable from one method to another?

            My point about ambiguity is that I don't f***** care how hard it is for the compiler to parse my code :-) Looking up symbol names in a hash map with millions of entries still takes only a few milliseconds while my brain power is precious. In 2011, I'm not going to touch a compiler that is only fast because half of the compilation has to happen in my head.

            As for Delphi: Delphi is/was successful because of the comprehensive library and things like the VCL that made insane problems with the Windows API manageable. The syntax and arrays that start with 1 still sucks.