Functions in Kotlin are declared with the fun keyword:
fun double(x : Int) : Int { return x * 2 }A function call goes in the traditional way:
val two = demo(1)See also Infix calls and Operator overloading.
Single-expression functions
If a function just returns a value of a single expression, one can specify its body after '=' and with no return statement:
fun double(x : Int) : Int = x * 2In this case, it is allowed to omit the return type annotation, and the type will be inferred from the expression on the right-hand side:
fun double(x : Int) = x * 2
Unit-returning functions
If a function does not return any useful value, its return type is Unit. Unit is a type with only one value — Unit.VALUE. This value does not have to be returned explicitly:
fun printHello(name : String?) : Unit { if (name != null) print("Hello, $name!") else print("Hi there!") // We don't need to write 'return Unit.VALUE' or 'return', although we could }Neither has the Unit return type to be specified explicitly:
If a function has a block body (in curly braces, not after '=') and returns Unit, one can omit the return type annotation:
fun printHello(name : String?) { //... }Local functions
Kotlin supports local functions, i.e. one can define a function inside a function:
fun dfs(graph : Graph){ fun dfs(current : Vertex, visited : Set<Vertex>) { if (!visited.add(current)) return for (v in current.neighbors) dfs(v, visited) } dfs(graph.vertices[0], HashSet()) }Local functions can "see" local variables of outer functions (i.e. the closure), so we can have our visited set as a local variable, not a parameter to always pass around:
fun dfs(graph : Graph){ val visited = HashSet<Vertex>() fun dfs(current : Vertex) { if (!visited.add(current)) return for (v in current.neighbors) dfs(v) } dfs(graph.vertices[0]) }Local functions can even return from outer functions using qualified return expressions:
fun reachable(from : Vertex, to : Vertex) : Boolean { val visited = HashSet<Vertex>() fun dfs(current : Vertex) { // here we return from the outer function: if (current == to) return@reachable true // And here -- from local function: if (!visited.add(current)) return for (v in current.neighbors) dfs(v) } dfs(from) return false // if dfs() did not return true already }Member functions
A member function is a function defined inside a class:
class Sample() { fun foo() { print("foo") } }Member functions are called with a dot:
Sample().foo() // creates a new object of Sample and calls foo() on itGeneric functions
Functions may have generic parameters which can be specified in angle brackets after the function name and before the value parameters:
fun singletonArray<T>(item : T) : Array<T> { return Array<T>(1, {item}) }More on generic functions can be found on the page dedicated to generics.
Varargs
The last argument of a function may be marked with vararg annotation:
fun asList<T>(vararg ts : T) : List<T> { val result = ArrayList<T>() for (t in ts) // ts is an Array result.add(t) return result }By default, vararg creates an array, but this behavior can be customized by providing arguments to the annotation:
fun asList<T>(vararg<ArrayList<T>> ts : T) : List<T> = ts // ts is a List now!The type argument to the vararg annotation denotes a builder type. A call to this function is compiled like this:
asList(0, 1, 2) // Compiles to val list = ArrayList<Int>(3) // 3 is the size of the structure list.add(0) list.add(1) list.add(2) asList(list.build()) // For ArrayList, build() just returns the list itselfSo, the vararg builder must be a type that has
- A constructor that takes one
Intparameter - An
add()function - A
build()function
The type of the vararg parameter if the returned type ofbuild().
Default arguments
Function parameters may have default values, which are used when a corresponding argument is omitted. This allows to reduce the number of overloads, compared to Java:
// In java.io.InputStream this function has two versions: fun read(b : Array<Byte>, off : Int = 0, len : Int = -1) { val actualLength = if (len == -1) b.length else len // ... }This function may be called in three forms:
read(b, off, len) read(b, off) // len = -1, effectively, b.length read(b) // off = 0, len = -1Named arguments
When a function has many parameters (and many of them have defaults), it is very convenient to see parameter names at the call site. Consider the following function in:
fun reformat( str : String, normalizeCase : Boolean = true, uppercaseFirstLetter : Boolean = true, divideByCamelHumps : Boolean = false, wordSeparator : Character = ' ' ) { // ... }The best-case call site is fine:
reformat(str)But what if we want to change the word separator without changing the flags?
reformat(str, true, true, false, '_')Without named arguments, a call site is hard to read. To document it, we can provide parameter names for each argument:
reformat(str, normalizeCase = true, uppercaseFirstLetter = true, divideByCamelHumps = false, wordSeparator = '_' )It is better already, but we can improve it: there's no need to specify all the arguments if some of the default values are fine for us:
reformat(str, wordSeparator = '_')Infix calls
If a member function (or an extension function) takes one parameter, it may be called in infix form, i.e. without a dot after receiver and parentheses around the arguments:
1 shl 2 // is the same as 1.shl(2)An infix call must have two parameters. One is not allowed to say, e.g. print 1, because there's nothing on the left of print.
Infix calls associate to the left, i.e. 1 foo 2 bar 3 means (1 foo 2) bar 3.
For precedence, see the grammar.
Extension functions
Extension functions allow us to define a function having some type as a receiver:
fun Int.abs() : Int = if (this >= 0) this else -thisThis function can be called on any Int with a dot, as if it were a member function:
print((-1).abs())For more details, see Extension functions.
Higher-order functions
A higher-order function is a function that takes functions as parameters, or returns a function. A good example of such a function is lock() that takes a lock object and a function, acquires the lock, runs the functions and releases the lock:
fun lock<T>(lock : Lock, body : () -> T) : T { lock.lock() try { return body() } finally { lock.unlock(); } }Let's examine the code above: body has a function type: () -> T, so it's supposed to be a function that takes no parameters and returns a value of type T. It is invoked inside the try block, while protected by the lock, and its result is returned by the lock() function.
If we want to call lock(), we can pass a function literal to it as an argument:
val result = lock(lock, { sharedResource.operation() })Function literals are described in details on this page. Here we only give a superficial description:
- a function literal is always surrounded by curly braces,
- its parameters (if any) are declared before
->(parameter types may be omitted), - the body goes after
->.
In our case, there are no parameters, and the expression in the curly braces is the function literal body.
There is a convention in Kotlin that makes our example look nicer:
- if the last parameter of a function is itself a function, the corresponding function literal may be passed outside the parentheses:
This makes our code look more like a 'control structure'.
lock(lock){sharedResource.operation()}
Another example of a higher order function would be map() (of Map/Reduce):
fun <T, R> List<T>.map(transform : (T) -> R) : List<R> { val result = ArrayList<R>() for (item in this) result.add(transform(item)) return result }This function can be called as follows:
val doubled = ints.map {it -> it * 2}One other convention helps us here:
- if a function literal has only one parameter, its declaration may be omitted (along with the
->) and its name will beit:intsmap{it*2}// Infix call + Implicit 'it'
These conventions allow us to write LINQ-like expressions:
strings filter {it.length == 5} sortBy {it} map {it.toUpperCase()}Extension function literals
Like named extension functions, function literals may declare receiver parameters. This allows us to write things like Groovy-style builders in a type-safe way.
Inline functions
Using higher-order functions imposes certain runtime penalties: each function is an object, and it captures a closure, i.e. those variables that are accessed in the body of the function. Memory allocations (both for function objects and classes) and virtual calls introduce runtime overhead. Plus, classes generated for lambdas bloat the bytecode on disk and PermGen at runtime.
But it appears that in many cases this kind of overhead can be eliminated by inlining the function literals. The functions shown above are good examples of this situation. I.e., the lock() function could be easily inlined at call-sites. Consider the following case:
lock(l) {foo()}Instead of creating a function object for the parameter and generating a call, the compiler could emit the following code:
lock.lock() try { foo() } finally { lock.unlock() }Isn't it what we wanted from the very beginning?
To make the compiler do this, one needs to annotate the lock() function with the inline annotation:
inline fun lock<T>(lock : Lock, body : () -> T) : T { // ... }Inlining may cause the generated code to grow, but if we do it in a reasonable way (do not inline big functions) it will pay off in performance, especially at "megamorphic" call-sites inside loops.
General guidelines for what functions should be marked inline:
- Do not inline big functions.
- The primary purpose of inline function is to inline lambdas at call sites. It is rarely a good idea to inline a function that does not take other functions as arguments.
Some functions can not be inlined. For example, if you do not call a lambda argument, but use it as a value (e.g. put it into a map).
The compiler will refuse to accept inline annotation on such functions.
By default, all functional parameters are inlined at the call site, if you want some of them to be passed as values instead, annotate these parameters with noinline:
inline fun twofun(a: () -> Int, noinline b: () -> Int) { a() // only call: fine for inlined parameter mylist.add(b) // add to collection, fine only for noinline parameter }



79 Comments
Weeble
The LINQ-like example with infix calls looks really nice. How hard is it to write map and filter if you want lazy evaluation instead of eager? Is there anything like C#'s iterators or Python's generators? Or would you just need to write your own Iterable<T> subclass?
Andrey Breslav
We are considering support for C#-like yield
B. K. Oxley (binkley)
I would love to see "yield". For generators and other lazy sequences, it is magical.
Anonymous
A very interesting approach to a new language, i like most of your ideas, really.
Having tuples, multiple inheritance and the property syntax are some of the things i really missed in my java experience.
But there's one thing i don't like and that's the abbreviation of the "function" keyword as "fun"!
There are two reasons, why i don't like it, one is the meaning of the "word", but the other is more important to me.
I don't know why it is the way like it is, but somehow most of the keywords used in expressions and such are relatively short while the keywords denoting major constructs like "namespace", "class", "module" and also "return" are relatively long.
So maybe it's something about code readability.
I vote for using "function" as the keyword for denoting functions!
Anonymous
I agree that "fun" is difficult to visualy parse. I'd rather see "func".
Kevin Hinners
I agree with this comment. The keyword "fun" to denote a function just doesn't seem right. I am okay with "function". I believe command-line completion would take care of having to type out the whole word. If you want to have an abbreviation, I would prefer "fn" or maybe "func".
Anonymous
How does function/method overloading work in the presence of function types? E.g., is it possible to declare:
And also overload it with:
Andrey Breslav
No, this is not possible in Kotlin. Partly because the Java platform constrains us, partly due to difficulties in type inference, and mostly due to being a discouraged practice. You can have overloads that differ in function arity, though, for this is very visible at the call site
Anonymous
The syntax for named function arguments seems risky/confusing to me. There is potential confusion between an identically named local variable at the call site and a function parameter used as a named function parameter. For instance, if I see code like this:
val foo = bar(baz=qux);
I can't tell if this is a local variable named "baz" being assigned to qux before being passed into foo, or whether it is a named function parameter named "baz" being passed the value qux.
I would like to see some sort of different syntax used to refer to function parameter names, so that it is clear when reading a code whether the name refers to a function parameter name or not. Perhaps a leading "@" or "#" or some other character on the function parameter name? Or using ":=" or "::=" instead of "=" as the separator between the variable and its value? Making these syntactically distinct could also speed up compilation, since the compiler would know ahead of time whether to search for the named variable in the calling scope or in the function declaration scope.
Andrey Breslav
Note that assignment cannot be used as an expression in Kotlin, so foo(bar = 1) is always a call with a named argument, and never an assignment.
Anonymous
The name "Unit" seems very nonintuitive to me for what this class does. I would expect a class with a name like Unit to be associated with things like meters, inches, kilograms, and furlongs per fortnight, not for it to be the class associated with methods that don't return any values. I'd like to see this class renamed to something that more clearly expressed its purpose in the language. Something like Empty or Void, perhaps. (It seems to serve in some ways a similar purpose to java.lang.Void, as far as I can tell, so that might be a good choice.)
Andrey Breslav
The type Unit is not empty (empty type is Nothing). It's a singleton type, i.e. has only one value in it.
Anonymous
So then it really IS like java.lang.Void, which has exactly one value -- the null pointer.
Andrey Breslav
Anonymous
0. How easy it is to pass member function to some another function?
1. Did you consider adding support for partial applications?
2. Infix notation is nice; did you also consider adding $-notation (like in Haskell)? It allows to get rid of many parentheses.
Andrey Breslav
0.
foo {a.bar()}1. Not as a language feature, but you can do this: {{ {1 + it} }}
2. I don't see a way of making this efficient
Anonymous
oh i see. so no point-free then.
Anonymous
Your example for named arguments is another good illustration that boolean values in function call make the code unreadable. Instead of named arguments I would consider redefining true/false for booleans in function definition. For example:
in function call could be used as:
I added # to distinguish normalizeCase parameter name from a local variable possibly having the same name. Exclamation stands for boolean NOT. That syntax is much shorter from caller's point of view. It's the same as if I would define a local variable called #normalizeCase with the value of true.
I also join the opinion that "fun" abbreviation looks ridiculous. I would vote for "function" too.
lacroix1547
I have had this reflection too at some point about boolean parameters inside languages in general.
Somehow
is better than
Anonymous
One of the pieces of advice from the book "Writing Solid Code" that has stuck with me over the years is that in many (most?) cases, it is better to use two-element enumerations than it is to use booleans. Some reasons include:
1) The enumerator names are self-documenting. It is clear that "enum PaintColor {RED, GREEN}" that the constant RED refers to the color red. It is less clear in the function call "doPaint(true)" that the parameter 'true' is being passed to indicate that the painting should be done in red.
2) You can do an IDE search on "RED" to find all places it is referenced. It is hard to do a search on "true".
3) You can do an IDE search on "PaintColor" to find all places that the type is referenced. It is hard to do a search on "boolean".
4) You can add additional methods to the enum if you need to (e.g. "toString()" or "getRGB()" that would otherwise be scattered auxiliary functions if you were passing booleans around instead.
5) If you decide that a third option is needed, you don't necessary have to rewrite all of your code to use a different type or pass a second boolean flag.
6) The enums provide extra type safety and hence mistake prevention. You remove the possiblity that you might accidentally swap two booleans being passed into a method call, which the compiler couldn't detect.
In Java, using enums this way is a little bit annoying since by using one, you always introduce a third possibility of passing 'null' that unctions receiving an enum parameter must be wary of. It seems that Kotlin will not have this problem.
Anonymous
I'm not sure how that "Unknown macro: " phrase with its associated line breaks got into the above text. Please ignore it. Apparently the wiki is somehow trying to interpret text inside curly braces as commands.
Andrey Breslav
You can escape "}" with a backslash
Anonymous
Fun Pros:
-Has three letters just like "val" and "var".
-Quicker to type
-Takes less real estate on a line
Fun Cons:
-It collides with a cute and un-enterprisy dictionary word.
-"function" is too much of a sacred and sexy word to be abbreviated.
Rustam Vishnyakov
I think "func" looks more like an abbreviation from "function". At the same time it has the same pros, just one extra character doesn't make a big sense.
lacroix1547
Ryan Flegel
It might seem trivial, but I don't like "fun", either. When I read it, I don't think "function" right away and it just seems kinda silly (funny? :-). I don't think "function" needs to be abbreviated at all. The abbreviated version doesn't really add any value, so why not just use "function" as the keyword?
That being said, if an abbreviated form must be used, then I would prefer "func", because it at least makes me think "function".
On var/val: Again, no real value from shortening them, but they're consistent with Scala (and other languages, I'm sure), and they make me think "variable" and "value", so I have no issue with them.
Leonid Bushuev
One question related functions.
Lets imaging the library function requres a function with one argument, like the following one:
fun List<T>.sortBy(f: fun(x:T))
And for my class, I've got a function with two arguments:
getName (x: MyClass, inLowerCase: Boolean = false): String
So does Kotlin accept something like the following
myObjects.sortBy(MyClass.getName(inLowerCase = true))
?
Andrey Breslav
No. Currying is not supported in this form. What you can do is:
myObjects.sortBy{MyClass.getName(it,true)}or better make use of extension functions:
funMyClass.getName(inLowerCase:Boolean=false):StringmyObjects.sortBy{it.getName(inLowerCase=true)}Anonymous
What is the scope of "it"? How nested "it" are managed?
Andrey Breslav
The scope of it is the function literal it is defined for. Since it is a normal variable (just implicitly declared), so when a nested scope defines another it, it will shadow the declaration of the outer scope.
Anonymous
So having
we couldn't say to which braces "it" corresponds to, right?
Andrey Breslav
If we are the person reading this code, then the answer is no, if we don't know what parameters b and d expect. Of course, IDE tells us if we ask.
Anonymous
thanks
Anonymous
Does Kotlin support dispatching based on the runtime type of its arguments?
Andrey Breslav
No, since there's no efficient way to implement it + multiple-dispatch complicates class hierarchy semantics.
See discussion in this paper: http://www.cs.cmu.edu/~donna/public/oopsla09.pdf
Chris Kent
The infix call syntax makes me nervous and is the thing I like least about Kotlin. It's also one of my least favourite features of Scala. It has the potential to make code look very inconsistent and therefore be much less readable.
When would developers be expected to use the infix form instead of a normal call? Always? Under certain special circumstances? When they feel like it? I also don't like the way it makes calls with a single argument look completely different from all other function calls. They aren't fundamentally different, they only differ by the number of arguments.
I think the flexibility for writing DSLs and the nice examples it enables are too high a price to pay for the inconsitency it introduces.
Andrey Breslav
A few questions:
Thanks for your replies.
Chris Kent
One of the main things that put me off Scala in the end was the flexibility of the syntax. Developers can't resist pushing things as far as they can and some of the results are very difficult to read and understand. Kotlin has already avoided one of Scala's biggest problems by not allowing arbitrary operators. I think the arbitrary use of infix function calls is another thing Kotlin would be better without.
I don't think the example looks too bad using normal function calls:
Doesn't look significantly different from:
One of the key things about LINQ is that the infix syntax can only be used inside LINQ expressions. Method calls everywhere else in C# use the dot syntax. LINQ expressions are a separate world where different syntax rules apply.
Andrey Breslav
You are making a fair point.
One problem with what you propose would be the inability to call a infix function on a nullable receiver (no ?. operator). Currently you can't call an infix '+' on a nullable Int, but have to fall back to the longer form a?.plus(b), this would be impossible for infix-only functions.
Chris Kent
I hadn't thought of that. How about this: functions declared as infix can be called using either syntax. Functions that aren't declared as infix can only be called using the conventional syntax.
I think the biggest problem would be people choosing the infix syntax for calling normal functions. If a function is declared as an infix function I think people would probably choose the infix syntax anyway. And even if they didn't it would be OK, you'd get code like this which is easy enough to understand:
instead of
Andrey Breslav
This looks like a good idea. Actually, we have exactly this discussed yesterday, but it's not on the issue tracker yet. I'll file an issue. Thank you.
Andrey Breslav
KT-593: Only functions that are annotated appropriately should be allowed in infix calls
Ryan Flegel
My two cents on "inline"...
I don't really like the idea of an "inline" keyword. I'm not against inline functions, but I think that it should be completely up to the compiler to decide which functions would benefit from being inlined.
Some likely scenarios:
I think that if it was solely up to the compiler (with optional optimization settings/flags from the user) to inline functions, the resulting bytecode would generally be much more efficient and would save the programmer from having to worry about such things.
Andrey Breslav
The compiler your use cases are up to is JIT, not Kotlin compiler.
You need inline only when it prevents closure allocation or in very similar situations. Such functions do not tend to grow.
Plus, the compiler can warn you in the rare case of inlining a huge function many times.
Vasiliy Kudriavtsev
Will the following work:
funmain(args:Array<String>){valresult=testMultipleReturn("test1","test2");System.out?.println(result.value1);// INSTEAD OF ._1System.out?.println(result.value2);// INSTEAD OF ._2}funtestMultipleReturn(inValue1:String,inValue2:String):#(value1:String,value2:String){return#(inValue1,inValue2);}I would be nice to have this feature.
Andrey Breslav
Yes, it will, once implemented. See Tuples.
Ashwin Jayaprakash
The LINQ style example "stringsfilter {it.length==5} sortby {it} map {it.toUpperCase()}" looks very interesting from a DSL builder's point of view.
Does/will Kotlin provide a way to read the AST of a code fragment - like Java Reflection/Class API but with an actual AST of the method, closures and expressions?
1 usecase would be allowing the user to write type-safe queries/expressions in pure Kotlin, but at run time the expression will be "parsed" and transformed into a database query or a memcached/redis query.
Andrey Breslav
Yes, we are planning to support this.
Simon Kitching
Example of "Extension Function" has a couple of errors. First, function returns Int not Boolean..
And caller needs parentheses around a negative number because unary-minus binds less strongly than invocation.
Andrey Breslav
Fixed, thank you
Simon Patrick
Will it be possible to pass a named function directly as an argument to another function?
It could be even better if compiler could accept TArg.() -> TResult where (TArg) -> TResult is expected :
Andrey Breslav
Not yet, but we are working on it: http://youtrack.jetbrains.com/issue/KT-1183
Mohammad Shamsi
in the example that given for generic functions:
I keep facing ClassCastException when I'm trying to use it.
I've tried following approaches:
but the result is this exception:
Andrey Breslav
It's a bug
Mohammad Shamsi
And this is happening only in Array. If I change the function to:
It will compile and run successfully.
btw, is this bug logged in youtrack yet?
Andrey Breslav
I think is is.
Mohammad Shamsi
This is kind of confusing:
Mohammad Shamsi
few minor issues in the page:
- in varargs example
- in Higher-order functions
- Do we still need 'tuples' section?
Andrey Breslav
Fixed. Thank you!
Alexey Pomelov
Is there any way to pass a pointer to a an object's function as a function-type argument?
e.g. I have some traverse function, that processes some pairs. Also I have a parametrized processor class that can process such pairs.
Now I'd like to write
instead of
Andrey Breslav
Not supported yet, but will be. See this blog post, under "First steps in callable references"
Matt Gile
Could Kotlin support fluent style by default, such that any method that returns Unit implicitly returns "this", allowing method chaining. for example
Andrey Breslav
This would affect other aspects of the language in an undesirable way.
Matt Gile
I like the way Kotlin eliminates much of the boilerplate code, simplifying fluent style member functions would be helpful, especially in the case of subclassing or delegation.
For example
I can override each method just change its return type, but this laborious. Maybe generics can help?
This does work but is a bit tricky, it would be great if Kotlin made this better, more direct.
A class modifying annotation like 'data' could be added, called 'fluent'. Class or member functions annotated with 'fluent' would implicitly return this, unless method explicitly returned a value. This option also allows for compact, single line methods, which I love in Kotlin.
Another option is return a special type 'this' which would indicate this's type, that of this class or its sub-class. I believe this is the most flexible and obvious syntax;
Andrey Breslav
The generic version falls short of generality: doesn't play well with inheritance. That's why the "this" type version is very tricky to fit into the language design and is likely to complicate it significantly.
The annotation version may be an option indeed.
Vladimir Alekseev
It may be useful for tiny fuctions to use unnamed parmeters. I mean
also this wil shorten some literals
vs
Andrey Breslav
This doesn't seem to be beneficial: we read a lot more code than we write, and having nameless parameters obscures their meaning
Kurt Sys
Just wondering: since Kotlin is compatible with Java6, does this mean that functions are somehow wrapped in a kind of one-function objects (in Kotlin)? I'm mainly wondering because untill yesterday I thought Kotlin made use of the amazing invokedynamic-instruction for the fun stuff like functions and lambda-like expressions. However, this can't be true, due to compability with Java6.
Andrey Breslav
We are not using
invokedynamicfor now, and I'm sad dissappoint you: usinginvokedynamicsaves only some "one-function objects", by far not all of them.Kurt Sys
Hey Andrey, not such a big dissapointment, more like: how did you implement the function type? Can I compare it to some kind of "one-function objects'? Well, it's maybe up to me to find out :).
Andrey Breslav
We are doing it pretty much like Scala (and Java 8's approach is similar): there are predefined interfaces Function0 .. Function22 and lambdas are compiled to their intantiations
Kurt Sys
I don't know about Scala, however, I (think I) do know about java8, and it looks somewhat different (but again, I'm not sure if I got it right). In Java8, lambda's are not some kind of function type (which seems to be Kotlin's and Scala's approach, if I understand well?), nor is it syntactic sugar for inner classes. In Java8, lambda's are extracted as a static function.
That's where, in Java8, 'invokedynamic' and stuff comes in... (As far as I understood, they actually exposed invokedynamic to make lambda's work, with the benefit that that instruction is available from Java as well). That's why I was somewhat confused (not dissapointed :) ) about Kotlin. I might try to make some kind of small comparison between the different implementations (inner classes vs Kotlin's approach vs Java8's approach). Just for fun ;).
Thanks a lot!
Andrey Breslav
You are right that static methods play a big role there, and
invokedynamicmakes it possible to rely on static methods. But in fact, Java 8 creates instances of SAM-interfaces that lambdas are converted to nevertheless. Only these instances are more like proxy objects and their classes are created through runtime byte code spinning.Kurt Sys
The little bastards... So far, I never understood properly how exactly they managed to get it all done. It starts to make much more sense now :).
Kurt Sys
Just some thoughts that came up:
Andrey Breslav
2. For now we create an instance on every call. This will be optimized at some point. + We are working on inline functions that do not create any instances at all.
3. This is a mystery. Martin Odersky would be the next in the chain to ask, because we copied this number from Scala
Kurt Sys
Inlining would be pretty cool, indeed. And having 42 Function-interfaces would make Kotlin way cooler than Scala ;).
Red Smith
This comment is on another page, and it seems that it should be on this page as well:
"Non-local returns are not implemented yet
See the corresponding issue."
Andrey Breslav
Fixed. Thanks