Motivation
In Java, we are used to classes named *Utils: FileUtils, StringUtils an so on. The famous java.util.Collections belongs to the same breed. And the unpleasant part about these Utils-classes is that the code that uses them looks like this:
Those class names are always getting in the way. We can use static imports and get this:
This is a little better, but we have no or little help from the powerful code completion of the IDE. It would be so much better if we could say
But we don't want to implement all the possible methods inside the class List, right?
So, Kotlin (after C# and Gosu) introduces extension functions: a function declared outside the class List may be contributed to this type as an extension. This is denoted by prepending the receiver type (the one being extended) to the function name:
fun List<Int>.swap(x : Int, y : Int) { val tmp = this[x] // 'this' corresponds to the list this[x] = this[y] this[y] = tmp }The this keyword inside an extension function corresponds to the receiver object (the one that is passed before the dot). Now, we can call such a function on any List<Int>:
val l = list(1, 2, 3) l.swap(0, 2) // 'this' inside 'swap()' will hold the value of 'l'Of course, this function makes sense for any List<T>, and we can make it generic:
fun <T> List<T>.swap(x : Int, y : Int) { val tmp = this[x] // 'this' corresponds to the list this[x] = this[y] this[y] = tmp }We declare the generic type parameter before the function name for it to be available in the receiver type expression. See Generic functions.
Extension functions are resolved statically
To avoid confusion, we would like to emphasize that extension functions are resolved statically, i.e. they are not virtual by receiver type. On the other hand they can be member functions on some class and thus can be virtual in that class hierarchy.
Similar features in other languages
AspectJ has inter-type declarations.
Groovy has metaclasses.
Scala makes heavy use of implicit conversions, i.e. wraps values into adapters at runtime.
C# and Gosu have extension functions implemented similarly to our approach.

56 Comments
comments.show.hideJul 21, 2011
Anonymous
It is not clear how Extension Functions are registered. I assume you have to use import (as in Scala), but wiki page is not clear
I hope it is not registered globally as in Groovy and other dynamic languages.
Jul 21, 2011
Andrey Breslav
You are right, one uses import
Jul 21, 2011
Daniel Worthington-Bodart
It's a shame you used a custom mechanism to define extension methods rather than just saying that if the first argument of the static method is the same type as the object, it can be treated as a extension method or called classicly.
This would mean that all those hundreds of thousands of static methods defined in Java would be usable as extension methods rather than requiring them to switch to using your language. This would mean that you example would actually work even if the 'swap' method was in a plain old Java library.
Jul 21, 2011
Maxim Shafirov
It would definitely be bad idea to treat any static method be an extension to the type of it's first parameter. Indeed having all those hundreds of thousands methods in completion list for String or Int would be disaster
Jul 21, 2011
Daniel Worthington-Bodart
Lol, well they would not automatically be there, you would have to explicitly import then just like you do with static methods.
What about following C# extension methods, as at least you can call all those extension methods from other languages that don't support them (just treat them like static methods) or would the Kotlin compiler implicitly add a first argument to the method called 'this' anyway?
Jul 21, 2011
Maxim Shafirov
C# has explicit this on the argument so you cannot use arbitrary legacy static method as extension function either.
Jul 21, 2011
Daniel Worthington-Bodart
You miss understand, you can still call them from languages without extension method support, by providing the first argument explicitly. What would the signature of a Kotlin extension method look like from Java code?
Jul 22, 2011
Andrey Breslav
You'll be able to call our extension functions from, say, Java. As you have said, they just have an extra parameter.
Jul 22, 2011
Hubo
Is it possible to access private fields in extension method?Please ignore this question, just knew that there is no way to declare a field in Kotlin
Jul 23, 2011
Andrey Breslav
There's no way to access anything private in an extension function that is declared outside of the receiver class
Jul 31, 2011
lacroix1547
Can we rephrase that as, an extension function cannot access private or protected elements of its receiver.
Aug 01, 2011
Maxim Shafirov
More accurately extension function has the same access level as if it received the receiver instance among other parameters explicitly.
Aug 02, 2011
lacroix1547
Then, trying to conclude, why is the exotic syntax needed for the declaration of extention functions?
You surely tried to avoid introducing this extra syntax by trying to use "plain old static functions" as extension functions, but couldnt for some reason.
Yea I know, no static function in Kotlin but there is the equivalent and I am not sure how to call them.
"Class object functions" I guess, but it sounds like a tautology.
Aug 03, 2011
Andrey Breslav
Note that if you define
funString.foo(){...}it's called on objects of class String, not on the class itself:
"abc".foo()So your analogy to static functions and class object members seems to be irrelevant.
Aug 03, 2011
lacroix1547
Yes but isnt it just an illusion.
foo is not truly a member of String and doesnt have any access to String private members.
foo is not more privileged than any function inside your favorite StringUtils.
This is what I understand.
Aug 03, 2011
Andrey Breslav
That's right. It's only a syntactic difference
Sep 25, 2011
Anonymous
I agree the exotic syntax is unnecessary verbiage.
And it is a very narrow syntax, as does not aid extension where the function required its caller to supply a "view bound", i.e. page 483 of Programming in Scala. This can be accomplished in any language with an input parameter that is a function that inputs the type to be view bounded and returns the desired interface of the bound. The JIT can probably optimize away the runtime overhead.
If you are aiming for simplicity over Scala, then you don't want to add narrow duplicitous syntax. Aim for regularity and consistency instead. I would deprecate this while you still can.
-Shelby Moore III
Sep 25, 2011
Andrey Breslav
I don't see how absence of view bounds in Kotlin makes extension functions "unnecessary verbirage".
To date, there are rather many use cases, both in Kotlin and C#, where extension functions work very well. For example, consider this section.
Sep 25, 2011
Anonymous
I see how you use the feature for builders, but my point remains that I don't see why you need the special definition site syntax. Simply make all functions that input an object as the first parameter, callable as object.function(...) or function( object, ...). I don't see why you need to have another complex syntax to explain and users to memorize. The control over which functions are applied is done with import any way. If you need another vector of control, you could add an option on the import keyword, this would be more orthogonal because then any functions could be imported with either functionality.
It is your language, I am just offering my feedback, given I am also designing a language that is trying to simplify Scala. Any way, I am designing an immutable language, so we are not competing, and I sharing with you some of my design principles. Apologies.
I added a comment to the builder section. I will try not to bother you now. Good luck.
-Shelby Moore III
Sep 26, 2011
Andrey Breslav
Absolutely nothing to apologize for. We really appreciate your feedback and suggestions.
Overall, I think, your point about the overly big difference in syntax is valid.
A big problem with making any function callable in the "firstArgument.function(otherArguments)" form is that when you type in "foo." in an IDE, and press Ctrl+Space you don't really want all the functions that take the type of foo as the first argument in the completion proposal list, because only some of them are intended to be used this way.
C# uses this as a prefix to the receiver parameter of an otherwise regularly defined function. We could simply say
funexample(this:Foo,other:Bar){...}Instead of
funFoo.example(other:Bar){}And we are considering this as an option.
Sep 27, 2011
Anonymous
What I suggested in the prior comment is to enable batch control over which functions are classified as eligible, by specifying it on import, i.e. import name[this] ... instead of import name..., or something like that.
That way functions can be reused either way. I am thinking don't hardcode the option at the function site, but rather leave it optional at the import. Haven't thought about it too deeply though.
Sep 27, 2011
Andrey Breslav
Well, what happens if you have a function in scope already (by direct definition or inheritance)? Can you call it this way, or do you need to import something you already see to do it?
Sep 27, 2011
Anonymous
Hi, I am very glad I read this page, because it caused me to think deeply about extension. I think I now realize that we can't handle extension in this fashion. We need to handle it with the vtable and mixins, in order to be fully generalized and compositional. Which should also provide the explicit code completion intelligence control you desire as a side-benefit. I will email you now to the email address you have listed on your username, because I composed something (for my own language, and I think maybe it is applicable to Kotlin), but it is too long to post here, and which might require back-and-forth discussion that it might get unwieldy here. If there is any merit in my idea, perhaps we can report findings here after discussing it in email-- that is if you find my email interesting. I am not knowledgeable enough about vtables on JVM, so that is another reason I hesitated to post it here, until the idea has been vetted.
Best,
- Shelby Moore III
Sep 27, 2011
Andrey Breslav
Thanks a lot for your effort. It makes sense to submit your suggestion as an issue to our tracker:
http://youtrack.jetbrains.net/issues/KT
Email is also fine, if you prefer it.
Sep 27, 2011
Anonymous
Tangentially, the way I am handling this in my language, is through interfaces. Nothing is accessible, except via an interface. So this selection of which functions behave like methods is done through typing which is the most granular and I think perhaps the most "correct" from a type theory perspective.
So if I want object with such methods, I input an interface with those methods, or I input a helper function which can convert one interface to another (i.e. a "view bound"). The caller is responsible to provide the conversion. This is the D principle in SOLID, a/k/a inversion-of-control or Hollywood principle. Gilad Bracha writes about this on his blog, "Constructors Are Considered Harmful". Meaning that we never want to hard-code implementation and limit the caller's compositionality. This was one of the main mistakes I saw in every language, is they allow class (and global functions, i.e. Scala's singleton object) to be a referencable type. And Scala conflated mixin implementation with interface in one trait.
The downside of my design is that caller has to build an object at runtime of desired type, but I am thinking this can be optimized away by the Hotspot JVM. The upside is that inversion-of-control is explicit and granular.
I realize your goals are somewhat different than mine, because I am aiming for a pure, immutable language (but not lazy a la Haskell). Whereas, you appear to be trying to provide an imperative improvement over Java, that is more straightforward than Scala.
Perhaps we can collaborate in the future. Email is shelby attr coolpage dotter com
-Shelby Moore III
Sep 28, 2011
Andrey Breslav
On the "JVM will optimize this": as the situation with java.util.Iterator shows, Hotspot really struggles with eliminating even really short-living objects from the heap. Maybe it will do a good job one day, but this day hasn't come yet.
Sep 27, 2011
lacroix1547
Can we really do that same kind of markup builder using c# and its extension methods ?
Sep 27, 2011
Andrey Breslav
The syntactic form Kotlin and Groovy offers will be problematic for C# due to lack of extension function literals.
Sep 28, 2011
lacroix1547
Can a Kotlin class multiple-inherit from (classes|traits|mixins) sets of commonly used extension functions?
Sep 28, 2011
Andrey Breslav
I'm not sure I understand what you mean. A big difference between classes/traits and extension functions is that class/trait members are dispatched dynamically, whereas extension functions are dispatched statically.
Could you provide a use case you have in mind?
Sep 29, 2011
lacroix1547
classStringExtensions{funString.before(s:String){StringUtils.substringBefore(this,s);}funString.after(s:String){StringUtils.substringAfter(this,s);}}classCollectionExtensions{fun<T>Collection<T>.before(t:T){...}fun<T>Collection<T>.after(t:T){valindex=thisindexOft;if(index==-1||index==this.size()-1){returnnull;}else{returnthis.get(index+1);}}}classWork1extendsStringExtensions,CollectionExtensions{funwork(){assert"aabbcc".after("bb")=="cc"assert[1,2,3].after(2)==3}}Sep 29, 2011
Andrey Breslav
We do not encourage (mis)using inheritance for importing. The easy way to handle this case would be with imports:
namespacestringExtensions{funString.before(s:String){StringUtils.substringBefore(this,s);}funString.after(s:String){StringUtils.substringAfter(this,s);}}}namespacecollectionExtensions{fun<T>Collection<T>.before(t:T){...}fun<T>Collection<T>.after(t:T){valindex=thisindexOft;if(index==-1||index==this.size()-1){returnnull;}else{returnthis.get(index+1);}}}namespacefoo{importstringExtensions.*importcollectionExtensions.*classWork1{funwork(){assert"aabbcc".after("bb")=="cc"assert[1,2,3].after(2)==3}}Sep 29, 2011
lacroix1547
Ok nice I finally get it.
This example would be nice at the top of this page.
It would have avoided a couple of confusion in the comments of this wiki page.
Plus a minimalist example for Extension function literals and then refer to markup builder for a real use case.
These literals are new for almost everybody and they justify what I was calling the "exotic syntax"
http://en.wikipedia.org/wiki/Extension_method does not even talk about these literals.
A small example is worth a thousand words.
Dec 03, 2011
James Strachan
Agreed - though it would be nice to be able to explicitly import static Java methods as extension functions. (A bit like static imports in Java). There's a ton of really useful methods out there in various libraries; it'd be nice to be able to import them as extension methods without having to hand craft Kotlin delegation methods.
So while I totally agree all static Java methods shouldn't be imported as extension functions by default; it would be good to be able to import them explicitly; maybe in a module definition or something? Or maybe just via the import statement?
Dec 03, 2011
Andrey Breslav
Please, see this issue: http://youtrack.jetbrains.net/issue/KT-732
Dec 04, 2011
James Strachan
Awesome thanks :)
Aug 05, 2011
Eugine Savin
namespace NS1
{
fun Int.Method() = 10
}
namespace NS2
{
fun Int.Method() = 20
}
namespace NS3
{
import NS1; import NS2;
fun Test() = 10.Method() // ????? NS1.Method or NS2.Method is called ???
}
In C# we can call extensioan methods as static method to solve this problem. And Kotlin??
Aug 05, 2011
Andrey Breslav
In Kotlin we can rename on import.
Aug 23, 2011
Leonid Bushuev
Hi,
what's about extension properties? for example,
fun Collection.IsNotEmpty = ! this.IsEmpty
fun Character.IsVowel = this.toLowerCase() in [ 'a', 'e', 'i', 'o', 'u', 'y' ]
That looks nice, isn't it?
Then, using
if (mySet?.IsNotEmpty) doSomething(mySet)
looks better than
if (mySet?!IsEmpty()) doSomething(mySet)
why not?
Aug 23, 2011
Andrey Breslav
We support extension properties:
valString.isEmpty:Booleanget()=this.length()==0Sep 01, 2011
Sergey Ignatov
Maybe it's a typo in the example about generic swap function:
And you mean:
Sep 01, 2011
Andrey Breslav
Fixed. Thank you
Oct 26, 2011
Anonymous
This is not a typo. vars x and y are indexes, not the data, so they should be Int
Oct 26, 2011
Andrey Breslav
Oh, thanks a lot!
Dec 02, 2011
Daniel Worthington-Bodart
Okay this will be my last attempt to change your minds! Please have a look at Xtend's static extension methods they are doing exactly what I am talking about:
import static extension java.util.Collections.*
This is so much simpler, and I really do feel you are missing a trick not allowing standard Java methods to be treated as extension methods. It seems to me that your arguments are based on the performance of your IDE autocomplete / index size rather than the easy of use plus all of those Java 'extension' methods sitting there waiting for some one to use them.
In fact if Kotlin did the same syntax, maybe one day Java might copy the syntax
Dec 02, 2011
Andrey Breslav
I think we can support this for functions coming from Java. I filed an issue in our tracker: http://youtrack.jetbrains.net/issue/KT-732
Thanks for the idea!
For Kotlin functions, this is not that interesting, because a lot is driven by having a default receiver this inside extension functions, see Type-safe Groovy-style builders.
Feb 17, 2012
Eugine Savin
One of motivation to introduce extension methods to C# is LINQ. But we can not make analog of LINQ because there is not "expression trees" in kotlin. Do you plan to implement this feature?
Feb 17, 2012
Andrey Breslav
Yes
Jul 19, 2012
Alexander Kosenkov
There is an important difference between class methods and extension methods regarding inheritance. Maybe you can illustrate is with simple example:
openclassParent{openfunvirtualCall()=println("virtual call parent")}classChild:Parent(){overridefunvirtualCall()=println("virtual call child")}funParent.extensionCall()=println("static call parent")funChild.extensionCall()=println("static call child")funmain(args:Array<String>){valp:Parent=Parent()valc1:Parent=Child()valc2:Child=Child()p.virtualCall()// -> parentc1.virtualCall()// -> child - overridden virtual callc2.virtualCall()// -> childp.extensionCall()// -> parentc1.extensionCall()// -> parent !!! due to variable definition as Parentc2.extensionCall()// -> child}This might be quite unexpected.
Jul 19, 2012
Andrey Breslav
Thanks for the suggestion. BTW, it's the same as overloading.
Jul 19, 2012
Alexander Kosenkov
I tried to make another example:
classTest{funfoo()=println("virtual call foo")funbaz()=println("virtual call baz")}funTest.foo()=println("static call foo")// will never be calledfunmain(args:Array<String>){valt=Test()t.foo()// -> virtualfunTest.baz()=println("extension call baz")t.baz()// -> extension! the function is defined within the method}So, it looks like there is no way to call the static function foo() - it tries to override virtual function with exactly the same signature, but virtual calls have priority. In my opinion, defining such extension function should lead to a compiler error (with the hint text that such functions can be defined within another function).
I mean, for normal methods we require "override" annotation in such cases.
Also, I could not find resolution rules in the documentation - apparently I learned the trick of re-defining existing functions (within the method) from one of your presentations, not from the wiki.
So, my suggestion would be:
// ...funTest.foo()=println("static call foo")// compiler erroroverridefunTest.foo()=println("static call foo")// if function can be somehow imported and used, then OK. Otherwise - also errorfunmain(args:Array<String>){valt=Test()t.foo()// -> virtualoverridefunTest.baz()=println("extension call baz")// I explicitly say that I want to override virtual function with the static callt.baz()// -> extension! the function overrides the normal method}Jul 19, 2012
Andrey Breslav
We will add a compiler message (error or warning) when an extension can't be called.
I think, your "override" proposal is too dangerous.
Thanks
Aug 31, 2012
Jose Getino
Hi Andrey, Im trying kotlin for the first time, but I can't get your swap() extension example to work from inside my java classes.
Do I need to add something to the calling java class?
Aug 31, 2012
Andrey Breslav
If you show me the code, I'll try to help you
Aug 31, 2012
Jose Getino
This is for the kotlin code, I just pasted your code
------------------------------------------
---------------------------------------------------
The java code that produces a compiler error, for swap() not being recognized
---------------------------------------------
Aug 31, 2012
Andrey Breslav
We can't alter the Java programming language and teach it to understand extension functions.
You can call your swap() as a static method, though: