As the first public preview of Kotlin is approaching (it will be announced on Jan 10th, 2012, which is less than a week from now!), we are putting some things in order…
In particular, we have reviewed syntactic forms available in the language, and decided to change a few. These changes are incompatible with the old syntax, and we have migrated all our test data, and will update the publicly available documentation soon.
I would like to point out that this is not the last change of this sort. Kotlin is not released yet, and until it is we are constantly gathering feedback and sometimes find out that something needs to be changed. Consequently, there are no backward-compatibility guarantees before the 1.0. We realize how important backward compatibility is, but we’d better be backward compatible to a really good design created according to the needs of real people.
Here’s an overview of the changes we’ve made.
The Namespace is dead. Long live the Package.
The concept of namespaces evolved into something so close to Java packages, that we decided to rename it. The namespace keyword is replaced by package keyword. Additionally, namespace blocks are no longer supported.
The Arrow loses weight
An arrow is used in function literals and when expressions. Some languages use a “fat arrow” (=>) and some use a “thin arrow” (->). Initially, we used the fat one, but is has some unfortunate interactions with comparisons, like this:
val higherThanY = {x => y <= x}
So we decided to switch to a thin arrow:
val higherThanY = {x -> y <= x}
More readable function types
In the old syntax we wrote function types as follows:
val f : fun(Int) : String
which is very close to Kotlin’s function declaration syntax, and seems perfectly logical. Unfortunately, as this feature starts interacting with others, things get a lot worse:
fun max(col : Collection<Int>, compare : fun(Int, Int) : Int) : Int
Have you got lost in colons? Yes, me too…
So we decided to change the function type syntax to the following:
fun max(col : Collection<Int>, compare : (Int, Int) -> Int) : Int
And a little more
Additionally, we introduced optional parentheses in types, changed the tuple syntax to be distinguishable from parenthesized expression lists and made some minor (backward compatible) changes. All this will be reflected in the docs soon. As usual, your feedback is very welcome.
Stay tuned, and don’t miss the announcement next Tuesday!
It looks very good.
Public preview == downloadable compiler?
A downloadable compiler will be available a little later. This preview is a web app that allows you to write Kotlin programs (using online error highlighting and code completion) and run them.
So it will be possible to download compiled jar?
As of Jan 10th the app will be running on our server for you to use it.
Mmm. Are you planning some sort of cloud-based IDE?
Not a full-featured IDE, but some basic web-based editor with completion and error highlighting.
I’m confused, isn’t the web demo already available at http://kotlin-demo.jetbrains.com/ ? I saw a link to it on Reddit 2 weeks ago or so.
That being said, the web demo seems to cause Chrome to kill the page, I’m getting the “Aw Snap” message (although it has worked in the past).
I’m afraid, we rolled out a broken applet once, so now you’d have to clear your browser cache to make it work. If this does not help, please tell me. Thanks
“The Great Syntactic Shift” -> “The First Great Syntactic Shift”
Make it a bit easier for historians of the future!
Do you plan to support Unicode characters in the source code?
>= ≥
⇒
→
But in current font in Idea those arrows don’t look readable. And additionally, UTF-8 must be default encoding in IDE to my taste.
val higherThanY = {x ⇒ y ≤ x} // Even not so bad now!
I don’t have a ≥ key on my keyboard, so I don’t know how I’d benefit from such a thing in the code…
I don’t think this is a good idea, in exchange for a little visual sugar you are going to cause all sorts of headaches for people with editors that have poor Unicode support, and for people with a poor understanding of Unicode.
If in doubt, leave it out
Well, with Unicode support it might have been even not so bad:
val higherThanY = {x ⇒ y ≤ x}
val higherThanY = {x → y ≤ x}
Just to show how ugly it looks now:
val higherThanY = {x -> y <= x}
I hope this needs just a tiny change in parser code and new option in Idea's Automcatic Code Formatting preferences.
Wouldn’t it be easier to change your font?
Will there be an IntelliJ plugin for the preview?
As of January, the plugin is going through the private preview.
Terrific!
can’t wait to get my hands on the eclipse plugin, when it comes out (I have absolutely no knowledge of plugin coding for eclipse, but if no one is working on an eclipse plugin currently, I’m ready to get my hands dirty)
Sounds great! Feel free to contact me in regard to this: andrey dot breslav at jetbrains dot com
An Eclipse plugin would be awesome, however be careful that you aren’t biting off more than you can chew. They’ve been working on an Eclipse plugin for Scala for several years, including several complete rewrites, and they still aren’t there yet. If you do plan on doing this you should research the design of the Scala Eclipse plugin.
Thanks for the info. May I ask you some questions about this when we start working on Eclipse integration?
Are you planning to release Kotlin plugin for Maven? If you’re not working on it, I am ready to offer my services to develop it (have some experience in this field).
Hi Pavel,
Many thanks for suggesting your services. I work on Kotlin integration with the build tools (Ant, Maven and Gradle are in the plans so far). Can you drop me a line (evgenyg at gmail) so that we’ll have your coordinates?
Thin arrow VS fat arrow VS no arrow
What if a ruby style for closures?
val higherThanY = {|x| y <= x}
First of all, it doesn’t look pretty
Then, parser recovery gets messier when using the same character as opening and closing parenthesis at the same time. And it is not really clear where to put the function return type in the complete form. And a short form (without braces) looks weird when takes no arguments…
So we decided to change the function type syntax to the following:
fun max(col : Collection, compare : (Int, Int) -> Int) : Int
Humm… Is it supposed to be
fun max(col : Collection, compare : (Int, Int) -> Int) -> Int
or am I missing something?
The main reason for this change was getting read of repetitive commas that look like a mess. With the second option you refer to we get exactly the same.
That’s why we changed only the function type syntax and not function declaration syntax, so that the first option you refer to is correct.
Mathematically an expression (Int,Int) -> Int is correct and means “a map from set of Int*Int to integer set”. But I find that the arrow “->” looks a little ungly (like rest of mathematical symbols
, rather difficult to type and uncondence whole type declaration. The alternative way is to use more verbose notation for a functional type like Int(Int,Int). It means “Integer that depends on two parameters of integer type”.

Thus:
val str : String // declares a value of type String
val f : String(Int,Int) // declares a function of type (Int,Int) -> String
fun max(col : Collection, compare : Int(Int, Int) ) : Int
val max : Int( col : Collection, compare : Int(Int, Int) ) //
I think no one will confuse this syntax with a constructor call while it is used only where type declaration is required.
There are two things to remember here:
First, a function type may describe an extension function, and thus might need to specify a receiver type. For example:
val arr : MyArray = ...
val get : MyArray.(Int) -> Int = ...
val i = arr.get(10)
Second, return types in Kotlin go after the declared element
Personally I quite like (Int, Int) -> Int, and prefer it relative to Int(Int, Int).
I was reading the dart website (this article: http://www.dartlang.org/articles/idiomatic-dart/) and one thing I was happy about top-level definitions, i.e. not having to put everything inside a class. This is something that annoys me in Java because often I have static functions (or fields) which don’t really fit in any class, but I have to put them in some class. It also makes classes a lot more confusing to read, because I end up with all these random static functions, fields, etc. mixed in with my classes.
Does Kotlin allow top-level definitions of functions and fields? I probably missed it in the docs, but it wasn’t clear to me from skimming the docs.
Whether you call it a namespace or a package, I don’t mind
Yes, we allow toplevel definitions.
I had great hopes from the title that you would be sorting the order of the type declarations. You’ve improved the colon confusion a little, but not enough to really make things suitable. The colon itself is the problem, caused by putting the type after the name. Remember that Scala users place the colon next to the variable name to help the colon disappear – its that bad.
Don’t get me wrong, this is better than before:
fun max(col : Collection, compare : (Int, Int) -> Int) : Int
but, it still places too much emphasis on the colons and the hanging return type at the end. (the colon is larger than the comma, so your eye tends to divide by colon, not comma, which is wrong)
And this always looks bad with default arguments, because it looks like the value is assigned to the type, not to the variable:
fun max(str : String = “foo”) : Int
Note that simply correcting the order doesn’t solve the problem either:
fun Int max(Collection col, (Int, Int) -> Int compare)
Remember the goal here is *readability* – and that requires the human brain to treat the type as a single unit when visually parsing (the human eye sees patterns, and the spaces and colons cause the pattern recognition to see different element parts, rather than whole elements). Compare these three:
fun Int max(Collection col, (Int, Int) -> Int compare)
fun Int max(Collection col, (Int, Int -> Int) compare)
fun Int max(Collection col, {Int, Int -> Int} compare)
Note how the eye can more easily group the elements to form a single type in the latter two. (When reading the signature, the first level of knowledge is that it is a function type – the types of the function type are second level knowledge).
Now adjust it again, and you get something interesting:
fun Int max(Collection col, Fn compare)
A function is essentially a parameterization, so why not express it as such. (BTW you could continue with an arrow, but it doesn’t look as good). Note that this can be prefixed by “MyArray.” for the receiver type.
val MyArray.Fn get = …
My main point though is that it is really important to *group* the function type as a single element in the human eye, so that the brain parses it as a single unit (ie, some form of surrounding brackets). Otherwise, the brain has to re-associate the separate parts to form a whole type – and it is that which makes the language less readable.
Darn blog eating HTML. The last two examples should be
fun Int max(Collection col, Fn<Int, Int: Int> compare)
val MyArray.Fn<Int, Int: Int> get = …
var s1 : String = s.toString()
To me, at first glance, it looks as though something is being assigned to a String.
var String s1 = s.toString()
would be better IMO
This question (whether type should go before or after the name) is also related to what one considers more important — the name or the type? In Java I’m usually searching for name first and if the name doesn’t tell me the type then I’m reading the type expression.
I have to agree. It’s a lot easier to read and understand without the colons and with the type in front.
This one:
fun Int max(Collection col, {Int, Int -> Int} compare)
is clearest declaration in my opinion, but you’re right: the colons are too distracting.
I hope Jetbrains take a look at this.
Interesting, I do not agree here.
What you consider clearest declaration is in no way best for me, although indeed the best for leading types.
Stephen Colebourne
> (the colon is larger than the comma, so your eye tends to divide by colon, not comma, which is wrong)
Then your eye must be trained different to mine. My eye tends to separate on comma, while the colon is kind of glueing two things for me. Much more as I tend to add a space to the comma, but not to the colon.
So in
(some:thing, other:thing)
I feel a strong binding of some to thing, what I do not feel in
(some thing, other thing)
That is too, why I tend to misread
( some, more -> thing)
as being some with an additional more -> thing . Comma separates a lot. Comma space much more.
Beside that, leading or trailing type doesn’t matter, when the separator is the space, like in Java/C or Google’s Go:
(name type, name type) vs. (type name, type name)
I always have to look at the position to decide what a word semantically is. parameter or type ?
The colon (or the arrow btw) clearly display a tag for what’s coming. These are markups that I immediately look for when searching the type in an expression.
So, as I separate by comma, it is easier to find the name always as first thing in the snippet:
(name type, name more<complex<type>:>)
fun Int max(Collection col, Fn<Int, Int: Int> compare)
is horrible. My eye at a glance separates:
Collection col
followed by
Fn<Int
followed by
Int:Int>
followed by
eventually the name of the parameter.
(BTW: You see that I do not feel a strong bracing of < and >, why I prefer Scala’s square brackets over Java’s angle brackets too.)
So much emphasis is placed on the technical aspect of all these new languages that it often sounds like there is little time left to look at the code from 2ft away, to see how the most obvious parser will process it. Call me old fashion but, whatever a grammar says, if the brain reads something else, I would not bet the house on the long term chances of that language.
If we were anywhere else but in the software industry, the answer would be obvious… run a blind test. But instead we are in the software industry where the few never even question that they would have all the answers for the many. Kotlin has some really appealing features… make it intuitive for switchers to embrace it and the sky is the limit…
I so much agree.
Return types at the end and the resulting colon clutter are the two things I immediately dislike about Kotlin. If it was not for that, I am sure this language would be adopted like wildfire.
It’s great. I can’t wait to use it. Does it support OSGi?
You can run Kotlin programs in OSGi environment as well as Java programs.
So cool. Would you provide some examples on how to build&run kotlin programs in OSGi enviroment in the near future?
We are not planning to dedicate much effort to framework integration in the closest time frame, but after the compiler is opensourced (which will be most likely February), anyone can do this.
It is likely too late for this suggestion, even if it would otherwise be considered. But anyway …
Please consider offering naming arguments at each call site, rather than exclusively positional arguments. Positional would (of course) still be available as before.
Smalltalk syntax version of call site (call site readability far more important than any other
smartCar goTo: aLocation via: someViaPoints by: aDeadline
There are several options to retain interoperability with Java, such as compiling to more than 1 method names (aliases). And with some modification (e.g. goTo instead of goTo: ) this can be considered a generalization of your optional-parenthesis for function call with 1 argument.
This is already implemented in some form. See this page
There are still a lot of colons. And in “Longer examples” it can be clearly seen.
Generic:
fun cloneWhenGreater<T : Comparable>(list : List, threshold : T) : List where T : Cloneable {Also inheritance is hard to read because constructor in class definition line. Maybe it is better to make default method, like python __init__.
No! Now I have to throw my multithousnd lines fantasy-project over board.