Kotlin Decoded | Part 1 - main() & semicolon

Daniel Rendox - Jun 20 '23 - - Dev Community

Table of Contents

 1. Program entry point
       1.1. Why do we need String[] args?
       1.2. Why does Kotlin not require String[] args?
       1.3. Where is the class wrapping the main function?

 2. Semicolon
 3. Conclusion

Hello everyone, welcome to another article from the Kotlin Decoded series. This one describes the main() function in Kotlin, which is the starting point of a program, and the role of semicolons in Kotlin syntax.

Kotlin Decoded is a series of articles for Java developers who want to learn Kotlin. It compares the two languages and gives helpful tips from various sources. It is not a complete Kotlin tutorial and assumes some programming experience. Read the series intro for more information.

And one more thing, for now, don’t pay attention to the syntax of functions, variables, and other things, which are not important right now. You will learn more about them in the next articles.

Program entry point

That’s the method you should run to start the program.

Java:

public class Main {
    public static void main(String[] args) {

    }
}
Enter fullscreen mode Exit fullscreen mode

Kotlin:

It can be written in two ways:

  1. Without string arguments:
fun main() {
    println("Hello world!")
}
Enter fullscreen mode Exit fullscreen mode
  1. With string arguments
fun main(args: Array<String>) {
    println(args.contentToString())
}
Enter fullscreen mode Exit fullscreen mode

That’s when I started wondering why there are two ways and why we need these String args. Honestly, writing in Java I’ve never questioned this. I just took it for granted. If you like me wonder why the heck we need these args, why this is necessary in Java and not in Kotlin, read the following passage, if not — jump to the next section.

Why do we need String[] args?

The matter is that you can start your Java program from the command line by simply typing:

java Main
Enter fullscreen mode Exit fullscreen mode

Note: For this to work, you should previously change the directory to your project’s outputs directory (the folder where .class files are generated while the project is being built). If you use IntelliJ, you can read more about this here.

Or you can put some arguments after the class’s name. Like if you had a class for processing a file, you would also specify what file needs to be processed, which would be the argument. For example:

java TxtProcessor my_file.txt
Enter fullscreen mode Exit fullscreen mode

A Java application can accept any number of arguments from the command line. This allows the user to specify configuration information when the application is launched. [source]

So the previous command contains only one argument, but you can add some more of them separated by spaces. These arguments will be saved into the String[] args array.

Why does Kotlin not require String[] args?

It’s mandatory in Java to put this in the main method’s parameter. But Kotlin allows us to omit it. Kotlin is compiled to Java-compatible bytecode when targeting the JVM. So it’s simply compiled to the Java main method with String[] args for the JVM to understand.

Where is the class wrapping the main function?

Kotlin allows a function to be out of a class's scope as well as multiple classes that aren’t nested in the same file:

class C1 {

}

class C2 {

}
Enter fullscreen mode Exit fullscreen mode

This can be useful, for example, for creating extension functions, which will be brought up in the following articles.

Semicolon

As you may have noticed, Kotlin aims to let developers write less code. So while semicolon is required in Java and some other languages, it’s optional in Kotlin. Kotlin compiler understands the end of a statement by line breaks (\n).

Although this simplifies the work, it has some downsides:

Java:

int a = 2
+ 1;
System.out.println(a);
// Output: 3
Enter fullscreen mode Exit fullscreen mode

Kotlin:

var a = 2
+ 1
print(a)
// Output: 2
Enter fullscreen mode Exit fullscreen mode

That’s because the line + 1 in Kotlin is perceived as a separate statement. So to avoid this write a “dangling operator” on the first line:

var a = 2 +
1
print(a)
// Output: 3
Enter fullscreen mode Exit fullscreen mode

Kotlin also understands when the lines don’t parse unless they are joined or when we’re inside an open parenthesis:

// open parenthesis
var array = arrayOf(1,2)
array[
        array.lastIndex
]

// the for-loop doesn't compile unless it's joined with the following line
for (i in 0..10)
    println()

// although the first line can be compiled on its own, 
// the following lines don't parse unless are joined with the previous one

if (time in 0..11) println("Good morning!")
else if (time == 12) println("Time for lunch")
else println("Good day!")
Enter fullscreen mode Exit fullscreen mode

So avoid splitting lines when they are grammatically valid on their own.

However, IDE will usually notify you about this.

In addition, semicolons are not ignored in certain cases. For example, when you want to write separate statements on the same line:

var a = 2 + 1 ; print (a)
Enter fullscreen mode Exit fullscreen mode

Also, note that semicolons are required when declaring enums.

Conclusion

So we’ve seen Kotlin and Java comparisons for the program entry point and semicolons. I hope you learned how to write the main() function in Kotlin and understood when semicolons are optional or required in Kotlin syntax. If you liked this article click the like button and subscribe for more. See you!

Other articles from this series

. . . . . . . . . . . . . . . . . . . .