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
*
2
In 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 it
Generic 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 itself
So, the vararg builder must be a type that has
- A constructor that takes one Int parameter
- An add() function
- A build() function
The type of the vararg parameter if the returned type of build().
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 = -1
Named 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
-
this
This 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:
lock
(
lock
)
{
sharedResource
.
operation
(
)
}
This makes our code look more like a 'control structure'.
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 be it:
ints
map
{
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.
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.
![]() | Inline functions are not implemented yet See the corresponding issue. |
66 Comments
comments.show.hideJul 22, 2011
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?
Jul 23, 2011
Andrey Breslav
We are considering support for C#-like yield
Jul 23, 2011
B. K. Oxley (binkley)
I would love to see "yield". For generators and other lazy sequences, it is magical.
Jul 22, 2011
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!
Jul 29, 2011
Anonymous
I agree that "fun" is difficult to visualy parse. I'd rather see "func".
Jul 22, 2011
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:
Jul 23, 2011
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
Jul 23, 2011
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.
Jul 24, 2011
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.
Jul 23, 2011
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.)
Jul 24, 2011
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.
Jul 28, 2011
Anonymous
So then it really IS like java.lang.Void, which has exactly one value -- the null pointer.
Jul 28, 2011
Andrey Breslav
Jul 26, 2011
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.
Jul 27, 2011
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
Jul 27, 2011
Anonymous
oh i see. so no point-free then.
Jul 27, 2011
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.
Jul 27, 2011
lacroix1547
I have had this reflection too at some point about boolean parameters inside languages in general.
Somehow
is better than
Jul 28, 2011
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.
Jul 28, 2011
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.
Jul 28, 2011
Andrey Breslav
You can escape "}" with a backslash
Jul 31, 2011
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.
Aug 11, 2011
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.
Aug 11, 2011
lacroix1547
Jan 08, 2012
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.
Aug 23, 2011
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))
?
Aug 23, 2011
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:
fun
MyClass
.
getName
(
inLowerCase
:
Boolean
=
false
)
:
String
myObjects
.
sortBy
{
it
.
getName
(
inLowerCase
=
true
)
}
Nov 02, 2011
Anonymous
What is the scope of "it"? How nested "it" are managed?
Nov 02, 2011
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.
Nov 02, 2011
Anonymous
So having
we couldn't say to which braces "it" corresponds to, right?
Nov 02, 2011
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.
Nov 02, 2011
Anonymous
thanks
Nov 11, 2011
Anonymous
Does Kotlin support dispatching based on the runtime type of its arguments?
Nov 11, 2011
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
Nov 22, 2011
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.
Nov 22, 2011
Andrey Breslav
A few questions:
Thanks for your replies.
Nov 22, 2011
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.
Nov 22, 2011
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.
Nov 22, 2011
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
Nov 22, 2011
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.
Nov 22, 2011
Andrey Breslav
KT-593: Only functions that are annotated appropriately should be allowed in infix calls
Jan 08, 2012
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.
Jan 08, 2012
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.
Jan 12, 2012
Vasiliy Kudriavtsev
Will the following work:
fun
main
(
args
:
Array
<
String
>
)
{
val
result
=
testMultipleReturn
(
"
test1
"
,
"
test2
"
)
;
System
.
out
?
.
println
(
result
.
value1
)
;
// INSTEAD OF ._1
System
.
out
?
.
println
(
result
.
value2
)
;
// INSTEAD OF ._2
}
fun
testMultipleReturn
(
inValue1
:
String
,
inValue2
:
String
)
:
#
(
value1
:
String
,
value2
:
String
)
{
return
#
(
inValue1
,
inValue2
)
;
}
I would be nice to have this feature.
Jan 12, 2012
Andrey Breslav
Yes, it will, once implemented. See [Tuples].
Jan 27, 2012
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.
Jan 27, 2012
Andrey Breslav
Yes, we are planning to support this.
Oct 04, 2012
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.
Oct 04, 2012
Andrey Breslav
Fixed, thank you
Mar 02, 2013
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 :
Mar 04, 2013
Andrey Breslav
Not yet, but we are working on it: http://youtrack.jetbrains.com/issue/KT-1183
Jul 08, 2013
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:
Jul 08, 2013
Andrey Breslav
It's a bug
Jul 08, 2013
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?
Jul 09, 2013
Andrey Breslav
I think is is.
Jul 08, 2013
Mohammad Shamsi
This is kind of confusing:
Jul 08, 2013
Mohammad Shamsi
few minor issues in the page:
- in varargs example
- in Higher-order functions
- Do we still need 'tuples' section?
Jul 08, 2013
Andrey Breslav
Fixed. Thank you!
Aug 22, 2013
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
Aug 22, 2013
Andrey Breslav
Not supported yet, but will be. See this blog post, under "First steps in callable references"
Oct 08, 2013
Matt Gile
Could Kotlin support fluent style by default, such that any method that returns Unit implicitly returns "this", allowing method chaining. for example
Oct 08, 2013
Andrey Breslav
This would affect other aspects of the language in an undesirable way.
Oct 11, 2013
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;
Oct 11, 2013
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.
Dec 19, 2013
Vladimir Alekseev
It may be useful for tiny fuctions to use unnamed parmeters. I mean
also this wil shorten some literals
vs
Dec 19, 2013
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