diff --git a/docs/CSClub_Kotlin.key b/docs/CSClub_Kotlin.key deleted file mode 100644 index becd3eb0037..00000000000 Binary files a/docs/CSClub_Kotlin.key and /dev/null differ diff --git a/docs/CSClub_Kotlin.pdf b/docs/CSClub_Kotlin.pdf deleted file mode 100644 index d0c210bace1..00000000000 Binary files a/docs/CSClub_Kotlin.pdf and /dev/null differ diff --git a/docs/CodeGen2012_Proposal.txt b/docs/CodeGen2012_Proposal.txt deleted file mode 100644 index 879d74bd7b3..00000000000 --- a/docs/CodeGen2012_Proposal.txt +++ /dev/null @@ -1,72 +0,0 @@ -Code Generation 2012 - Session Proposal Form - -Submission Deadline: Friday December 9th 2011 - -Session title: - -DSLs in Kotlin - -Session type and duration: - -Tutorial, 60 min - -Session abstract: - -Kotlin is a statically typed programming language for the JVM, proposed recently by JetBrains. The language is intended for industrial use as a safer and more convenient alternative to Java. The language is fully Java compatible, so one can mix Kotlin and Java sources in the same project. Language documentation is available at http://jetbrains.com/kotlin. - -In this session we will demonstrate Kotlin's abilities to define APIs as domain-specific languages (DSLs). This includes explanation of interesting language features illustrated with practical use-cases. - -As a flagship example we will present Type-safe Builders, a technique that improves upon Groovy builders (http://groovy.codehaus.org/Builders) by making them statically checked for correctness. This enables specifying declarative data right inside the code. Want to describe a build file? Xml/HTML? Swing UI? Use builders! We will show how Kotlin compiler itself uses builders to specify modules. Along with this example we will show and explain a few other DSLs built in Kotlin. - -Benefits of participating: - -Participants will learn about Kotlin and how a few language features can be combined to create internal DSLs in a natural and flexible way. - -Process & timetable: - -Introduction to Kotlin — 7-10 minutes -Q&A - 5 minutes -DSL-enabling features - 15 minutes -Q&A - 5 minutes -Builders (live demo) - 20 minutes -Q&A - 5 minutes - -Session outputs: - -Slides, example code - -Intended Audience: - -The session is intended for developers and tech leads. -We expect the audience to be familiar with basic concepts of OOP and some of the statically typed languages (Java, Scala, C#, C++ etc). - -Availability: - -No constraints - -Detailed Description / Supporting Information - -Kotlin is a new statically typed JVM-targeted programming language developed by JetBrains and intended for industrial use. Kotlin is designed to be fully Java compatible, and at the same time safer, more concise than Java and way simpler than its main competitor, Scala. Also, IDE support is being developed in parallel with the language itself. - -This session focuses on the language features that enable DSL creation and corresponding patterns. - -During the introduction, we will give an overview of the language. The features we’re planning to cover include: -* function literals (closures); -* extension functions; -* type inference; -* operator overloading/overriding; -* null safety and automatic casts. - -As a flagship example we will present type-safe builders, a technique that improves upon Groovy builders (http://groovy.codehaus.org/Builders) by making them statically checked for correctness. Builders are a flexible and clean way of describing declarative data in the code with very little syntactic overhead. The technique is so handy that Kotlin uses it instead of XML for compiler configuration, which we will show in action along with XML/HTML and Swing UI building. -This part is presented as a live demo within the IntelliJ IDEA IDE for Kotlin. Along with this example we'll demonstrate a DSL for LINQ-like collection processing and how to turn any type into a Fluent interface (http://martinfowler.com/bliki/FluentInterface.html) with extension functions. - -This session has not been run before, but the material we use is partly taken from Kotlin talks from OSCON, StrangeLoop and Devoxx. - -Main presenter name, contact details and biography - -Name: Andrey Breslav -Affiliation: JetBrains -Telephone / Skype: andrey.breslav @ skype -Email: andrey.breslav@jetbrains.com -Biography (up to 100 words): -Andrey is the lead language designer working on Project Kotlin. He joined JetBrains in 2010. \ No newline at end of file diff --git a/docs/Devclub_Kotlin.key b/docs/Devclub_Kotlin.key deleted file mode 100644 index 7bd77f7dbe7..00000000000 Binary files a/docs/Devclub_Kotlin.key and /dev/null differ diff --git a/docs/Devoxx_Kotlin.key b/docs/Devoxx_Kotlin.key deleted file mode 100644 index 179323a6fca..00000000000 Binary files a/docs/Devoxx_Kotlin.key and /dev/null differ diff --git a/docs/JVMLS_12_Ktloin_Java_Interop.key b/docs/JVMLS_12_Ktloin_Java_Interop.key deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/docs/JVMLS_12_Ktloin_Java_Interop.key.pdf b/docs/JVMLS_12_Ktloin_Java_Interop.key.pdf deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/docs/JVMLS_talk_2011.pdf b/docs/JVMLS_talk_2011.pdf deleted file mode 100755 index 3f841d1928f..00000000000 Binary files a/docs/JVMLS_talk_2011.pdf and /dev/null differ diff --git a/docs/JVMLS_talk_2011.pps b/docs/JVMLS_talk_2011.pps deleted file mode 100755 index c2e293121b8..00000000000 Binary files a/docs/JVMLS_talk_2011.pps and /dev/null differ diff --git a/docs/JVMLS_talk_2011.ppt b/docs/JVMLS_talk_2011.ppt deleted file mode 100755 index af8effa1b2b..00000000000 Binary files a/docs/JVMLS_talk_2011.ppt and /dev/null differ diff --git a/docs/JVMLS_workshop_2011.pdf b/docs/JVMLS_workshop_2011.pdf deleted file mode 100755 index d5d86331579..00000000000 Binary files a/docs/JVMLS_workshop_2011.pdf and /dev/null differ diff --git a/docs/JVMLS_workshop_2011.pps b/docs/JVMLS_workshop_2011.pps deleted file mode 100755 index a79e1af22d0..00000000000 Binary files a/docs/JVMLS_workshop_2011.pps and /dev/null differ diff --git a/docs/JVMLS_workshop_2011.ppt b/docs/JVMLS_workshop_2011.ppt deleted file mode 100755 index 04f20e155a5..00000000000 Binary files a/docs/JVMLS_workshop_2011.ppt and /dev/null differ diff --git a/docs/Kotlin-RivieraDev.ppt b/docs/Kotlin-RivieraDev.ppt deleted file mode 100644 index 77fb8065dd6..00000000000 Binary files a/docs/Kotlin-RivieraDev.ppt and /dev/null differ diff --git a/docs/Kotlin_OopenSystems.pages b/docs/Kotlin_OopenSystems.pages deleted file mode 100644 index 438eb3a0b96..00000000000 Binary files a/docs/Kotlin_OopenSystems.pages and /dev/null differ diff --git a/docs/OSCON_Kotlin.key b/docs/OSCON_Kotlin.key deleted file mode 100755 index 74011b5995b..00000000000 Binary files a/docs/OSCON_Kotlin.key and /dev/null differ diff --git a/docs/OSCON_Kotlin.pdf b/docs/OSCON_Kotlin.pdf deleted file mode 100755 index dbf7518f144..00000000000 Binary files a/docs/OSCON_Kotlin.pdf and /dev/null differ diff --git a/docs/StrangeLoop_Kotlin.key b/docs/StrangeLoop_Kotlin.key deleted file mode 100644 index cf94f3c845d..00000000000 Binary files a/docs/StrangeLoop_Kotlin.key and /dev/null differ diff --git a/docs/StrangeLoop_Kotlin.pdf b/docs/StrangeLoop_Kotlin.pdf deleted file mode 100644 index 0cde8259f5e..00000000000 Binary files a/docs/StrangeLoop_Kotlin.pdf and /dev/null differ diff --git a/docs/confluence.jetbrains.com/Kotlin/0_Welcome.confluence b/docs/confluence.jetbrains.com/Kotlin/0_Welcome.confluence deleted file mode 100644 index c9839e2cbab..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/0_Welcome.confluence +++ /dev/null @@ -1,56 +0,0 @@ -{section} -{column:width=512px} -h3. What is [Kotlin]? -"Project [Kotlin]" is a codename for a statically typed programming language compiled to JVM byte code and JavaScript. -It is developed by [JetBrains|http://jetbrains.com] and distributed under [Apache 2 Open Source License|http://www.apache.org/licenses/LICENSE-2.0.html]. -{note:title=Kotlin is Under Development}Please report bugs to our [Issue Tracker|http://youtrack.jetbrains.com/issues/KT]{note} -See our [*blog*|http://blog.jetbrains.com/kotlin/]. Follow us on [*Twitter*|http://twitter.com/#!/project_kotlin]. Join our [*forum*|http://devnet.jetbrains.net/community/kotlin]. -h3. Hello, world! -{jet} -package hello - -fun main(args : Array) { - println("Hello, world!") -} -{jet} -h3. More Examples -[Kotlin Web Demo|http://kotlin-demo.jetbrains.com] offers many runnable example programs. -You can also *write your own programs* right in the browser and run them on JVM or JavaScript platform. -h3. Documentation -The [Getting Started] page describes the set-up process. -The [Docs Home] page will guide you through the documentation. -*New*: Documentation for the [Kotlin standard APIs|http://jetbrains.github.com/kotlin/apidoc/stdlib/]. -See this presentation for the introduction: -{widget:url=http://www.slideshare.net/abreslav/kotlin-devoxx-2011} -[*Slides* and *video* from StrangeLoop 2011|http://www.infoq.com/presentations/The-Kotlin-Programming-Language] -h3. Source Code -Check out the sources on [GitHub|http://github.com/jetbrains/kotlin]. -Sources are distributed under *Apache 2* license. -Nightly builds can be downloaded from our [build server|https://teamcity.jetbrains.com/viewType.html?buildTypeId=bt345&tab=buildTypeStatusDiv&guest=1]. -You can also use [http://www.jetbrains.com/kotlin/eap-plugin-repository/updatePlugins.xml] to set up a *plugin repository* in IntelliJ IDEA. -{info} -The IDE plugin requires the latest EAP build of [IntelliJ IDEA 11.1|http://eap.jetbrains.com/idea]. -{info} - -h3. Kontributions -* [stdlib|https://github.com/JetBrains/kotlin/tree/master/stdlib] by James Strachan -* [Ant, Maven etc integration|https://github.com/JetBrains/kotlin/tree/master/ant] by Evgeny Goldin -* [Aztec|https://github.com/kondratovich/aztec] by Andrew Kondratovich -* [Be the next Kontributor!|http://blog.jetbrains.com/kotlin/2012/03/contributing-to-kotlin/] -{column} -{column} -h3. IDE -{widget:width=500|url=http://www.youtube.com/watch?v=0jBPcIPVihI} - -h3. Recommended reading -* [The Kotlin Journey by Hadi Hariri|http://hadihariri.com/2012/02/17/the-kotlin-journey-part-i-getting-things-set-up/] -* [Kotlin: The Language of the Month (Dr. Dobb's)|http://drdobbs.com/jvm/232600839] -* [Язык программирования Kotlin|http://www.osp.ru/os/2011/09/13011550/] (in Russian) - -h3. Twitter -{widget:url=http://search.twitter.com/search?q=kotlin%20OR%20project_kotlin%20-kotlin_ru|width=500} - -h3. Kotlin Events -{widget:width=500px|height=300px|url=https://www.google.com/calendar/embed?mode=AGENDA&showPrint=0&showCalendars=0&showTitle=0&src=nvijaubrlepgko0alipqhpmtj8%40group.calendar.google.com&ctz=Europe/Moscow} -{column} -{section} \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40699414_Enum+classes.confluence b/docs/confluence.jetbrains.com/Kotlin/40699414_Enum+classes.confluence deleted file mode 100644 index d8472361598..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40699414_Enum+classes.confluence +++ /dev/null @@ -1,89 +0,0 @@ -The most basic usage of *enum* classes is implementing [_type-safe enums_, like in *Java*|http://www.javacamp.org/designPattern/enum.html]: -{jet} -enum class Direction { - NORTH; SOUTH; WEST; EAST -} -{jet} -As everywhere in [Kotlin], one can omit semicolons if each enum constant is situated on its own line: -{jet} -enum class Direction { - NORTH - SOUTH - WEST - EAST -} -{jet} - -{note:title=Enums are under development}See the corresponding [issues|http://youtrack.jetbrains.com/issues/KT?q=%23unresolved+enum].{note} - -h4. Open enums - -In [Kotlin] *enums* can be *open*, i.e. can be subclassed by other enums: -{jet} -open enum class OptionKeys { - OPTION1 -} -enum class ExtraOptionKeys : OptionKeys { - OPTION2 -} -fun demo() { - ExtraOptionKeys.OPTION2 : ExtraOptionKeys // legal - ExtraOptionKeys.OPTION1 : OptionKeys // legal - OptionKeys.OPTION2 // error: OPTION2 is not a member of OptionKeys -} -{jet} -Enums can extend other enums and traits as well. - -h4. Enums constants are objects - -Since enum constants are different instances of the *enum class*, they can be initialized differently: -{jet} -enum class Color(val rgb : Int) { - RED : Color(0xFF0000) - GREEN : Color(0x00FF00) - BLUE : Color(0x0000FF) -} -{jet} - -h4. Enum constants define (anonymous) classes - -Each enum constant may declare its own members and override members of the *enum class*: -{jet} -enum class ProtocolState { - WAITING { - override fun signal() = TALKING - } - - TALKING { - override fun signal() = WAITING - } - - abstract fun signal() : ProtocolState -} -{jet} - -h4. Constructors in enum classes - -Enum classes actually encode (generalized) Algebraic Data Types, and thus may have _named constructors_ instead of constants: -{jet} -enum class List(val size : Int) { - Nil : List(0) - Cons(h : T, t : List) : List(t.size + 1) -} -{jet} - -h4. Pattern matching - -Enums classes are integrated with [pattern matching|Pattern matching]: -{jet} -fun List.join(separator : String) = - when (this) { - is List.Nil -> "[]" - is List.Cons#(val h, val tail) -> h + separator + tail.join(separator) - } -{jet} - -h3. What's next - -* [Nested classes] -* [Object expressions and Declarations] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40699414_Nested+classes.confluence b/docs/confluence.jetbrains.com/Kotlin/40699414_Nested+classes.confluence deleted file mode 100644 index 2308ed3ed65..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40699414_Nested+classes.confluence +++ /dev/null @@ -1,34 +0,0 @@ -Classes can be nested in other classes: -{jet} -class Outer() { - private val bar : Int = 1 - class Nested() { - fun foo() = 2 - } -} - -val demo = Outer.Inner().foo() // == 2 -{jet} - -h3. Inner classes - -A class may be marked as *inner* to be able to access members of outer class. Inner classes carry a reference to an object of an outer class: - -{jet} -class Outer() { - private val bar : Int = 1 - inner class Inner() { - fun foo() = bar - } -} - -val demo = Outer().Inner().foo() // == 1 -{jet} - -See [Qualified *this* expressions|This expressions#Qualified] to learn about disambiguation of *this* in inner classes. - -{note:title=Inner classes are under development}See the corresponding [issue|http://youtrack.jetbrains.com/issue/KT-1174].{note} - -h3. What's next - -* [Object expressions and Declarations] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40699414_Object+expressions+and+Declarations.confluence b/docs/confluence.jetbrains.com/Kotlin/40699414_Object+expressions+and+Declarations.confluence deleted file mode 100644 index f07faed2248..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40699414_Object+expressions+and+Declarations.confluence +++ /dev/null @@ -1,74 +0,0 @@ -Sometimes we need to create an object of a slight modification of some class, without explicitly declaring a new subclass for it. *Java* handles this case with _anonymous inner classes_. [Kotlin] slightly generalizes this concept with *object* expressions and *object* declarations. - -h3. Object expressions - -To create an object of an anonymous class that inherits from some type (or types), one writes: -{jet} -window.addMouseListener(object : MouseAdapter() { - override fun mouseClicked(e : MouseEvent) { - // ... - } - - override fun mouseEntered(e : MouseEvent) { - // ... - } -}) -{jet} -If a supertype has a constructor, appropriate constructor parameters must be passed to it. Many supertypes may be specified as a comma-separated list after the colon: -{jet} -open class A(x : Int) { - public virtual val y : Int = x -} - -open class B(s : String) - -val ab = object : A(1), B("abc") { - override val y = 15 -} -{jet} - -If, by any chance, we need "just an object", with no nontrivial supertypes, we can simply say: -{jet} -val adHoc = object { - var x : Int = 0 - var y : Int = 0 -} - -print(adHoc.x + adHoc.y) -{jet} - -h3. Object declarations - -[Singleton|http://en.wikipedia.org/wiki/Singleton_pattern] is a very useful pattern, and [Kotlin] (after *Scala*) makes it easy to declare singletons: -{jet} -object DataProviderManager { - fun registerDataProvider(provider : DataProvider) { - // ... - } - - val allDataProviders : Collection - get() = // ... -} -{jet} -This is called an _object declaration_. If there's a name following the *object* keyword, we are not talking about an _expression_ any more. We cannot assign such a thing to a variable, but we can refer to it by its name. Such objects can have supertypes: -{jet} -object DefaultListener : MouseAdapter() { - override fun mouseClicked(e : MouseEvent) { - // ... - } - - override fun mouseEntered(e : MouseEvent) { - // ... - } -} -{jet} - -h3. Semantical difference between object expressions and declarations - -There is one important semantical difference between *object* expressions and *object* declarations: -* *object* declarations are initialized lazily, when accessed for the first time -* *object* expressions are executed (and initialized) immediately, where they are used - -h3. What's next - -* [Generics] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40699701_Runtime+Type+Information.confluence b/docs/confluence.jetbrains.com/Kotlin/40699701_Runtime+Type+Information.confluence deleted file mode 100644 index 936da5d39f1..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40699701_Runtime+Type+Information.confluence +++ /dev/null @@ -1,19 +0,0 @@ -[Kotlin] preserves type information at runtime, including the [generic arguments of types and functions|Generics#Reified generics]. - -This information can be retrieved with the {{typeinfo()}} function: -{jet} -val typeinfo = typeinfo(list) -{jet} - -{{typeinfo()}} returns an object of the class {{TypeInfo}} that provides type information and reflective access to the members of the given type. - -To retrieve a {{TypeInfo}} instance of a type expression, we can use an overloaded version of the {{typeinfo()}} function, but passing in a type argument: -{jet} -val typeinfo = typeinfo> -{jet} - -{note:title=TypeInfo is not supported yet}On the JVM you can say {{foo.javaClass}} to ge the Java class of {{foo}}.{note} - -h3. What's next - -* [Null-safety] diff --git a/docs/confluence.jetbrains.com/Kotlin/40700001_Strings.confluence b/docs/confluence.jetbrains.com/Kotlin/40700001_Strings.confluence deleted file mode 100644 index cb022c04150..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40700001_Strings.confluence +++ /dev/null @@ -1,41 +0,0 @@ -Strings are represented by the type {{String}}. Strings are immutable. Elements of a string are [characters|Basic types#Characters] can be accessed by the indexing operation: {{s\[i\]}}. A string can be iterated over with a *for* loop: -{jet} -for (c in str) { - println(c) -} -{jet} - -h3. String literals - -[Kotlin] has two types of string literals: _escaped_ strings that may have escaped characters in them and _raw_ strings that can contain newlines and arbitrary text. An escaped string is very much like a *Java* string: -{jet} -val s = "Hello, world!\n" -{jet} -Escaping is done in the conventional way, with a backslash. - -A _raw_ string is delimited by a triple quote ({{"""}}), contains no escaping and can contain newlines and any other characters: -{jet} -val text = """ - for (c in "foo") - print(c) -""" -{jet} - -{anchor:Templates} - -h3. Templates - -Strings may contain _template expressions_, i.e. pieces of code that are evaluated and whose results are concatenated into the string. A template expression starts with a dollar sign ({{$}}) and consists of either a simple name: -{jet} -val i = 10 -val s = "i = $i" // evaluates to "i = 10" -{jet} -or an arbitrary expression in curly braces: -{jet} -val s = "abc" -val str = "$s.length is ${s.length}" // evaluates to "abc.length is 3" -{jet} - -h3. What's next - -* [Expressions] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40700138_Basic+operations.confluence b/docs/confluence.jetbrains.com/Kotlin/40700138_Basic+operations.confluence deleted file mode 100644 index d9a52bfadae..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40700138_Basic+operations.confluence +++ /dev/null @@ -1,35 +0,0 @@ -h3. Equality - -In [Kotlin] there are two types of equality: -* referential equality (two references point to the same object) -* structural equality (a check for {{equals()}} - -h4. Referential equality - -In [Kotlin], there's no built-in operator to check for referential equality, for we believe that it is rarely needed. Instead, there's an [inline function|Functions#Inline functions] {{identityEquals()}} that can be called in the following way: -{jet} -a.identityEquals(b) -// or -a identityEquals b // infix call -{jet} -And returns *true* if and only if {{a}} and {{b}} point to the same object. - -h4. Structural equality - -Structural equality is checked by the {{==}} operation (and its negated counterpart {{!=}}). By [convention|Operator overloading#Equals], an expression like {{a == b}} is translated to -{jet} -a?.equals(b) ?: b.identityEquals(null) -{jet} -I.e. if {{a}} is not *null*, it calls the {{equals(Any?)}} function, otherwise (i.e. {{a}} is *null*) it checks that {{b}} is referentially equal to *null*. - -Note that there's no point in optimizing your code when comparing to *null* explicitly: {{a == null}} will be automatically translated to {{a.identityEquals(null)}}. - -h3. What's next - -* [Control structures] -* [Function literals] -* [Returns and jumps] -* [Ranges] -* [This expressions] -* [Tuples] -* [Type casts] diff --git a/docs/confluence.jetbrains.com/Kotlin/40700138_Control+structures.confluence b/docs/confluence.jetbrains.com/Kotlin/40700138_Control+structures.confluence deleted file mode 100644 index d3a887eaff8..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40700138_Control+structures.confluence +++ /dev/null @@ -1,207 +0,0 @@ -{anchor:If} - -h3. If expression - -In [Kotlin], *if* is an _expression_, i.e. it returns a value. Therefore there is not _ternary operator_ ({{condition ? then : else}}), because ordinary *if* works fine in this role. Consider the following examples: - -{jet} -// Traditional usage -var max = a -if (a < b) - max = b - -// With else -var max : Int -if (a > b) - max = a -else - max = b - -// As expression -val max = if (a > b) a else b -{jet} - -*If* branches can be blocks, and the last expression is the value of a block: -{jet} -val max = if (a > b) { - print("Choose a") - a - } - else { - print("Choose b") - b - } -{jet} - -When *if* has only one branch, or one of its branches results in [{{Unit}}|Functions#Unit], it's type is [{{Unit}}|Functions#Unit]. - -See the grammar for *if* [here|Grammar#if]. - -{anchor:When} - -h3. When expression - -*When* replaces the *switch* operator of *C*\-like languages. In the simplest form it looks like this: -{jet} -when (x) { - 1 -> print("x == 1") - 2 -> print("x == 2") - else -> { // Note the block - print("x is neither 1 nor 2") - } -} -{jet} - -*When* matches its argument against all branches consequently until some branch condition is satisfied. *When* is an _expression_ and results in satisfied branch's right hand side. If some of its branches return result in a value of type [{{Unit}}|Functions#Unit], the whole expression has type [{{Unit}}|Functions#Unit]. -Note that the *else* branch is mandatory, unless the compiler can prove that all possible cases are covered with branch conditions. - -If many cases should be handled in the same way, the branch conditions may be combined with a comma: -{jet} -when (x) { - 0, 1 -> print("x == 0 or x == 1") - else -> print("otherwise") -} -{jet} - -We can use arbitrary expressions (not only constants) as branch conditions: -{jet} -when (x) { - parseInt(s) -> print("s encodes x") - else -> print("s does not encode x") -} -{jet} - -One can also check a value for being *in* or *\!in* a [range|Ranges]: -{jet} -when (x) { - in 1..10 -> print("x is in the range") - !in 10..20 -> print("x is outside the range") - else -> print("none of the above") -} -{jet} - -*When*\-expressions support [pattern matching|Pattern matching] through {{is}} and {{\!is}}: -{jet} -when (tuple) { - is #(1, 2) -> ... - is #(val a, 3) -> print(a) // binding a to the first element of the tuple - !is #(*, 1100) -> ... - else -> ... -} -{jet} -We do not expand on the pattern matching here. For details, look at [this page|Pattern matching]. - -{anchor:bare-when} -*When* can also be used as a replacement for an *if*\-*else*\-*if* chain. If no argument is supplied, the branch conditions are simply boolean expressions, and a branch is executed when its condition is true: -{jet} -when { - x.isOdd() -> print("x is odd") - x.isEven() -> print("x is even") - else -> print("x is funny") -} -{jet} - -{anchor:continue-when} -h4. Continue inside {{when}} - -Inside *when* expressions, *continue* jumps to the next branch condition, if any: -{jet} -when (x) { - in 1..100 -> - if (x.isOdd()) - continue // Jump to the next branch, i.e. '3, 101 -> ...' - else - print("Even between 1 and 100") - 3, 101 -> print("3 or 101") - 1000 -> continue // Error: continue is not allowed in the last branch -} -{jet} - -This mechanism replaces the concept of _guards_ available in other languages. I.e. in *Scala* one has _guard_ *{_}if{_}* _expressions_ in *match* (that corresponds to *when*): -{code:Scala} -// Scala -term match { - case Fun(x, Var(y)) if x == y -> print(x) - case _ -> print("Nope!") -} -{code} -This can be rewritten in [Kotlin] with as follows: -{jet} -when(term) { - is Fun#(val x, Var#(val y)) -> { if (x != y) continue; print(x) } - else -> print("Nope!") -} -{jet} -See [Returns and jumps] for more information about *continue*. - -See the grammar for *when* [here|Grammar#when]. -See also [Pattern matching]. - -{note:title=Continue in when is not implemented yet}See the corresponding [issue|http://youtrack.jetbrains.com/issue/KT-771]{note} - -{anchor:Loops} -{anchor:For} -h3. For loop - -*For* loop iterates through anything that provides an _iterator_. The syntax is as follows: -{jet} -for (item in collection) - print(item) -{jet} - -One can specify a type and *val* or *var* for the loop variable. The body can be a block. -{jet} -for (val item : Int in ints) { - // ... -} -{jet} - -As mentioned before, *for* iterates through anything that provides and *iterator*, i.e. -# has an instance\- or extension-function {{iterator()}}, whose return type -# has an instance\- or extension-function {{next()}}, and -# either -## a property {{hasNext}} of type {{Boolean}}, or -## a function {{hasNext()}} that returns {{Boolean}}. - -If you want to iterate through an [array|Basic types#Arrays] or list with an index, you can do it this way: -{jet} -for (i in array.indices) - print(array[i]) -{jet} -Note that this "iteration through a range" is compiled down to optimal implementation with no extra objects created. - -See the grammar for *for* [here|Grammar#for]. - -{anchor:while} - -h3. While and do..while loops - -*While* and *do*..*while* work as usual: -{jet} -while(x > 0) { - x-- -} - -do { - val y = retrieveData() -} while(y != null) // y is visible here! -{jet} - -See the grammar for *while* [here|Grammar#while]. - -h3. Break and continue in loops - -[Kotlin] supports traditional *break* and *continue* operators in loops. See more here [Returns and jumps]. - -h3. Try expression - -See [Exceptions] for the details. - -h3. What's next - -* [Function literals] -* [Returns and jumps] -* [Ranges] -* [This expressions] -* [Tuples] -* [Type casts] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40700138_Function+literals.confluence b/docs/confluence.jetbrains.com/Kotlin/40700138_Function+literals.confluence deleted file mode 100644 index 8d55c188b66..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40700138_Function+literals.confluence +++ /dev/null @@ -1,109 +0,0 @@ -A _function literal_ as an "anonymous function", i.e. a function that is not declared, but passed immediately as an expression. Consider the following example: -{jet} -max(strings, {a, b -> a.length < b.length}) -{jet} -Function {{max}} is a [higher-order function|Functions#Higher-order functions], i.e. is takes a function value as the second argument. This second argument is an expression that is itself a function, i.e. a _function literal_. As a function, it is equivalent to -{jet} -fun compare(a : String, b : String) : Boolean = a.length < b.length -{jet} - -h3. Function types - -For a function to accept another function as a parameter, we have to specify a _function type_ for that parameter. For example the abovementioned function {{max}} is defined as follows: -{jet:lineNumbers=true} -fun max(collection : Collection, less : (T, T) -> Boolean) : T? { - var max : T? = null - for (it in collection) - if (max == null || less(max, it)) - max = it - return max -} -{jet} -The parameter {{less}} is of type {{(T, T) -> Boolean}}, i.e. a function that takes two parameters of type {{T}} and returns a {{Boolean}}: *true* if the first one is smaller than the second one. - -In the body, line 4, {{less}} is used as a function: it is called by passing two arguments of type {{T}}. - -A _function type_ is written as above, or may have named parameters, for documentation purposes and to enable calls with [named arguments|Functions#Named arguments]. -{jet} -val compare : (x : T, y : T) -> Int = ... -{jet} - -{anchor:Syntax} - -h3. Syntactic forms of function literals - -The _full_ syntactic form of function literals, i.e. literals of function types, is as follows: -{jet} -val sum = {(x : Int, y : Int) : Int -> x + y} -{jet} - -* A function literal is always surrounded by curly braces, -* parameter declarations in the full syntactic form go inside parentheses and have _optional_ type annotations, -* the _optional_ return type annotation goes after the parameter list, -* the body goes after an '{{->}}' sign. - -If we leave all the optional annotations out, what's left looks like this: -{jet} -val sum : (Int, Int) -> Int = {(x, y) -> x + y} -{jet} -As this is the most common case, [Kotlin] allows us to leave the parentheses out as well, if no type annotations are present, and so we get the _short_ syntactic form for functional literals: -{jet} -val sum : (Int, Int) -> Int = {x, y -> x + y} -{jet} - -It very common that a function literal has _only one parameter_. If [Kotlin] can figure the signature out itself, it allows us not to declare the only parameter, and will implicitly declare it for us under the name *it*: -{jet} -ints.filter {it > 0} // this literal is of type '(it : Int) -> Boolean' -{jet} -Note that if a function takes another function as the last parameter, the function literal argument can be passed outside the parenthesized argument list. See [Higher-order functions|Functions#Higher-order functions] and the grammar for [callSuffix|Grammar#callSuffix]. - -See the grammar for function literals [here|Grammar#functionLiteral]. - -h3. Closures - -A function literal (as well as a [local function|Functions#Local functions] and [object expressions|Object expressions and Declarations]) can access its _closure_, i.e. the variables declared in the outer scope. Unlike *Java* the closure variables can be modified: -{jet} -var sum = 0 -ints filter {it > 0} forEach { - sum += it -} -print(sum) -{jet} - -{anchor:Extensions} - -h3. Extension function literals - -Besides ordinary functions, [Kotlin] supports [extension functions|Extension functions]. This kind of functions in so useful, that extension function literals are also supported. One of the most important examples of their usage is [Type-safe Groovy-style builders|Type-safe Groovy-style builders]. - -An extension function differs from an ordinary one in that it has a _receiver type_ specification. One can specify a receiver type in a function literal as well: -{jet} -val sum = {Int.(other : Int) : Int -> this + other} -{jet} -Receiver type may be specified only in the _full_ syntactic form of a function literal (remember that parameter types and return type annotations are optional in this form). - -Such a literal has a function type with receiver: -{jet} -sum : Int.(other : Int) -> Int -{jet} -it can be called with a dot or in infix form (since it has only one parameter): -{jet} -1.sum(2) -1 sum 2 -{jet} - -h4. Disambiguation of {{this}} expressions - -See [*This* expressions|This expressions#Qualified]. - -h3. What's next - -*Expressions* -* [Returns and jumps] -* [Ranges] -* [This expressions] -* [Tuples] -* [Type casts] - -*Functions* -* [Type-safe Groovy-style builders] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40700138_Ranges.confluence b/docs/confluence.jetbrains.com/Kotlin/40700138_Ranges.confluence deleted file mode 100644 index 8161854f558..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40700138_Ranges.confluence +++ /dev/null @@ -1,24 +0,0 @@ -Range expressions are formed with {{rangeTo}} functions that have the [operator form of {{..}}|Operator overloading#Binary operations] which are complemented by [*in* and *!in*|Operator overloading#in]: -{jet} -// Check range membership, i.e. contains -// (optimized for Ints) -if (a in 1..100) { - print("in range") -} - -// Iterate through a range, i.e. iterator() -// (optimized for Ints) -for (x in 1..100) { - print(x) -} -{jet} - -A {{rangeTo()}} function may return whatever type one likes, but there's a common convention: -* For enumerable types like {{Int}}, {{rangeTo()}} returns an {{IterableRange}} object that supports both checking membership with {{contains()}} (*in*) and iterating with {{iterator()}}. -* For other ordered types (like {{String}} or {{Double}}), it returns a {{Range}} that only supports checking membership with {{contains()}}. - -h3. What's next - -* [This expressions] -* [Tuples] -* [Type casts] diff --git a/docs/confluence.jetbrains.com/Kotlin/40700138_Returns+and+jumps.confluence b/docs/confluence.jetbrains.com/Kotlin/40700138_Returns+and+jumps.confluence deleted file mode 100644 index 7274966fbb3..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40700138_Returns+and+jumps.confluence +++ /dev/null @@ -1,118 +0,0 @@ -There are three so-called _structural jump operators_ that are sort of like *goto* but much nicer: *return*, *break* and *continue*. By default, their behavior is as follows: -* *return* returns from the _nearest enclosing_ _[function|Functions]_, and not a [function literal|Function literals] -* *break* terminates the _nearest enclosing_ _[loop|Control structures#Loops]_ -* *continue* either proceeds to the next step of the _nearest enclosing_ _[loop|Control structures#Loops]_ or to the next branch in the _nearest enclosing_ _[*when* expression|Control structures#When]_ - -h3. Break and continue at labels - -Any expression in [Kotlin] may be marked with a _label_. Labels have the from of the {{@}} sign followed by an optional identifier, for examples {{@}}, {{@abc}}, {{@fooBar}} are valid labels (see the [grammar|Grammar#label]). To label an expression, we just put a label in front of it: -{jet} -@loop for (i in 1..100) { - // ... -} -{jet} - -Now, we can qualify a *break* or *continue* with a label: -{jet} -@loop for (i in 1..100) { - for (j in 1..100) { - if (...) - break@loop - } -} -{jet} -A *break* qualified with a label jumps to the execution point right after the loop marked with that label. A *continue* proceeds to the next iteration of that loop. - -h3. Return at labels - -With [function literals|Function literals], [local functions|Functions#Local functions] and [object expression|Object expressions and Declarations], functions can be nested in [Kotlin]. _Qualified_ *{_}return{_}{*}_'s_ allow us to return from an _outer function_. The most important use case is returning from a function literal. Recall that when we write this: -{jet} -fun foo() { - ints.forEach { - if (it == 0) return - print(it) - } -} -{jet} -The *return* expression returns from the nearest enclosing _function_, i.e. {{foo}}. If we need to return from a _function literal_, we have to label it and qualify the *return*: -{jet} -fun foo() { - ints.forEach @lit { - if (it == 0) return@lit - print(it) - } -} -{jet} -Now, it returns only from the function literal. Often times it is more convenient to use the shortest implicit label {{@}} for function literals: -{jet} -fun foo() { - ints.forEach { - if (it == 0) return@ // Works if there's one and only one function literal in lexical scope up to named entity (function or class) - print(it) - } -} -{jet} -Note that such non-local returns are supported only for function literals passed to inline-functions. - -When returning a value, the parser gives preference to the qualified return, i.e. -{jet} -return@a 1 -{jet} -means "return 1 at label @a" and not "return a labeled expression (@a 1)". - -Named functions automatically define labels: -{jet} -fun outer() { - fun inner() { - return@outer // the label @outer was defined automatically - } -} -{jet} - -{note:title=Non-local returns are not implemented yet}See the corresponding [issue|http://youtrack.jetbrains.com/issue/KT-1435].{note} - -{anchor:custom} -h4. Break and continue in custom control structures - -[Inline functions|Functions#Inline functions] make writing performant "custom control structures" easy, for example, the {{forEach()}} function that executes a function literal for every element in a collection: -{jet} -inline fun Collection.forEach(body : (item : T) -> Unit) { - for (item in this) { - body(item) - } -} -{jet} -Note that this function is not exactly a redundant example easily substitutable by a normal *for* loop. Consider the following code: -{jet} -ints filter {it > 0} sortby {-it} forEach {print(it)} -{jet} - -Now, what happens when we write *break* (or *continue*) inside the body of {{forEach}}? We simply get a compile-time error, because, lexically, there's no loop to *break*: -{jet} -ints forEach { - if (it < 0) break // Error: 'break' does not belong to a loop - print(it) -} -{jet} -But, actually, there _is_ a loop, hidden inside {{forEach}}, and it is _inlined_ there, so we should be able to tell the compiler to understand that. An we can, by annotating the loop inside {{forEach}} with the {{loop}} annotation. The function parameter should also be annotated with {{loopbody}} annotation: -{jet} -inline fun Collection.forEach(loopbody body : (item : T) -> Unit) { - [loop] for (item in this) { - body(item) - } -} -{jet} -Now, the compiler allows *break* and *continue* in the function literal argument passed to {{forEach}}, and these operators apply to the loop marked with {{@@}}. - -{note:title=Break and continue for custom control structures are not implemented yet}See the corresponding [issue|http://youtrack.jetbrains.com/issue/KT-1436].{note} - -h3. Qualified {{this}} expressions - -See [*This* expressions|This expressions#Qualified]. - -h3. What's next - -* [Ranges] -* [This expressions] -* [Tuples] -* [Type casts] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40700138_This+expressions.confluence b/docs/confluence.jetbrains.com/Kotlin/40700138_This+expressions.confluence deleted file mode 100644 index 6d95f97c068..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40700138_This+expressions.confluence +++ /dev/null @@ -1,41 +0,0 @@ -To denote the current _receiver_, we use *this* expressions: -* In a member of a [class|Classes and Inheritance], *this* refers to the current object of that class -** *this{*}{{}} is used to qualified calls to supertype's implementations of members, see [Classes and Inheritance#Overriding rules] -* In an [extension function|Extension functions] or an [extension function literal|Function literals#Extensions], *this* denotes the _receiver_ parameter that is passed on the left-hand side of a dot. - -If *this* has no qualifiers, it refers to the _innermost enclosing scope_. To refer to *this* in other scopes, _label qualifiers_ are used: - -{anchor:qualified} - -h3. Qualified {{this}} - -To access *this* from an outer scope (a [class|Classes and Inheritance], or [extension function|Extension functions], or labeled [extension function literal|Function literals#Extensions]) one writes *this{*}{{@label}} where {{@label}} is a [label|Returns and jumps] on the scope {{this}} is meant to be from: -{jet} -class A { // implicit label @A - class B { // implicit label @B - fun Int.foo() { // implicit label @foo - val a = this@A // A's this - val b = this@B // B's this - - val c = this // foo()'s receiver, an Int - val c1 = this@foo // foo()'s receiver, an Int - - val funLit = {String.() -> // implicit label @ - val d = this // funLit's receiver - val d1 = this@ // funLit's receiver - } - - - val funLit2 = { (s:String) -> - val d1 = this // foo()'s receiver, since enclosing function literal doesn't have any receiver - } - } - } -} -{jet} - - -h3. What's next - -* [Tuples] -* [Type casts] diff --git a/docs/confluence.jetbrains.com/Kotlin/40700138_Tuples.confluence b/docs/confluence.jetbrains.com/Kotlin/40700138_Tuples.confluence deleted file mode 100644 index 495caf85a34..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40700138_Tuples.confluence +++ /dev/null @@ -1,52 +0,0 @@ -Tuples (pairs, triples and so on) are useful when we need a lightweight mechanism of data together, for example, to return several values from a function. - -h3. Tuple types and literals - -There are 22 tuple classes named {{Tuple0}} through {{Tuple21}}. {{Tuple0}} (also called [Unit|Functions#Unit]) has zero type parameters, {{Tuple1}} has one parameter, and so on. The type parameters determine types of tuple components. For example, {{Tuple2}} is defined as follows: -{jet} -class Tuple2( - val _1 : T1, - val _2 : T2 -) -{jet} - -We can use shorthand syntax for tuple types and values -{jet} -val intStrPair : #(Int, String) = #(1, "") // same as 'Tuple2(1, "")' -{jet} - -One can access tuples' components either by [pattern matching|Pattern matching#Tuple patterns]: -{jet} -when (x) { - is #(null, *) => throw NullPointerException() - is #(val a, val b) => print(a, b) -} -{jet} -or by generic accessors {{\_1}}, {{\_2}} etc: -{jet} -print("left = ${pair._1}, right = ${pair._2}") -{jet} - -To make accessors more readable, one can use [labeled tuples|#Labeled tuples]. - -h3. Labeled tuples - -One can define a tuple type with _labels_ for its components: -{jet} -val point : #(x : Int, y : Int) -{jet} -Such a tuple can be accessed by those labels: -{jet} -print("x = ${point.x}, y = ${point.y}") -{jet} - -We can even create tuples with named components, where order does not matter any more: -{jet} -val point : #(x : Int, y : Int) = #(y = 10, x = 5) -{jet} - -{note:title=Labeled tuples are not implemented yet}See the corresponding [issue|http://youtrack.jetbrains.com/issue/KT-1433].{note} - -h3. What's next - -* [Type casts] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40700138_Type+casts.confluence b/docs/confluence.jetbrains.com/Kotlin/40700138_Type+casts.confluence deleted file mode 100644 index f7299c823cc..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40700138_Type+casts.confluence +++ /dev/null @@ -1,45 +0,0 @@ -A type cast operator changes the static type of an expression after performing a run-time check. - -h3. Smart casts - -In many cases, one does not need to use explicit cast operators in [Kotlin], because the compiler tracks the [*is*\-checks for immutable values|Pattern matching] and inserts (safe) casts automatically when needed: -{jet} -fun demo(x : Any) { - if (x is String) { - print(x.length) // x is automatically cast to String - } -} -{jet} - -Automatic casts work for [*when* expressions|Control structures#When] and [*while*|Control structures#While] loops as well: -{jet} -when (x) { - is Int -> print(x + 1) - is String -> print(x.length + 1) - is Array -> print(x.sum()) -} -{jet} - -h3. "Unsafe" cast operator - -Usually, cast operator throws an exception if the cast is not possible. Thus, we call it _unsafe_. The unsafe cast in [Kotlin] is done by an infix operator *as* (see [operator precedence|Grammar#Precedence]): -{jet} -val x : String = y as String -{jet} -Note that *null* cannot be cast to {{String}} as this type is not [nullable|Null-safety], i.e. if {{y}} is *null*, the code above throws an exception. -In order to match Java cast semantics we have to have nullable type at cast right hand side, like -{jet} -val x : String? = y as String? -{jet} - -h3. "Safe" (nullable) cast operator - -To avoid an exception being thrown, one can use a "safe" cast operator *as?* that returns *null* on failure: -{jet} -val x : String? = y as? String -{jet} -Note that despite the fact that the right-hand side of *as?* is a non-null type {{String}} the result of the cast is nullable. - -h3. What's next - -* [Pattern matching] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40700160_Extension+functions.confluence b/docs/confluence.jetbrains.com/Kotlin/40700160_Extension+functions.confluence deleted file mode 100644 index 9204c87a575..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40700160_Extension+functions.confluence +++ /dev/null @@ -1,61 +0,0 @@ -h1. 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: -{code} -// Java -Collections.swap(list, Collections.binarySearch(list, Collections.max(otherList)), Collections.max(list)) -{code} -Those class names are always getting in the way. We can use static imports and get this: -{code} -// Java -swap(list, binarySearch(list, max(otherList)), max(list)) -{code} -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 -{code} -// Java -list.swap(list.binarySearch(otherList.max()), list.max()) -{code} -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: -{jet} -fun List.swap(x : Int, y : Int) { - val tmp = this[x] // 'this' corresponds to the list - this[x] = this[y] - this[y] = tmp -} -{jet} -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}}: -{jet} -val l = list(1, 2, 3) -l.swap(0, 2) // 'this' inside 'swap()' will hold the value of 'l' -{jet} - -Of course, this function makes sense for any {{List}}, and we can make it generic: -{jet} -fun List.swap(x : Int, y : Int) { - val tmp = this[x] // 'this' corresponds to the list - this[x] = this[y] - this[y] = tmp -} -{jet} -We declare the generic type parameter _before_ the function name for it to be available in the _receiver_ type expression. See [Generic functions|Generics#Generic functions]. - -h2. 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. - -h1. Similar features in other languages - -*AspectJ* has [inter-type declarations|http://www.eclipse.org/aspectj/doc/released/adk15notebook/ataspectj-itds.html]. - -*Groovy* has [metaclasses|http://groovy.codehaus.org/JN3525-MetaClasses]. - -*Scala* makes heavy use of implicit conversions, i.e. wraps values into adapters at runtime. - -*[C#|http://msdn.microsoft.com/en-us/library/bb383977.aspx]* and *[Gosu|http://gosu-lang.org/doc/wwhelp/wwhimpl/api.htm?&context=gosu&src=enhancements&topic=Using_Enhancements]* have extension functions implemented similarly to our approach. - -h1. What's next - -* [Function literals] -* [Type-safe Groovy-style builders] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40700160_Operator+overloading.confluence b/docs/confluence.jetbrains.com/Kotlin/40700160_Operator+overloading.confluence deleted file mode 100644 index 74a61da662e..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40700160_Operator+overloading.confluence +++ /dev/null @@ -1,123 +0,0 @@ -[Kotlin] allows us to provide implementations for a predefined set of operators on our types. These operators have fixed symbolic representation (like '{{+}}' or '{{*}}') and fixed [precedence|Grammar#Precedence]. To implement an operator, one provides a [member function|Functions#Member functions] or an [extension function|Extension functions] with a fixed name, for the corresponding type, i.e. left-hand side type for binary operations and argument type for unary ones. - -h3. Conventions - -Here we describe the conventions that regulate operator overloading for different operators. - -h5. Unary operations - -||Expression||Translated to|| -| {{+a}} | {{a.plus()}} | -| {{-a}} | {{a.minus()}} | -| {{!a}} | {{a.not()}} | - -This table says that when the compiler processes, for example, an expression {{+a}}, it performs the following steps: -# Determines the type of {{a}}, let it be {{T}}. -# Looks up a function {{plus()}} with no parameters for the receiver {{T}}, i.e. a member function or an extension function. -# If the function is absent or ambiguous, it is a compilation error. -# If the function is present and its return type is {{R}}, the expression {{+a}} has type {{R}}. - -*Note* that these operations, as well as all the others, are optimized for [Basic types] and do not introduce overhead of function calls for them. - -||Expression||Translated to|| -| {{a++}} | {{a.inc()}} + see below | -| {{a--}} | {{a.dec()}} + see below | - -These operations are supposed to change their receiver and (optionally) return a value. -{note:title=inc()/dec() shouldn't mutate the receiver object} -By "changing the receiver" we mean the receiver-variable, not the receiver object. -{note} -The compiler performs the following steps for resolution of an operator in the *postfix* form, e.g. {{a++}}: -# Determines the type of {{a}}, let it be {{T}}. -# Looks up a function {{inc()}} with no parameters, applicable to the receiver of type {{T}}. -# If the function returns a type {{R}}, then it must be a subtype of {{T}}. - -The effect of computing the expression is: -# Store the initial value of {{a}} to a temporary storage {{a0}}, -# Assign the result of {{a.inc()}} to {{a}}, -# Return {{a0}} as a result of the expression. - -For {{a--}} the steps are completely analogous. - -For the *prefix* forms {{++a}} and {{--a}} resolution works the same way, and the effect is: -# Assign the result of {{a.inc()}} to {{a}}, -# Return the new value of {{a}} as a result of the expression. - -h5. Binary operations - -||Expression||Translated to|| -| {{a + b}} | {{a.plus(b)}} | -| {{a - b}} | {{a.minus(b)}} | -| {{a * b}} | {{a.times(b)}} | -| {{a / b}} | {{a.div(b)}} | -| {{a % b}} | {{a.mod(b)}} | -| {{a..b}} | {{a.rangeTo(b)}} | - -For the operations in this table, the compiler just resolves the expression in the *Translated to* column. - -||Expression||Translated to|| -| {{a in b}} | {{b.contains(a)}} | -| {{a !in b}} | {{!b.contains(a)}} | - -{anchor:in} -For *in* and *!in* the procedure is the same, but the order of arguments is reversed. - -||Symbol||Translated to|| -| {{a\[i\]}} | {{a.get\(i\)}} | -| {{a\[i, j\]}} | {{a.get\(i, j\)}} | -| {{a\[i_1, ..., i_n\]}} | {{a.get\(i_1, ..., i_n\)}} | -| {{a\[i\] = b}} | {{a.set(i, b)}} | -| {{a\[i, j\] = b}} | {{a.set(i, j, b)}} | -| {{a\[i_1, ..., i_n\] = b}} | {{a.set(i_1, ..., i_n, b)}} | - -Square brackets are translated to calls to {{get}} and {{set}} with appropriate numbers of arguments. - -{anchor:assignments} -||Expression||Translated to|| -| {{a += b}} | {{a.plusAssign(b)}} | -| {{a -= b}} | {{a.minusAssign(b)}} | -| {{a *= b}} | {{a.timesAssign(b)}} | -| {{a /= b}} | {{a.divAssign(b)}} | -| {{a %= b}} | {{a.modAssign(b)}} | - -For the assignment operations, e.g. {{a += b}}, the compiler performs the following steps: -# If the function from the right column is available -## If the corresponding binary function (i.e. {{plus()}} for {{plusAssign()}}) is available too, report error (ambiguity). -## Make sure its return type is {{Unit}}, and report an error otherwise. -## Generate code for {{a.plusAssign(b)}} -# Otherwise, try to generate code for {{a = a + b}} (this includes a type check: the type of {{a + b}} must be a subtype of {{a}}). - -*Note*: assignments are *NOT* expressions in [Kotlin]. - -{anchor:Equals} -||Expression||Translated to|| -| {{a == b}} | {{a?.equals(b) ?: b.identityEquals(null)}} | -| {{a \!= b}} | {{\!(a?.equals(b) ?: b.identityEquals(null))}} | - -*Note*: {{identityEquals}} checks if two references point to the same object. - -The {{==}} operation is special in two ways: -# It is translated to a complex expression that screens for *null*'s, and {{null == null}} is *true*. -# It looks up a function with a specific _signature_, not just a specific _name_. The function must be declared as -{code} -fun equals(other : Any?) : Boolean -{code} -Or an extension function with the same parameter list and return type. - -||Symbol||Translated to|| -| {{a > b}} | {{a.compareTo(b) > 0}} | -| {{a < b}} | {{a.compareTo(b) < 0}} | -| {{a >= b}} | {{a.compareTo(b) >= 0}} | -| {{a <= b}} | {{a.compareTo(b) <= 0}} | - -All comparisons are translated into calls to {{compareTo}}, that is required to return {{Int}}. - -h4. Infix calls for named functions - -One can simulate custom infix operations by using [infix function calls|Functions#Infix calls]. - -h3. What's next - -* [Extension functions] -* [Function literals] -* [Type-safe Groovy-style builders] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40700160_Type-safe+Groovy-style+builders.confluence b/docs/confluence.jetbrains.com/Kotlin/40700160_Type-safe+Groovy-style+builders.confluence deleted file mode 100644 index d34e7ce220c..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40700160_Type-safe+Groovy-style+builders.confluence +++ /dev/null @@ -1,263 +0,0 @@ -The concept of [builders|http://groovy.codehaus.org/Builders] is rather popular in the *Groovy* community. Builders allow for defining data in a semi-declarative way. Builders are good for [generating XML|http://groovy.codehaus.org/GroovyMarkup], [laying out UI components|http://groovy.codehaus.org/GroovySWT], [describing 3D scenes|http://www.artima.com/weblogs/viewpost.jsp?thread=296081] and more... - -For many use cases, [Kotlin] allows to *type-check* builders, which makes them even more attractive than the dynamically-typed implementation made in *Groovy* itself. - -For the rest of the cases, [Kotlin] supports [dynamic|Dynamic types] builders. - -h3. A type-safe builder example - -Consider the following code that is taken from [here|http://groovy.codehaus.org/Builders] and slightly adapted: -{jet} -import html.* - -fun result(args : Array) = - html { - head { - title {+"XML encoding with Kotlin"} - } - body { - h1 {+"XML encoding with Kotlin"} - p {+"this format can be used as an alternative markup to XML"} - - // an element with attributes and text content - a(href = "http://jetbrains.com/kotlin") {+"Kotlin"} - - // mixed content - p { - +"This is some" - b {+"mixed"} - +"text. For more see the" - a(href = "http://jetbrains.com/kotlin") {+"Kotlin"} - +"project" - } - p {+"some text"} - - // content generated by - p { - for (arg in args) - +arg - } - } - } -{jet} -This is a completely legitimate [Kotlin] code. Click on names to navigate to definitions of function used in this example (they appear below in this page). - -h3. How it works - -Let's walk through the mechanisms of implementing type safe builders in [Kotlin]. First of all we need to define the model we want to build, in this case we need to model HTML tags. It is easily done with a bunch of classes. For example, {{HTML}} is a class that describes the {{}} tag, i.e. it defines children like {{}} and {{}}. -(See its declaration [below|#declarations].) - -Now, let's recall why we can say something like this in the code: -{jet} -html { - // ... -} -{jet} -This is actually a function call that takes a [function literal|Function literals] as an argument (see [this page|Functions#Higher-order functions] for details). Actually, this function is defined as follows: -{jet} -fun html(init : HTML.() -> Unit) : HTML { - val html = HTML() - html.init() - return html -} -{jet} -This function takes one parameter named {{init}}, which is itself a function. Actually, it is an [extension function|Extension functions] that has a receiver of type {{HTML}} (and returns nothing interesting, i.e. [Unit|Functions#Unit]). So, when we pass a function literal to as an argument to {{html}}, it is typed as an extension function literal, and there's *this* reference available: -{jet} -html { - this.head { /* ... */ } - this.body { /* ... */ } -} -{jet} -({{head}} and {{body}} are member functions of {{HTML}}.) -Now, *this* can be omitted, as usual, and we get something that looks very much like a builder already: -{jet} -html { - head { /* ... */ } - body { /* ... */ } -} -{jet} -So, what does this call do? Let's look at the body of {{html}} function as defined above. It creates a new instance of {{HTML}}, then it initializes it by calling the function that is passed as an argument (in our example this boils down to calling {{body}} on the {{HTML}} instance), and then it returns this instance. This is exactly what a builder should do. - -The {{head}} and {{body}} functions in the {{HTML}} class is defined similarly to {{html}}. The only difference is that they add the built instanced to the {{children}} collection of the enclosing {{HTML}} instance: -{jet} -fun head(init : Head.() -> Unit) { - val head = Head() - head.init() - children.add(head) - return head -} - -fun body(init : Body.() -> Unit) { - val body = Body() - body.init() - children.add(body) - return body -} -{jet} -Actually these two functions do just the same thing, so we can have a generic version, {{initTag}}: -{jet} -protected fun initTag(init : T.() -> Unit) : T - where class object T : Factory { - val tag = T.create() - tag.init() - children.add(tag) - return tag -} -{jet} -This function uses [class objects|Classes and Inheritance#Class objects] to instantiate classes. It depends on the {{Factory}} class defined as follows: -{jet} -abstract class Factory { - fun create() : T -} -{jet} - -Now, the classes {{Head}} and {{Body}} declare class objects that extend {{Factory}}, for example: -{jet} -class Head() : TagWithText("head") { - class object : Factory { - override fun create() = Head() - } - - // ... -} -{jet} - -So, now our functions are very simple: -{jet} -fun head(init : Head.() -> Unit) = initTag(init) - -fun body(init : Body.() -> Unit) = initTag(init) -{jet} - -And we can use them to build {{}} and {{}} tags. - -One other thing to be discussed here is how we add text to tag bodies. In the example above we say something like -{jet} -html { - head { - title {+"XML encoding with Kotlin"} - } - // ... -} -{jet} -So basically, we just put a string inside a tag body, but there is this little "+" in front of it, do it is a function call that invokes a prefix "plus" operation. That operation is actually defined by an extension function {{plus}} that is a member of the {{TagWithText}} abstract class (a parent of {{Title}}): -{jet} -fun String.plus() { - children.add(TextElement(this)) -} -{jet} -So, what the prefix "+" does here is it wraps a string into an instance of {{TextElement}} and adds it to the {{children}} collection, so that it becomes a proper part of the tag tree. - -All this is defined in a namespace {{html}} that is imported at the top of the builder example above. In the next section you can read through the full definition of this namespace. - -h3. Full definition of the {{html}} namespace - -This is how the namespace {{html}} is defined (only the elements used in the example above). It builds an HTML tree. It makes heavy use of [Extension functions] and [Extension function literals|Function literals#Extensions]. -{anchor:declarations}{jet} -namespace html { - - abstract class Factory { - fun create() : T - } - - abstract class Element - - class TextElement(val text : String) : Element - - abstract class Tag(val name : String) : Element { - val children = ArrayList() - val attributes = HashMap() - - protected fun initTag(init : T.() -> Unit) : T - where class object T : Factory { - val tag = T.create() - tag.init() - children.add(tag) - return tag - } - } - - abstract class TagWithText(name : String) : Tag(name) { - fun String.plus() { - children.add(TextElement(this)) - } - } - - class HTML() : TagWithText("html") { - class object : Factory { - override fun create() = HTML() - } - - fun head(init : Head.() -> Unit) = initTag(init) - - fun body(init : Body.() -> Unit) = initTag(init) - } - - class Head() : TagWithText("head") { - class object : Factory { - override fun create() = Head() - } - - fun title(init : Title.() -> Unit) = initTag(init) - } - - class Title() : TagWithText("title") - - abstract class BodyTag(name : String) : TagWithText(name) { - } - - class Body() : BodyTag("body") { - class object : Factory { - override fun create() = Body() - } - - fun b(init : B.() -> Unit) = initTag(init) - fun p(init : P.() -> Unit) = initTag(init) - fun h1(init : H1.() -> Unit) = initTag(init) - fun a(href : String, init : A.() -> Unit) { - val a = initTag(init) - a.href = href - } - } - - class B() : BodyTag("b") - class P() : BodyTag("p") - class H1() : BodyTag("h1") - class A() : BodyTag("a") { - var href : String - get() = attributes["href"] - set(value) { attributes["href"] = value } - } - - fun html(init : HTML.() -> Unit) : HTML { - val html = HTML() - html.init() - return html - } - -} -{jet} - -h3. Appendix. Making Java classes nicer - -In the code above there's something that looks very nice: -{jet} - class A() : BodyTag("a") { - var href : String - get() = attributes["href"] - set(value) { attributes["href"] = value } - } -{jet} -We access the {{attributes}} map as if it were an "associative array": just with the {{\[\]}} operation. By [convention|Operator overloading] this compiles to a call to {{get(K)}} or {{set(K, V)}}, all right. But we said that {{attributes}} was a *Java* {{Map}}, i.e. it does NOT have a {{set(K, V)}}. This problem is easily fixable in [Kotlin]: -{jet} - fun Map.set(key : K, value : V) = this.put(key, value) -{jet} -So, we simply define an [extension function|Extension functions] {{set(K, V)}} that delegates to vanilla {{put}} and make a [Kotlin] operator available for a *Java* class. - -h3. What's next - -*Examples* -* [Comparison to Java] - -*Functions* -* [Properties And Fields] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40700182_Modules+%E2%80%94+Rethought+to+packages.confluence b/docs/confluence.jetbrains.com/Kotlin/40700182_Modules+%E2%80%94+Rethought+to+packages.confluence deleted file mode 100644 index 77971676681..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40700182_Modules+%E2%80%94+Rethought+to+packages.confluence +++ /dev/null @@ -1,178 +0,0 @@ -h2. Modules/Namespaces rethought - -In the initial design we had modules and namespaces. -*Module* is a unit of compilation, specifies dependencies and provides a scope for *internal* visibility. -*Namespaces* are just intended for name disambiguation, they have a syntactic for (two, actually): each file may have a namespace declaration in the header, and all the contents are placed under that namespace. Additionally, there may be namespace blocks. Each namespace occurrence has a separate block of imports. - -_All this looks a little bit brittle, so we rethought the design, and propose a unified concept of *packages* that replaces modules and namespaces:_ - - -h3. Packages - -(Our packages are similar to Java's ones, but there are some important differences, so, please, read carefully.) - -A *package* is a group of source files along with dependencies, default imports and other compiler settings. -* Any *unit of compilation* is a package, although some packages are not units of compilation. -* Every source file declares the package it belongs to in a *package* directive (like in Java). This is needed only for self-documentation of the code. -** If there's no *package* directive in a file, it is a script (whatever it means) -* Packages are not tied up to file system, one can have as many directories for the code in a single packages as they please. One can store a dozen packages in a single directory as well. -* One file immediately belongs to exactly one package, though. -* Every package has a unique name and encloses its contents so that there may be two entities with the same name in different packages. - -Example of a kotlin file: -{jet} -package my.example - -import other.* - -fun foo() {} // package-level function -class A {} // FQN is my.example.A -class B {} // many classes in a file -{jet} - -Packages may *contain* other packages. By default, child packages inherit all the compiler settings from their parents. -* Every package defines a *visibility* scope. It may contain *internal* members, including child packages. Internal members are visible to all the members of the package and their members as well. -* Only members of the same package are visible by default (without importing). Members of child and enclosing packages are accessible but require importing. - -Example: -{jet} -package my.example.other // sits inside my.example - -val a : A = ... // class my.example.A is not visible without importing -fun foo() {} // default visibility is internal: visible to child packages and other members of this package - -public class Foo {} // visible to everybody who sees this package -{jet} - -To specify package *settings* such as visibility, dependencies etc, one may define a package configuration script in the spirit of former module scripts. -* At least the root package in the project must have such a script, a single script may describe several packages. -* If a package has no script, then it's visibility is *internal* and all the other settings are inherited from its parent. - -h3. Summary. Diff from Java - -How Kotlin packages are better that Java ones: -* In Kotlin package is a *unit* of compilation (optimization for *internal* things) -* Kotlin packages specify their dependencies, default imports and other compiler settings -* Packages truly nest in Kotlin (hence *internal* visibility is useful) -* Kotlin packages are not folders, i.e. not tied up to the file system -* You name it - -*Your objections/corrections/proposals are very welcome in the comments.* - ----- - -Here goes the old descriptions of modules: - -h2. Overall structure - -A *module* is a unit of compilation, i.e. we do not compile classes or source file, we compile _modules_. -A module descriptor contains information about source files that reside in the module, how they are divided into production code and test code, dependencies, compiler options and so on. - -h3. Module scripts - -Physically, modules are represented as *scripts* written in Kotlin. The compiler (or IDE, or other tool) runs a script that builds a module object in memory, and uses the information from that object to resolve dependencies and compile the sources. - -A script creates objects that describe the modules and adds them to a *project* object that is passed to the script by the caller (typically, the compiler or the IDE). - -h3. Class path issues & configuration - -There're two kinds of class paths: -* Compiler class path: classes that Kotlin compiler uses at runtime -** module scripts are compiled against this class path -** this class path is configured in a {{.kotlinrc}} file: there's a global one, one in home dir, and one in local dir -* Module class path: classes the module is compiled against (does not necessarily contain all classes in the compiler class path) -** Specified in a module script - -Example: -Compiler class path would contain things like {{maven4kotlin.jar}}, {{my_compiler_extension_1.0.jar}} and such. -Module class path would contain things like {{my_nosqldb_driver.jar}}, {{my_actor_library.jar}}, {{janes_module.jar}} and such. - -h2. Information that constitutes a module descriptor -* Basic metadata -** Root namespace/module name -* Sources -** Kotlin source files -** Java source files -* Compiler options -** Kotlin compiler options -*** Extensions -- what compiler extensions to use to compile this module -*** Default imports -- what's imported by default into every source file -** Javac options -* Dependencies (each may be exported or private, and embedded, jarjar'ed or not embedded) -** JDK -** Java-style class path -** Kotlin modules -** Maven modules -** ... -* User data -** Key-value pairs - -NOTE: currently there's no built-in versioning for modules planned. We intend to reuse Maven for that. - -Files are treated according to their types. E.g. *.java files are Java sources, *.kt files are Kotlin sources etc. One can register custom file types in a module script. - -h2. What a module script looks like - -Syntactically, a script is not a normal Kotlin source file: it contains import directives followed immediately by code. And this code has an implicit receiver of type {{Project}} that has member functions for building module objects: -{jet} -import kotlin.modules.dependencies.maven.* - -fun ModuleBuilder.defineModules() { - jdk = defaultJDK("1.6") - - // Standard extensions are registered, adding custom ones - source mask "*.jav" language java // Non-standard extension for Java - source mask "*.kt" language kotlin - resource mask "*.bundle" - - module ("org.example.mymodule") { - source files "kotlin/src/*.kt" - source root "kotlin_src" - source root "java_src" - - kotlin extension MyCoolExtension - kotlin import "kotlin.*" - kotlin import "java.lang.*" - kotlin import "java.util.*" - - javac options "-g:lines -Afoo=bar" - - classpath entries "lib/*.jar" - classpath entry "bin/classes" - - require module "org.jetbrains.extras" - require maven "junit" version "3.8.1" - - resource root "resources" - - data["key"] = "value" - } -} -{jet} - -Actually, the {{module()}} is called on the *this* reference that represents current project. - -One other difference from normal Kotlin is that a script can define *public val*'s. A public *val* may be used by another script that "requires" this one: - -E.g., {{Compiler.kts}}: -{jet} -public val frontend = module("kotlin.frontend") { - ... -} -public val frontend_java = module("kotlin.frontend.java") { - ... -} -public val backend = module("kotlin.backend") { - ... -} -{jet} - -{{IDE.kts}}: -{jet} -val compiler = requireScript - -module ("ide") { - ... - require module compiler.frontend -} -{jet} \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40701077_Address+book.confluence b/docs/confluence.jetbrains.com/Kotlin/40701077_Address+book.confluence deleted file mode 100644 index d97e058dfdb..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40701077_Address+book.confluence +++ /dev/null @@ -1,53 +0,0 @@ -{jet} -namespace addressbook - -class Contact( - val name : String, - val emails : List, - val addresses : List, - val phonenums : List -) - -class EmailAddress( - val user : String, - val host : String -) - -class PostalAddress( - val streetAddress : String, - val city : String, - val zip : String, - val state : USState?, - val country : Country -) { - assert {(state == null) xor (country == Countries["US"]) } -} - -class PhoneNumber( - val country : Country, - val areaCode : Int, - val number : Long -) - -object Countries { - fun get(id : CountryID) : Country = countryTable[id] - - private var table : Map? = null - private val countryTable : Map - get() { - if (table == null) { - table = HashMap() - for (line in TextFile("countries.txt").lines(stripWhiteSpace = true)) { - table[line] = Country(line) - } - } - return table - } -} - -class Country(val name : String) -{jet} - -h3. What's next - -* [HTML builder example|Type-safe Groovy-style builders] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40701077_Basic+syntax+walk-through.confluence b/docs/confluence.jetbrains.com/Kotlin/40701077_Basic+syntax+walk-through.confluence deleted file mode 100644 index 9a51d4b0660..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40701077_Basic+syntax+walk-through.confluence +++ /dev/null @@ -1,249 +0,0 @@ -h4. Define a package - -{jet} -package my.demo // One per file - -import std.io.* - -// ... -{jet} - -See [Packages]. - -h4. Define a function - -{jet} -// Return type mandatory -fun sum(a : Int, b : Int) : Int { - return a + b -} -{jet} - -or - -{jet} -// Return type may be inferred -fun sum(a : Int, b : Int) = a + b -{jet} - -When no meaningful value returned: -{jet} -fun printSum(a : Int, b : Int) : Unit { - print(a + b) -} -{jet} - -or - -{jet} -// Return type is optional when Unit is intended -fun printSum(a : Int, b : Int) { - print(a + b) -} -{jet} - -See [Functions]. -See [Hello, world!]. - -h4. Define a local variable - -Assign-once (read-only) local variable: -{jet} -val a : Int = 1 -val b = 1 // Type is inferred -val c : Int // Type required when no initializer provided -c = 1 // definite assignment -{jet} - -Note that [semicolons are optional|Grammar#Semicolons]. - -Mutable variable: -{jet} -var x = 5 // Type inferred -x += 1 -{jet} - -See also [Properties And Fields]. - -h4. Use a string template - -{jet} -fun main(args : Array) { - if (args.size == 0) return - - print("First argument: ${args[0]}") -} -{jet} - -See [String templates|Strings#Templates]. -See [Arrays|Basic types#Arrays]. - -h4. Use a conditional expression - -{jet} -fun max(a : Int, b : Int) : Int { - if (a > b) - return a - else - return b -} -{jet} - -or -{jet} -// 'if' is an expression -fun max(a : Int, b : Int) = if (a > b) a else b -{jet} - -See [{{if}} expressions|Control structures#If]. - -h5. Null-checks - -A reference must be explicitly marked as _nullable_ to be able hold a {{null}}: -{jet} -package multiplier - -// Return null if str does not hold a number -fun parseInt(str : String) : Int? { - // ... -} - -fun main(args : Array) { - if (args.size < 2) { - print("No number supplied"); - } - val x = parseInt(args[0]) - val y = parseInt(args[1]) - - // We cannot say 'x * y' now because they may hold nulls - - if (x != null && y != null) { - print(x * y) // Now we can - } -} -{jet} - -or - -{jet} -// ... - if (x == null) { - print("Wrong number format in '${args[0]}'") - return - } - if (y == null) { - print("Wrong number format in '${args[1]}'") - return - } - print(x * y) // Now we know that x and y are not nulls -{jet} - -See [Null-safety]. - -h5. {{is}}-checks and automatic casts - -The *is* operator checks if an expression is an instance of a type (and [more|Pattern matching]). If we *is*-checked an immutable local variable or property, there's no need to cast it explicitly to the *is*-checked type: -{jet} -fun getStringLength(obj : Any) : Int? { - if (obj is String) - return obj.length // no cast to String is needed - return null -} -{jet} - -or - -{jet} -fun getStringLength(obj : Any) : Int? { - if (obj !is String) - return null - return obj.length // no cast to String is needed -} -{jet} - -See [Classes and Inheritance]. -See [Type casts]. - -h4. Use a {{for}}-loop - -{jet} -fun main(args : Array) { - for (arg in args) - print(arg) - -// or - - for (i in args.indices) - print(args[i]) -} -{jet} - -See [{{for}}-loops|Control structures#For]. - -h4. Use a {{while}}-loop - -{jet} -fun main(args : Array) { - var i = 0 - while (i < args.size) - print(args[i++]) -} -{jet} - -See [{{while}}-loop|Control structures#While]. - -h4. Use pattern-matching - -{jet} -fun cases(obj : Any) { - when (obj) { - 1 -> print("One") - "Hello" -> print("Greeting") - is Long -> print("Long") - !is String -> print("Not a string" - else -> print("Unknown") - } -} -{jet} - -See [Pattern matching]. - -h4. Use ranges and {{in}} - -Check if a number lies within a range: -{jet} -if (x in 1..y-1) - print("OK") -{jet} - -Check if a number is out of range: -{jet} -if (x !in 0..array.lastIndex) - print("Out") -{jet} - -Check if a collection contains an object: -{jet} -if (obj in collection) // collection.contains(obj) is called - print("Yes") -{jet} - -Iterate over a range: -{jet} -for (x in 1..5) - print(x) -{jet} - -See [Ranges]. - -h4. Use function literals to filter and map collections - -{jet} -names filter {it.startsWith("A")} sortby {it} map {it.toUpperCase()} foreach {print(it)} -{jet} - -See [Higher-order functions|Functions#Higher-order functions] and [Function literals]. - -h3. What's next - -* [Address book example|Address book] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40701077_Hello%2C+world%21.confluence b/docs/confluence.jetbrains.com/Kotlin/40701077_Hello%2C+world%21.confluence deleted file mode 100644 index 35b1be08e30..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40701077_Hello%2C+world%21.confluence +++ /dev/null @@ -1,104 +0,0 @@ -This page gives some very basic examples of [Kotlin] syntax. - -h3. Simplest version - -{jet:linenumbers=true} -package demo - -fun main(args : Array) { - println("Hello, world!") -} -{jet} - -Line 1 is the optional [package header|Packages#Header package declaration]. -Then we declare a [package-level|Packages] function {{main}} which [returns {{Unit}}|Functions#Unit] and takes an [Array|Basic types#Arrays] of strings as a parameter. - -Note that [semicolons are optional|Grammar#Semicolons]. - -h3. Reading a name from the command line - -{jet:linenumbers=true} -fun main(args : Array) { - if (args.size == 0) { - println("Please provide a name as a command-line argument") - return - } - println("Hello, ${args[0]}!") -} -{jet} - -Line 6 demonstrates [string templates|Strings#Templates] and [array access|Basic types#Arrays]. - -h3. Reading many names from the command line - -{jet:linenumbers=true} -fun main(args : Array) { - for (name in args) - println("Hello, $name!") -} -{jet} - -Line 2 demonstrates the [*for*\-loop|Control structures#For loop], that would have been called "enhanced" if there were any other *for*\-loop in [Kotlin] :-) - -h3. An "object-oriented" Hello - -{jet:linenumbers=true} -class Greeter(val name : String) { - fun greet() { - println("Hello, ${name}"); - } -} - -fun main(args : Array) { - Greeter(args[0]).greet() -} -{jet} - -Here we have a [class|Classes and Inheritance] with a _primary constructor_ and a member function. -Note that there's no *new* keyword used to create an object. - -h3. A multi-language Hello - -{jet:linenumbers=true} -fun main(args : Array) { - val language = if (args.size == 0) "EN" else args[0] - println(when (language) { - "EN" -> "Hello!" - "ES" -> "¡Hola!" - "RU" -> "Привет!" - else -> "Sorry, I can't greet you in $language yet" - }) -} -{jet} - -In this example, *val* denotes a declaration of a read-only local variable, that is assigned an [*if*\-expression|Control structures#If expression]. Then we use very basic [pattern matching|Pattern matching] expression. - -h3. Extension function {{hello()}} - -{jet:linenumbers=true} -fun String.hello() { - println("Hello, $this!") -} - -fun main(args : Array) { - "world".hello() // prints 'Hello, world!' -} -{jet} - -In this snippet, we define an [extension function|Extension functions] {{hello()}} for the type {{String}} that uses *this* in a [string template|Strings#Templates]. And then we call this function on a string {{"world"}}, i.e. we pass this string as the receiver-argument (*this*\-argument) to {{hello()}}. - -h3. LINQ-like Hello - -{jet:linenumbers=true} -fun main(args : Array) { - args filter {it.length() > 0} forEach {print("Hello, $it!")} -} -{jet} - -Here we first called the {{filter()}} [higher-order function|Functions#Higher-order functions] to select only those string from the {{args}} array that have non-zero length. To do this, we passed a [function literal|Function literals] that checks the length of its parameter. the name {{it}} is the default name of a parameter for a function literal. - -Filter created a collection for us, and we called {{foreach()}} on that collection, passing in a function literal to be executed for each element. And that function literal just prints a greeting with the passed string. - -h3. What's next - -* [Basic syntax walk-through|Basic syntax walk-through] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40702623_Annotations.confluence b/docs/confluence.jetbrains.com/Kotlin/40702623_Annotations.confluence deleted file mode 100644 index ddd8b23a8ed..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40702623_Annotations.confluence +++ /dev/null @@ -1,56 +0,0 @@ -In Kotlin, one can attach metadata to declarations in the form of _annotations_. To declare an annotation, put the *annotation* annotation (no pun intended :)) in front of a normal class: -{jet} -annotation class fancy {} -{jet} -(Note that, by convention, annotation classes are named with the lowercase fitst letter; the reason will be clear from the examples below.) -Now we can annotate a declaration or an expression with the new {{fancy}} annotation. In general, one puts square brackets around the annotation name: -{jet} -[fancy] class Foo { - [fancy] fun baz([fancy] foo : Int) : Int { - return [fancy] 1 - } -} -{jet} -{note:title=Annotations are under development}{note} - -When annotating a declaration (e.g. a function or a class), the square brackets may be omitted: -{jet} -fancy class Foo() { - fancy fun baz(fancy foo: Int) { - return [fancy] 1 - } -} -{jet} -Note that square brackets are required for expressions. - -Annotation classes may have constructors that take parameters. For example: -{jet} -annotation class special(val why : String) - -special("example") class Foo {} -{jet} -As you can see, to pass arguments to an annotation one simply calls its constructor. - -On the JVM one can re-use Java annotations: -{jet} -import org.junit.Test -import org.junit.Assert.* - -class Tests { - Test fun simple() { - assertEquals(42, getTheAnswer()) - } -} -{jet} - -If you want your Java annotations to look like modifiers, you can rename them on import: - -{jet} -import org.junit.Test as test - -class Tests { - test fun simple() { - ... - } -} -{jet} diff --git a/docs/confluence.jetbrains.com/Kotlin/40702623_Basic+types.confluence b/docs/confluence.jetbrains.com/Kotlin/40702623_Basic+types.confluence deleted file mode 100644 index 384fd19825c..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40702623_Basic+types.confluence +++ /dev/null @@ -1,181 +0,0 @@ -In [Kotlin], everything is an object in the sense that one can call member functions and properties on any variable. Some types are built-in, because their implementation is optimized, but for the used they look like ordinary classes. In this section we describe most of these types: [numbers|#Numbers], [characters|#Characters], [booleans|#Booleans] and [arrays|#Arrays]. - -h3. Numbers - -[Kotlin] handles numbers in a way close to *Java*, but not exactly the same. For example, there are no _implicit widening conversions_ or numbers, and literals are slightly different in some cases. - -[Kotlin] provides the following built-in types representing numbers (this is close to *Java*): -|| Type || Bitwidth || -| Double | 64 | -| Float | 32 | -| Long | 64 | -| Int | 32 | -| Short | 16 | -| Byte | 8 | - -Note that [characters|#Characters] are not numbers in [Kotlin]. - -h4. Representation - -On the *Java* platform, numbers are physically stored as JVM primitive types, unless we need a [nullable|Null-safety] number reference (e.g. {{Int?}}) or generics are involved. In the latter cases numbers are _boxed_. - -*Note* that boxing of numbers does not preserve [identity|Basic operations]: -{jet} -val a : Int = 10000 -print(a identityEquals a) // Prints 'true' -val boxedA : Int? = a -val anotherBoxedA : Int? = a -print(boxedA identityEquals anotherBoxedA) // !!!Prints 'false'!!! -{jet} -On the other hand, it preserves [equality|Expressions#Equality checks]: -{jet} -val a : Int = 10000 -print(a == a) // Prints 'true' -val boxedA : Int? = a -val anotherBoxedA : Int? = a -print(boxedA == anotherBoxedA) // Prints 'true' -{jet} - -h4. Explicit conversions - -Due to different representations, smaller types are not _subtypes_ of bigger ones. -If they were, we would have troubles of the following sort: -{jet} -// Hypothetical code, does not actually compile: -val a : Int? = 1 // A boxed Int (java.lang.Integer) -val b : Long? = a // implicit conversion yields a boxed Long (java.lang.Long) -print(a == b) // Surprise! This prints "false" as Long's equals() check for other part to be Long as well -{jet} -So not only identity, but even equality would have been lost silently all over the place. - -As a consequence, smaller types are *NOT* implicitly converted to bigger types. This means that one cannot assign a value of type {{Byte}} to an {{Integer}} variable without an explicit conversion: -{jet} -val b : Byte = 1 // OK, literals are checked statically -val i : Int = b // ERROR -{jet} -One can use *explicit conversions* to widen numbers: -{jet} -val i : Int = b.int // OK: explicitly widened -{jet} - -Every number type supports the following conversions: -* {{toLong() : Byte}} -* {{toShort() : Short}} -* {{toInt() : Int}} -* {{toLong() : Long}} -* {{toFloat() : Float}} -* {{toDouble() : Double}} -* {{toChar() : Char}} - -Absence of implicit conversions is rarely noticeable because one can use literals almost freely cause the type is inferred from the context, and arithmetical operations are _overloaded_ for appropriate conversions, for example -{jet} -val l = 1.toLong() + 3 // Long + Int => Long -{jet} - -h4. Literals - -All the integer literals are written in the same way: -* Decimals: {{123}}, {{123.5}}, {{123.5e10}} -* Hexadecimals: {{0x0F}} -* Binaries: {{0b00001011}} - -*NOTE*: Octal literals are not supported. - -There're no "L"-tagged or otherwise tagged literals. In case of ambiguity, one should use explicit conversions to specify a type for a literal: -{jet} -val list = list(1.toLong(), 100000000000, 2.toLong()) -{jet} - -h4. Operations - -[Kotlin] supports the standard set of arithmetical operations over numbers, which are declared as members of appropriate classes (but the compiler optimizes the calls down to the corresponding instructions). See [Operator overloading|Functions#Operator overloading]. - -As of _bitwise_ operations, there're no special characters for them, but just named functions that can be called in [infix form|Functions#Infix calls], for example: -{jet} -val x = (1 shl 2) and 0x000FF000 -{jet} -Here is the complete list of bitwise operations (available for {{Int}} and {{Long}} only): -* {{shl(bits)}} -- signed shift left (*Java*'s {{<<}}) -* {{shr(bits)}} -- signed shift right (*Java*'s {{>>}}) -* {{ushr(bits)}} -- unsigned shift right (*Java*'s {{>>>}}) -* {{and(bits)}} -- bitwise {{and}} -* {{or(bits)}} -- bitwise {{or}} -* {{xor(bits)}} -- bitwise {{xor}} -* {{inv()}} -- bitwise inversion - -h2. Characters - -Characters are represented by the type {{Char}}. They are can not be treated directly as numbers: -{jet} -fun check(c : Char) { - if (c == 1) { // ERROR: incompatible types - // ... - } -} -{jet} -Character literals go in single quotes: {{'1'}}, {{'\n'}}, {{'\uFF00'}}. -One can explicitly _convert_ a character to an {{Int}} number: -{jet} -fun decimalDigitValue(c : Char) : Int { - if (c !in '0'..'9') - throw IllegalArgumentException("Out of range") - return c.toInt() - '0'.toInt() // Explicit conversions to numbers -} -{jet} - -Like numbers, characters are *boxed* when a nullable reference is needed. Identity is not preserved by the boxing operation. - -h2. Booleans - -The type {{Boolean}} represents booleans, and has two values: {{true}} and {{false}}. - -Booleans are boxed if a nullable reference is needed. - -Built-in operations on booleans include -* {{\|\|}} -- lazy disjunction -* {{&&}} -- lazy conjunction - -h3. Arrays - -Arrays in [Kotlin] are represented by the {{Array}} class, that has {{get}} and {{set}} functions (that turn into {{\[\]}} by [operator overloading conventions|Operator overloading]), and {{size}}, along with a few other useful member functions: -{jet} -class Array(val size : Int, init : (Int) -> T) { - fun get(index : Int) : T - fun set(index : Int, value : T) : Unit - - fun iterator() : Iterator - - val indices : IntRange -} -{jet} - -To create an array one can call its [constructor|Classes and Inheritance#Classes and Primary constructors] providing the array size and a [function|Function literals] that knows how to initialize elements of the array: -{jet} - val asc = Array(5, {i -> i * i}) // Creates an array [0, 1, 2, 3, 4] -{jet} -Or, alternatively, one can use a library function {{array()}} and pass the item values to it, so that {{array(1, 2, 3)}} creates an array {{\[1, 2, 3\]}}. - -As we said above, the {{\[\]}} operation stands for calls to member functions {{get()}} and {{set()}}. When compiling to JVM byte codes, the compiler optimizes access to arrays so that there's no overhead introduced, and all operations work exactly like in *Java*: -{jet} -val array = array(1, 2, 3, 4) -array[x] = array[x] * 2 // no actual calls to get() and set() generated -for (x in array) // no iterator created - print(x) -{jet} -Even when we navigate with an index, it does not introduce any overhead: -{jet} -for (i in array.indices) // no iterator created - array[i] += 2 -{jet} -Finally, *in*\-checks have no overhead either -{jet} -if (i in array.indices) { // same as (i >= 0 && i < array.size) - print(array[i]) -} -{jet} - -*Note*: arrays are [invariant|Java interoperability#Arrays]. For the best performance on the JVM use [specialized array classes|Java interoperability#Arrays]. - -h3. What's next - -* [Strings] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40702623_Classes+and+Inheritance.confluence b/docs/confluence.jetbrains.com/Kotlin/40702623_Classes+and+Inheritance.confluence deleted file mode 100644 index f1a6b4f857f..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40702623_Classes+and+Inheritance.confluence +++ /dev/null @@ -1,291 +0,0 @@ -h1. Classes and Primary constructors - -Here is an example of a class declaration in [Kotlin]: -{jet} -class Example(param : Int) { - val property = param -} -{jet} -Let's start with the header that says -{jet} -class Example(param : Int) { -{jet} -This is a declaration of a class {{Example}} that has a constructor that takes one parameter of type {{Int}}. Such constructors, declared immediately in the class header, are called _primary constructors_. - -To create a new instance of the class {{Example}}, one simply calls its constructor, as if it were a regular function: -{jet} -val e = Example(10) -{jet} -(Note that one does not need the *new* keyword.) - -If a class does not have any constructors declared, one cannot instantiate it: -{jet} -class Some {} - -val s = Some() // Error: no constructor for Some -{jet} -*Note* that a class with no constructors must not declare any state (properties with backing fields), or inherit from classes that have constructors. - -What does the primary constructor do? It executes the initializers of properties, in the order of declaration. These initializers can use the constructor's parameters. In the example above, the only thing the constructor does is initialization of {{property}}. - -Additionally, one can place "anonymous initializers" in the body of a class, just surrounding pieces of code with curly braces: -{jet} -class ExampleWithAnonymousInitializer(param : Int) { - val property = HashSet() - { - property.add(param) - } -} -{jet} -Here, the primary constructor first creates a new {{HashSet}}, assigns it to {{property}} and then adds the value of {{param}} to this set. - -{anchor:bean-class} -Parameters of primary constructors can be prefixed with *val* or *var* keywords to declare corresponding [properties|Properties And Fields] in-place: -{jet} -class Bean(val prop1 : Int, val prop2 : String) -{jet} -Class body is optional, and the example above is a complete declaration of a class that has two properties *prop1* and *prop2* and a primary constructor with two parameters, that initializes these properties in an obvious way. - -So, it does not take you much code to declare a bean-style data class in [Kotlin], at least it is a lot less code than in Java. - -h1. Class members - -Classes have the following kinds of members: -* [Functions] -* [Properties|Properties And Fields] -* [Other classes|Nested classes] -* [Object declarations|Object expressions and Declarations] - -h1. Inheritance - -All classes in [Kotlin] have a common superclass {{Any}}, that is a default super for a class with no supertypes declared: -{jet} -class Example // Implicitly inherits from Any -{jet} - -{{Any}} is not {{java.lang.Object}}; in particular, it does not have any members, not even {{equals()}}, {{hashCode}} or {{toString()}}. This does not mean that you can not call, say, {{toString()}} on any object: you can, but it will be an [extension function|Extension functions]. See [Java interoperability#Object methods] for more details. - -To declare an explicit supertype, one puts it after a colon in the class header: -{jet} -open class Base(p : Int) - -class Derived(p : Int) : Base(p) -{jet} -As you can see, the base type can (and must) be initialized right there, using the parameters of the primary constructor. - -The *open* annotation on a class is the opposite of *Java*'s *final*: it allows others to inherit from this class. By default, all classes in [Kotlin] are *final*, which corresponds to Item 17 of _[Effective Java|http://java.sun.com/docs/books/effective]_: *Design and document for inheritance or else prohibit it*. - -A class may have _many supertypes_. See [*this post*|http://blog.jetbrains.com/kotlin/2011/08/multiple-inheritance-part-2-possible-directions/] for more details. - -h2. Overriding members - -As we mentioned before, we stick to making things explicit in [Kotlin]. And unlike *Java*, [Kotlin] requires explicit annotations for overridable members that we call *open* and for *overrides*: -{jet} -open class Base { - open fun v() {} - fun nv() {} -} -class Derived() : Base { - override fun v() {} -} -{jet} -The *override* annotation is required for {{Derived.v()}}. If it were missing, the compiler would complain. If there is no *open* annotation on a function, like {{Base.nv()}}, declaring a method with the same signature in a subclass is illegal, either with *override* or without it. In a *final* class (e.g. a class with no *open* annotation), *open* members are prohibited. - -A member marked *override* is itself _open_, i.e. it may be overridden in subclasses. If you want to prohibit re-overriding, use *final*: -{jet} -open class AnotherDerived() : Base { - final override fun v() {} -} -{jet} - -h3. (!) Wait\! How will I hack my libraries now?\! - -One issue with our approach to overriding (classes and members *final* by default) is that it would be difficult to subclass something inside the libraries you use to override some method that was not intended for overriding by the library designer, and introduce some nasty hack there. - -We think that this is not a disadvantage, for the following reasons: -# Best practices say that you should not allow these hacks anyway -# People successfully use other languages (C++, C#) that have similar approach -# If people really want to hack, there still are ways: in some cases it will be possible to write your hack in Java, and Aspect frameworks always work for these purposes... - -h2. Traits - -_Traits_ are essentially interfaces with (optional) method bodies. See [*this post*|http://blog.jetbrains.com/kotlin/2011/08/multiple-inheritance-part-2-possible-directions/] for more details. - -h2. Overriding rules - -In [Kotlin], implementation inheritance is regulated by the following rule: if a class inherits many _implementations_ of the same member from its immediate superclasses, it must override this member and provide its own implementation (perhaps, using one of the inherited ones). To denote the supertype from which the inherited implementation is taken, we use *this* qualified by the supertype name in angle brackets, e.g. *this{*}{{}}: -{jet} -open class A { - open fun f() { print("A") } - fun a() { print("a") } -} - -trait B { - open fun f() { print("B") } - open fun b() { print("b") } -} - -class C() : A(), B { - // The compiler requires f() to be overridden: - override fun f() { - super.f() // call to A.f() - super.f() // call to B.f() - } -} -{jet} -It's fine to inherit from both {{A}} and {{B}}, and we have no problems with {{a()}} and {{b()}} since {{C}} inherits only _one implementation_ of each of these functions. But for {{f()}} we have _two_ implementations inherited by {{C}}, and this we _have to_ override {{f()}} in {{C}} and provide our own implementation that eliminates the ambiguity. - -h2. Abstract classes - -As in *Java*, a class and some of its members may be declared *abstract*. An *abstract* member does not have an implementation in its class. Thus, when some descendant inherits an abstract member, it does not count as an implementation: -{jet} -abstract class A { - abstract fun f() -} - -trait B { - open fun f() { print("B") } -} - -class C() : A(), B { - // We are not required to override f() -} -{jet} -Note that we do not need to annotate an *abstract* class *open* -- it goes without saying. Neither need we annotate an *abstract* function *open*. - -One can *override* a non-abstract *open* member with an *abstract* one: -{jet} -open class Base { - open fun f() {} -} - -abstract class Derived : Base { - override abstract fun f() -} -{jet} - -h2. Overridable properties and accessors - -A property may be declared *open* as well as a function. This actually means that _accessors_ of this property can be overridden: -{jet} -open class Base { - open val p : Int - get() = 1 -} -class Derived : Base { - override val p : Int - get() = 2 -} -{jet} - -One can make individual accessors *open* and *override* them one-by-one: -{jet} -open class Base { - var p : Int - get() = 1 - open set(value) { /* do nothing */ } -} -class Derived : Base { - var p : Int - /* get is inherited as it was */ - override set(value) { print(value) } -} -{jet} - -h1. Delegation - -The [Delegation pattern|http://en.wikipedia.org/wiki/Delegation_pattern] has proven to be a good alternative to implementation inheritance, and [Kotlin] supports it natively requiring zero boilerplate code. A class {{Derived}} can inherit from a trait {{Base}} and delegate all of its public methods to a specified object: -{jet} -trait Base { - fun print() -} - -class BaseImpl(val x : Int) : Base { - override fun print() { print(x) } -} - -class Derived(b : Base) : Base by b - -fun main() { - val b = BaseImpl(10) - Derived(b).print() // prints 10 -} -{jet} -The *by*\-clause in the supertype list for {{Derived}} indicates that {{b}} will be stored internally in objects of {{Derived}} and the compiler will generate all the methods of {{Base}} that forward to {{b}}. - -h1. Generic classes - -See [Generics] - -h1. Class objects - -In [Kotlin], unlike *Java*, classes do not have *static* methods. In most cases, [namespace-level functions|Packages] form a good substitute for them, but there are a few cases when they don't. These cases involve access to class' internals (private members). - -For example, to replace a constructor with a [Factory method|http://en.wikipedia.org/wiki/Factory_method_pattern], one makes the constructor *private* and provides a function that calls the constructor. But if this function in located outside the class in question, it would not have any access to the constructor. - -To address this issue (and to provide some other interesting features), [Kotlin] introduces a concept of a *class object* (the closest analog in other languages would be [Companion objects in *Scala*|http://programming-scala.labs.oreilly.com/ch06.html#CompanionObjects]). Roughly speaking, a *class object* for class {{C}} is an object (in the sense of [Object declaration|Object expressions and Declarations]) that is associated to {{C}}. There may be not more than one class object for each class. A *class object* is declared inside its associated class, and thus it can access its *private* members. A *class object* for {{C}} itself is (usually) not and instance of {{C}}. For example: -{jet} -class C() { - class object { - fun create() = C() - } -} - -fun main() { - val c = C.create() // C denotes the class object here -} -{jet} - -At first you may think that this is just a way of grouping static members of a class together instead of mixing them with instance members: in *Java* we access static members of {{C}} by calling {{C.foo()}}, and the same happens with *class object*'s members in [Kotlin]. But in fact there is an important difference: a *class object* can have _supertypes_, and {{C}}, as an expression denotes this object as a value, so one can pass it around, say, as an argument for a function. Let's modify our example to demonstrate this: -{jet} -abstract class Factory { - fun create() : T -} - -open class C() { - class object : Factory { - override fun create() : C = C() - } -} - -fun main() { - val factory = C // C denotes the class object - val c = factory.create() -} -{jet} - -{note:title=Class object bounds are not supported yet}See the corresponding [issue|http://youtrack.jetbrains.com/issue/KT-1437].{note} - -*Note* that class objects are never inherited: -{jet} -class D : C() - -val d = D.create() // Error: no class object for D -{jet} - -A description of some more interesting features related to *class objects* can be found in the [Generic constaints|Generics#Class objects] section. - -*Note*: if you think that *class objects* are a great way of implementing singletons in [Kotlin], please see [Object expressions and Declarations]. - -h1. Best practices related to this feature - -[Effective Java Second Edition by Joshua Bloch|http://java.sun.com/docs/books/effective/] -*Item 16*: Favor composition over inheritance -*Item 17*: Design and document for inheritance or else prohibit it -*Item 18*: Prefer interfaces to abstract classes - -h1. Similar features in other languages - -IDEs automatically [generate delegating methods|http://www.jetbrains.com/idea/features/code_generation.html#link1]. - -[Project Lombok|http://projectlombok.org/features/Delegate.html] implements delegation in *Java* with annotations. - -*Scala* has traits. - -*Groovy* has [Categories and Mixins|http://groovy.codehaus.org/Category+and+Mixin+transformations]. - -h3. What's next - -* [Enum classes] -* [Nested classes] -* [Object expressions and Declarations] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40702623_Coding+Conventions.confluence b/docs/confluence.jetbrains.com/Kotlin/40702623_Coding+Conventions.confluence deleted file mode 100644 index 1a2bf6c129c..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40702623_Coding+Conventions.confluence +++ /dev/null @@ -1,25 +0,0 @@ -h1. Kotlin Coding Style - -This page contains the current coding style for the Kotlin language. - -* if in doubt default to the [Java Coding Conventions|http://www.oracle.com/technetwork/java/codeconv-138413.html] such as: -** use of camelCase for names (and avoid underscore in names) -** types start with upper case -** methods and properties start with lower case -** use 4 space indentation -* public functions should have documentation such that it appears in [Kotlin Doc] -* Kotlin does not have fields as a primary concept in the language - it only has properties. Avoid the use of prefixes on properties, such as _ or m\_ or other kinds of notation; If you need access to a backing field of a property, use the $ prefix: $foo to refer to a field behind property foo; never create a private property and call it \_foo - -h3. Colon - -There is a space before colon where colon separates type and supertype and there's no color where color separates instance and type: - -{code} -trait Foo : Bar { - fun foo(a: Int): String -} -{code} - -h4. See also - -[Kotlin Doc] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40702623_Comparison+to+Java.confluence b/docs/confluence.jetbrains.com/Kotlin/40702623_Comparison+to+Java.confluence deleted file mode 100644 index cfc4f894c64..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40702623_Comparison+to+Java.confluence +++ /dev/null @@ -1,49 +0,0 @@ -This document provides a quick comparison of [Kotlin] to *Java*. - -h3. Fixes - -Safety problems in *Java* that are fixed in [Kotlin]: -* Null references are controlled by the type system, i.e. [Kotlin] has [no {{NPE}}'s|Null-safety] -* Full type information is [retained at runtime|Generics#Reified generics], i.e. better reflection/safer instanceof-checks -* [No raw types|Java interoperability#Java generics in Up] -* Arrays in [Kotlin] are [invariant|Basic types#Arrays] - -Usability problems in *Java* that are fixed in [Kotlin]: -* [Kotlin] has [higher-order functions|Functions#Higher-order functions], aka closures -** And with [inlining|Functions#Inline functions] they are cheap -* [Use-site variance without wildcards|Generics#Type projections] -* [Declaration-site variance|Generics#Declaration-site variance] -* [Kotlin] has [no checked exceptions|Exceptions] - -h3. What Java has and [Kotlin] has not - -* [Checked exceptions|Exceptions] -* [Primitive types|Basic types] that are not objects -* [Static members|Classes and Inheritance#Class objects] -* [Non-private fields|Properties And Fields] -* [Type erasure|Java interoperability#Java generics in Up] -* [Wildcard-types|Generics#Variance] - -h3. What [Kotlin] has and Java has not - -* [Function literals] + [Inline functions|Functions#Inline functions] = performant custom control structures -* [Null-safety] -* [Smart casts|Type casts] -* [String templates|Strings#Templates] -* [Properties|Properties And Fields] -* [Primary constructors|Classes and Inheritance#Primary constructors] -* [Mixins and First-class delegation|Classes and Inheritance#Inheritance] -* [Extension functions] -* [Type inference for variable and property types|Basic syntax walk-through#Define a local variable] -* [Singletons|Object expressions and Declarations] -* [Declaration-site variance & Type projections|Generics#Variance] -* [Modules|Modules and Compilation] -* [Range expressions|Ranges] -* [Pattern matching] -* [Generic types retained at runtime|Generics#Reified generics] -* [Operator overloading] -* [Class objects|Generics#Class objects] - -h3. What's next - -* [Comparison to Scala] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40702623_Comparison+to+Scala.confluence b/docs/confluence.jetbrains.com/Kotlin/40702623_Comparison+to+Scala.confluence deleted file mode 100644 index 207b1c1cc4b..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40702623_Comparison+to+Scala.confluence +++ /dev/null @@ -1,47 +0,0 @@ -Two of the [main design goals|Welcome#Design goals] for [Kotlin] are -* make *compilation* at least as fast as *Java* and, -* keeping the useful level of expressiveness (see above), make it as simple as possible. - -{info:title:Note} -If you are happy with *Scala*, you probably don't need [Kotlin]. -{info} - -h3. What Scala has that [Kotlin] has not - -* Implicit conversions, parameters, etc -** In *Scala*, sometimes it's very hard to tell what's happening in your code without using a debugger, because too many implicits get into the picture -** To enrich your types with functions in [Kotlin] use [Extension functions]. -* Overridable type members -* Path-dependent types -* Existential types -** [Type projections|Generics#Type projections] are a very special case -* Complicated logic for initialization of traits -** See [Classes and Inheritance] -* Custom symbolic operations -** See [Operator overloading] -* Built-in XML -** See [Type-safe Groovy-style builders] - -Things that may be added to [Kotlin] later: -* Higher kinds -* Structural types -* Yield operator -* Actors -* Parallel collections -* .NET target - -h3. What [Kotlin] has that Scala has not -* [Zero-overhead null-safety|Null-safety] -** *Scala* has {{Option}}, which is a syntactic and run-time wrapper -* [Smart casts|Type casts] -* Static [extension functions|Extension functions] -** Instead of wrapping at runtime (with Scala 2.10, implicit value classes will fix the runtime overhead problem) -* [Kotlin]'s [Inline functions|Functions#Inline functions] facilitate [Nonlocal jumps|Returns and jumps#custom] -* [String templates|Strings#Templates]. -** This feature will be supported in Scala 2.10 -* [First-class delegation|Classes and Inheritance#Delegation]. Also implemented via 3rd party plugin: [Autoproxy|https://github.com/kevinwright/Autoproxy-Lite] -* [Modules|Modules and Compilation] - -h3. What's next - -* [Modules and Compilation] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40702623_Docs+Home.confluence b/docs/confluence.jetbrains.com/Kotlin/40702623_Docs+Home.confluence deleted file mode 100644 index a2db65fbd5b..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40702623_Docs+Home.confluence +++ /dev/null @@ -1,86 +0,0 @@ -h1. Welcome to [Kotlin] documentation page\! - -*Disclaimer*: this is not a language specification. Neither is it a complete reference manual. These documents are written to give you an impression of what kind of language [Kotlin] is. Some of the examples are somewhat speculative as the implementation of the compiler and library is currently in progress. Most of the details presented here are subject to change. *Your feedback and suggestions are very welcome.* You can write comments or file an issue in the [issue tracker|http://youtrack.jetbrains.net/issues/KT]. - -h3. Introductory Video - -For an introduction, check out the presentation [*slides* and *video* from StrangeLoop 2011|http://www.infoq.com/presentations/The-Kotlin-Programming-Language]. -More presentations are available on the [Talks and Publications] page. - -h3. What is [Kotlin]? - -"Project [Kotlin]" is the codename for a *statically-typed JVM-targeted programming language* developed by [*JetBrains*|http://jetbrains.com] and intended *for industrial use*. - -h3. Why a new language? - -At [JetBrains|http://jetbrains.com], we’ve been developing for the *Java* platform for a long time, and we know how good it is. On the other hand, we know that the *Java* programming language has certain limitations and problems that are either impossible or very hard to fix due to backward-compatibility issues. We know that *Java* is going to stand long, but we believe that the community can benefit from a new statically typed JVM-targeted language free of the legacy trouble and having the features so desperately wanted by the developers. - -{anchor:Design goals} -The main *design goals* behind this project are -* to create a [*Java-compatible* language|Java interoperability], -* that *compiles* at least *as fast as Java*, -* make it *safer* than Java, i.e. statically check for common pitfalls such as [null pointer dereference|Null-safety], -* make it *more concise* than *Java* by supporting [variable type inference|Basic syntax walk-through#Define a local variable], [higher-order functions|Functions#Higher-order functions] (closures), [extension functions|Extension functions], [code in interfaces and first-class delegation|Classes and Inheritance], etc; -* and, keeping the useful level of expressiveness (see above), make it as *simple* as possible. - -See more [here|http://blog.jetbrains.com/kotlin/2011/08/02/why-jetbrains-needs-kotlin/]. - -h3. What does it look like? - -{jet} -fun main(args : Array) { - println("Hello, world!") -} -{jet} -See more [here|Hello, world!] and below. - -h3. Development status - -The compiler is being developed alongside with an [IntelliJ IDEA|http://www.jetbrains.com/idea/] integration. -[Kotlin] is an [Open Source project|http://github.com/jetbrains/kotlin]. Distributed under Apache 2 License. - -{note:title=Kotlin is Under Development}Please report bugs to our [Issue Tracker|http://youtrack.jetbrains.com/issues/KT]{note} - -If you're interested in keeping track of the project status, you're welcome to subscribe to the [Kotlin blog|http://blog.jetbrains.com/kotlin] or to [follow us on Twitter|http://twitter.com/project_kotlin]. - -h3. Read more - -*FAQ*. See [this page|FAQ] for the answers to the most common questions. - -API Documentation for the *Standard Library* can be found [here|http://jetbrains.github.com/kotlin/apidoc/stdlib/]. -API Documentation for the *Runtime* can be found [here|http://jetbrains.github.com/kotlin/versions/snapshot/apidocs/]. - -Check out some *[Examples]* to get an idea of what [Kotlin] is: -* [Hello, world!] -* [Basic syntax walk-through|Basic syntax walk-through] -* [Address book] --- collections and higher-order functions -* [HTML builder|Type-safe Groovy-style builders] --- declarative structures -* [More...|Examples] --- extensions, pattern matching, IO, operator overloading, etc. - -If you are a *Java* developer, look here: -* [Comparison to Java], and -* [Java interoperability] - -If you got interested, take the *Feature tour*: -* [Modules and Compilation] -* [Packages] -* [Functions] -** [Operator overloading] -** [Extension functions] -** [Function literals] -** [Type-safe Groovy-style builders|Type-safe Groovy-style builders] -* [Properties And Fields] -* [Basic types] -** [Strings] -* [Expressions] -{children:page=Expressions|depth=5} -* [Pattern matching] -* [Classes and Inheritance] -{children:page=Classes and inheritance|depth=5} -* [Generics] -** [Runtime Type Information] -* [Null-safety|Null-safety] -* [Exceptions] -* [Java interoperability] - -Check out the *[Grammar]* for a formal syntax description. \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40702623_Examples.confluence b/docs/confluence.jetbrains.com/Kotlin/40702623_Examples.confluence deleted file mode 100644 index afbfe5de9a0..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40702623_Examples.confluence +++ /dev/null @@ -1 +0,0 @@ -{children} \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40702623_Exceptions.confluence b/docs/confluence.jetbrains.com/Kotlin/40702623_Exceptions.confluence deleted file mode 100644 index 9beac310ba5..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40702623_Exceptions.confluence +++ /dev/null @@ -1,71 +0,0 @@ -Exceptions in [Kotlin] are not very different from any other language. the main difference from *Java* is that there're no checked exceptions in [Kotlin], you can find out the motivation for this [below|#why]. - -h3. Exception classes - -All exception classes in [Kotlin] are descendants of the class {{Exception}}. Every exception has a message, stack trace and an optional cause. - -To *throw* an exception object, one uses the *throw* expression: -{jet} -throw MyException("Hi there!") -{jet} - -To catch an exception, one uses the *try* expression: -{jet} -try { - // some code -} -catch (e : SomeException) { - // handler -} -finally { - // optional finally block -} -{jet} -As usual, there may be zero or more *catch* blocks, and *finally* may be omitted, but at least one *catch* or *finally* must be present. - -Note that *try* is an _expression_, i.e. it may have a value: -{jet} -val a : Int? = try { parseInt(input) } catch (e : NumberFormatException) { null } -{jet} -The "returned" value of *try* expression with no *finally* is either the last expression in the *try* block or the last expression in the *catch* block (or blocks). - -If *finally* block is present, its last expression is the value of *try* expression. - -{anchor:why} -h3. Why [Kotlin] has no checked exceptions - -People with *Java* background may wonder why [Kotlin] does not have checked exceptions. There's so much said on this topic, that we just provide a few citations and one example here. - -Our example is {{java.lang.Appendable}} -- an interface from {{JDK}}, implemented by {{StringBuilder}}, that has, among others, the following method declaration: -{jet} -Appendable append(CharSequence csq) throws IOException; -{jet} -What does this signature say? It says that _every time_ I append a string to something (a {{StringBuilder}}, some kind of a log, a console, etc) I _have to_ catch those {{IOExceptions}}. Why? Because it _might be_ performing IO ({{Writer}} also implements {{Appendable}})... So it results into this kind of code all over the place: -{jet} -try { - log.append(message); -} -catch (IOException e) { - // Must be safe -} -{jet} -And this is no good, see [Effective Java|http://java.sun.com/docs/books/effective] Item 65: *Don't ignore exceptions*. - -h4. Some citations from prior art: - -Bruce Eckel says in [Does Java need Checked Exceptions? |http://www.mindview.net/Etc/Discussions/CheckedExceptions]: -{quote} -Examination of small programs leads to the conclusion that requiring exception specifications could both enhance developer productivity and enhance code quality, but experience with large software projects suggests a different result -- decreased productivity and little or no increase in code quality. -{quote} - -Other citations of this sort: -# [Java's checked exceptions were a mistake|http://radio-weblogs.com/0122027/stories/2003/04/01/JavasCheckedExceptionsWereAMistake.html] (Rod Waldhoff) -# [The Trouble with Checked Exceptions|http://www.artima.com/intv/handcuffs.html] (Anders Hejlsberg] - -h3. Java interoperability - -Some details on *Java* interoperability are available [here|Java interoperability#Checked exceptions]. - -h3. What's next - -* [Java interoperability] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40702623_Expressions.confluence b/docs/confluence.jetbrains.com/Kotlin/40702623_Expressions.confluence deleted file mode 100644 index 5cec3b14bf4..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40702623_Expressions.confluence +++ /dev/null @@ -1,35 +0,0 @@ -This is a quick overview of expressions in [Kotlin]. - -h3. Atomic expressions - -Atomic expressions are -* Literal constants (see [Basic types], [Strings]) -* [Tuple literals|Tuples] -* [Variable names or field references|Properties And Fields] -* [Object expressions|Object expressions and Declarations] -* Parenthesized expression -* [Control structures (if, when, try)|Control structures] -* [Function literals] -* [*this* expressions|This expressions] -* [*break*, *continue* or *return*|Returns and jumps] -** note that these are _expressions_ that are typed with the type [{{Nothing}}|Returns and jumps#Nothing] - -See the [grammar for atomic expressions|Grammar#atmoicExpression]. - -h3. Operators - -The [grammar|Grammar#Expressions] defines a number of operators denoted by symbols. The precedence table is available [here|Grammar#Precedence]. Many of the operators can be [overloaded|Operator overloading], other are described below: -* {{.}} -- for member access -* {{?.}} and {{?:}} -- for [Null-safety] -* {{&&}} and {{||}} -- for incomplete boolean evaluation - -h3. What's next - -* [Basic operations] -* [Control structures] -* [Function literals] -* [Returns and jumps] -* [Ranges] -* [This expressions] -* [Tuples] -* [Type casts] diff --git a/docs/confluence.jetbrains.com/Kotlin/40702623_FAQ.confluence b/docs/confluence.jetbrains.com/Kotlin/40702623_FAQ.confluence deleted file mode 100644 index 0d1375f0199..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40702623_FAQ.confluence +++ /dev/null @@ -1,75 +0,0 @@ -h3. What is [Kotlin]? - -"Project [Kotlin]" is the codename of a statically-typed JVM-targeted programming language developed by [JetBrains|http://jetbrains.com] intended for industrial use. - -h4. Why a new language? -At [JetBrains|http://jetbrains.com], we’ve been developing for the *Java* platform for a long time, and we know how good it is. On the other hand, we know that the *Java* programming language has certain limitations and problems that are either impossible or very hard to fix due to backward-compatibility issues. We know that *Java* is going to stand long, but we believe that the community can benefit from a new statically typed JVM-targeted language free of the legacy trouble and having the features so desperately wanted by the developers. - -{anchor:Design goals} -The main design goals behind this project are -* to create a *Java-compatible* language, -* that *compiles* at least *as fast as Java*, -* make it *safer* than Java, i.e. statically check for common pitfalls such as [null pointer dereference|Null-safety], -* make it *more concise* than *Java* by supporting [variable type inference|Basic syntax walk-through#Define a local variable], [higher-order functions|Functions#Higher-order functions] (closures), [extension functions|Extension functions], [mixins and first-class delegation|Classes and Inheritance], etc; -* and, keeping the useful level of expressiveness (see above), make it way *simpler* than the most mature competitor -- *Scala*. - -See [Comparison to Java] and [Comparison to Scala]. - -h4. Is this an open source project? What's the license? - -Both the compiler and the IntelliJ IDEA plugin are open source under the Apache 2 license. We're happy to accept [contributions|Kontributions]. - -h4. Is it Java-compatible? - -Yes. The compiler emits *Java* byte-code. [Kotlin] can call *Java*, and *Java* can call [Kotlin]. See [Java interoperability]. - -h4. Other platforms than Java? - -We have started a JavaScript back-end recently. There are external Kontributors willing to work on an LLVM back-end. - -{anchor:Eclipse} -h4. Eclipse-based IDE? - -We plan to provide two things: -1) An open source Eclipse plugin that will be initially contributed by JetBrains, and later we will gradually move it's support onto the community. -2) API exposed by the compiler, to make it easy to retrieve semantic information from within the plugin. - -In any case, Eclipse support will be released later that IntelliJ support. - -h4. Is this a functional language? Is this an object-oriented language? - -This is an object-oriented language. It supports [higher-order functions|Functions#Higher-order functions] and [function literals|Function literals], but that does not make it a functional language. It targets OO-developers. - -h4. What about generics? -[Kotlin] has [generics|Generics]. They are [retained at runtime|Generics#Reified generics], support [declaration-site variance|Generics#Declarations-site variance] and [usage-site variance|Generics#Type projections], and [Kotlin] does not have any wildcard types. - -h4. Does it have type inference? Is it a good idea? -[Kotlin] infers type arguments when generic functions are called, as well as types of variables from their initializers. This makes the code more concise. - -h4. Does it have semicolons, curly braces, etc? - -Semicolons are [optional|Grammar#Semicolons]. Curly braces are there. Types of [variables|Basic syntax walk-through] and [functions|Functions] are written on the right after a colon (like *Scala*, and unlike *C*-style languages). - -h4. Why types on the right? - -We believe that it makes the code more readable. Besides, it enables some nice syntactic features, for example, it's easy to leave type annotations out, and *Scala* has proven pretty well that this is not really a problem. - -h4. Is this language extensible? - -We are planning to make it extensible in a few ways: from [inline functions|Functions#Inline functions] to annotations, type loaders and language-quotations. - -h4. Can I embed my DSL into this language? - -Yes, [Kotlin] provides a few features that help here: [Operator overloading], [Custom control structures via inline functions|Functions#Inline functions], [Infix function calls|Functions#infix function calls], [Extension functions], annotations, language-quotations. - -h4. Does it have IDE support? - -Yes. The compiler is developed as an [IntelliJ IDEA|http://jetbrains.com/idea] plugin, and user-facing IDE features are there from the very beginning (we make good use of them while debugging and testing). - -h4. Where to ask more questions? - -Join our [*Forum*|http://devnet.jetbrains.net/community/kotlin]. - -h3. What to read next - -* [Hello, world!] \ No newline at end of file diff --git a/docs/confluence.jetbrains.com/Kotlin/40702623_Functions.confluence b/docs/confluence.jetbrains.com/Kotlin/40702623_Functions.confluence deleted file mode 100644 index 30e4b1d7737..00000000000 --- a/docs/confluence.jetbrains.com/Kotlin/40702623_Functions.confluence +++ /dev/null @@ -1,350 +0,0 @@ -Functions in [Kotlin] are declared with the *fun* keyword: -{jet} -fun double(x : Int) : Int { - return x * 2 -} -{jet} - -A function call goes in the traditional way: -{jet} -val two = demo(1) -{jet} - -See also [Infix calls|#Infix calls] and [Operator overloading]. - -h3. 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: -{jet} -fun double(x : Int) : Int = x * 2 -{jet} - -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: -{jet} -fun double(x : Int) = x * 2 -{jet} - -{anchor:Unit} - -h3. {{Unit}}\-returning functions - -If a function does not return any useful value, its return type is {{Unit}}. {{Unit}} is a type of [tuples|Tuples] of zero components, its an alias for {{Tuple0}}. It has only one value -- a tuple of zero components, that is written {{()}}. This value does not have to be returned explicitly: -{jet} -fun printHello(name : String?) : Unit { - if (name != null) - print("Hello, $name!") - else - print("Hi there!") - // We don't need to write 'return ()' or 'return', although we could -} -{jet} - -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: -{jet} -fun printHello(name : String?) { -//... -} -{jet} - -h3. Local functions - -[Kotlin] supports _local functions_, i.e. one can define a function inside a function: -{jet} -fun dfs(graph : Graph){ - fun dfs(current : Vertex, visited : Set) { - if (!visited.add(current)) return - for (v in current.neighbors) - dfs(v, visited) - } - - dfs(graph.vertices[0], HashSet()) -} -{jet} - -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: -{jet} -fun dfs(graph : Graph){ - val visited = HashSet() - fun dfs(current : Vertex) { - if (!visited.add(current)) return - for (v in current.neighbors) - dfs(v) - } - - dfs(graph.vertices[0]) -} -{jet} - -Local functions can even *return* from outer functions using [qualified *return* expressions|Returns and jumps]: -{jet} -fun reachable(from : Vertex, to : Vertex) : Boolean { - val visited = HashSet() - 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 -} -{jet} - -h3. Member functions - -A _member function_ is a function defined inside a class: -{jet} -class Sample() { - fun foo() { print("foo") } -} -{jet} - -Member functions are called with a dot: -{jet} -Sample().foo() // creates a new object of Sample and calls foo() on it -{jet} -See [Classes and Inheritance]. - -h3. Generic functions - -Functions may have generic parameters which can be specified in angle brackets after the function name and before the value parameters: -{jet} -fun singletonArray(item : T) : Array { - val result = Array(1) - result[0] = item - return result -} -{jet} -More on generic functions can be found on the page dedicated to [generics|Generics#Generic functions]. - -h3. Varargs - -The last argument of a function may be marked with *vararg* annotation: -{jet} -fun asList(