What’s new in Standard Library M13 and M14


Standard Library continues its evolution:

  • Lazy<T> type has been introduced
  • More concise syntax for storing properties in a Map
  • Final changes in the Char arithmetics
  • Plus and minus operations on a collection now depend on its type
  • New scope functions: apply and run
  • Right-open ranges
  • Trimming indents in multiline strings literals
  • and more

What’s new in M13

Lazy

Lazy evaluation is a useful pattern and it was unfair to limit it only to delegated properties. Now there is Lazy<T> type right in the kotlin package and you can use it in many contexts. You can delegate properties to instances of Lazy, which has the get extension function to satisfy the delegation convention:

Unlike Delegates.lazy, an semantics of lazy is synchronized by default.

Delegating properties to a map

Another common use case is storing values of properties in a map, where names of properties serve as keys. For this case we provide extension functions get and set on maps to satisfy the delegation convention, allowing to delegate property right to the map, without creating wrapper delegate objects:

Observable and vetoable properties

We have fixed a nuisance with observable delegates: the callback handler passed to observable property was called before the property value was changed. Now it is invoked after. It’s worth noting that callbacks are now inlined into these delegates, thus usages of observable and vetoable delegates now cost one object allocation less.

Read more about standard delegates in the reference.

Completing the change of Char arithmetic

In M13 we’re finalizing the semantic changes of arithmetic operations on the Char type. Only three arithmetic operations on Char are left:

  • Char - Int → Char
  • Char + Int → Char
  • Char - Char → Int

All other binary operations involving Char were deprecated in M12 and now are dropped.

Plus and minus operators for collections

plus operation on collections is not new, but it was defined so that its return type and behavior were not intuitive: for example, when adding an element to a set, you would receive a list having that element concatenated to all elements of the set, possibly resulting in that element to be duplicated.
Now return type of plus operation depends on the type of first operand:

  • for Iterable, Collection and List the result is List, and operation is a concatenation
  • for Array the result is Array, and operation is concatenation
  • for Set the result is Set, and operation is inclusion of element(s) into the resulting set
  • for Map the result is Map, and operation is inclusion of key-value pair(s) into the resulting map
  • for Sequence the result is Sequence, and operation is lazy concatenation

Also we have introduced minus operation. It has the same relation between type of its first operand and its return type, and the following semantics:

  • Collection - single_element returns the collection with the single occurrence of that element removed
  • Collection - collection_of_elements returns the collection without all the elements contained in another collection.

New scope functions: apply and run

Prior to M13 there were two so-called scope functions in the Standard Library: let and with. We call them scope functions, because their only purpose is to modify scope of a function passed as the last parameter. For example, to bring the parameter of scope function to the receiver of function parameter in case of with, and vice versa in case of let.
Now you have two more scope functions at your disposal:

  • one that passes its receiver to the receiver of its function parameter:
    T.run(f: T.() → R): R
    We call it run, because it’s a generalization of run without receiver.
  • one that applies given Unit-returning function to the receiver and returns the receiver itself:
    T.apply(f: T.() → Unit): T

Constructing open ranges

There was a common request to introduce right-open ranges in Kotlin. We have examined use-cases and found that most of them are involving integer ranges. In case of integers an opened at the end range can be represented with a closed range, whose end value is one less than the corresponding open range’s end.
To create such ranges you can use newly introduced until function. It returns closed range with values up to the specified end but not including it, so that:

0 until 20 == 0..19

find vs firstOrNull

There were many debates about naming a function that finds the first element matching given predicate in a collection. find is easy to explore, but firstOrNull is consistent with how this operation is called in LINQ and Reactive Extensions. Prior to M13 find was deprecated in favor of firstOrNull, but now we’ve decided to “undeprecate” it and leave as a synonym for firstOrNull. Also we’ve provided findLast, which is a synonym for lastOrNull.

Removing indentation from multiline string literals

A well-known pain with multiline string literals was the formatting: you couldn’t format a code containing these literals well without introducing whitespace into the literal itself.

Now we provide several functions to strip common whitespace prefix from each line of a string:
trimIndent, trimMargin, replaceIndent, replaceIndentByMargin

Dropping deprecated API

In M13 we have dropped some of previously deprecated APIs: streams, extension methods for iterators, FunctionalList, FunctionalQueue and StringTemplate.

The full list of changes is available here.

Plans for M14

Distributing top-level functions between package parts

As we have announced earlier we’re changing the way how top-level functions and properties are mapped to class files in compiled code. In the next milestone all the top-level stuff in Standard Library is going to be distributed between corresponding package parts. We’ll keep the KotlinPackage facade class that contains all top-level functions, but it will be deprecated and removed in the future.

Note that these changes only affect usages of top-level Kotlin members from Java code. An inspection in the IDE will be provided to migrate these usages.

What’s going to be dropped next

We’re still in the process of cleaning up deprecated APIs from the Standard Library and here is the list of what we are going to drop in the next milestone:

  • size, empty and notEmpty extension properties;
  • extensions makeString and appendString;
  • methods to construct arrays and collections from provided elements: array, intArray, arrayList, hashMap, etc.

kotlin-swing and kotlin-jdbc status

There were two experimental libraries: kotlin-swing and kotlin-jdbc. We’re not going to ship them anymore to the Maven Central repository. Last versions published to Maven would be compiled against M14.

If you depend on these libraries feel free to fork their source code and compile them locally. We have extracted them from the Kotlin codebase into separate repositories on GitHub under kotlin-projects organization:

This entry was posted in Libraries. Bookmark the permalink.

18 Responses to What’s new in Standard Library M13 and M14

  1. Zdenek says:

    Changes looks nice, but when do you plan to release 1.0? Do you think you will make it this year or it will be postponed to the 2016?

    • Roman Belov says:

      It’s hard to give the estimates, but we are working hard to release 1.0 as soon as possible.

      • Zdenek says:

        I know, but very roughly… do you think it is real release this year or somewhere 2016 is closer to the reality?

        • Jayson Minard says:

          I think the language is ready for 1.0, recent blog posts indicating that last changes needed to be done soon before 1.0, and behaviour of releases indicates that it is imminent. I’m hoping for 1.0 this year.

  2. Zlonax Bubuka says:

    Do you consider Kotlin->Java translator? For example, GWT would benefit from it.

  3. Thank you so much for your work! You make life of many developers much easier!

  4. MuppetGate says:

    I’m not sure that until keyword is particularly intuitive. If I see 0 until 20 then I expect the value to run from 0 to 20.

    • Christian Brüggemann says:

      I really wonder why IntRanges aren’t open ended by default anyway. That would follow the standard Java semantics, see String.substring(x, y) for example.

    • Peter Niederwieser says:

      For what it’s worth, Scala also uses until for exclusive upper bound.

  5. Neil says:

    If a plus operation on an Iterable returns a List, does that mean the iterator was iterated all the way through to construct the List?

    Why not cons up a new Iterable that first delegates to the old iterator then when old one has finished returns the new item?

    That way no copy is made, and the original Iterable is evaluated lazily (as you seem to be saying for Sequence).

    • ilya.gorbunov says:

      We had thought about this operation and decided to give it eager behavior as most of operations on iterables in standard library have.
      For lazy evaluation we provide sequences. You can convert an Iterable to Sequence with asSequence extension function.

  6. chushuhuch says:

    Open ranges improve iterating experience. But I can’t find any discussions (and maybe it’s already too late) about why C-style loops are not supported. Do you suppose most of the cases are covered with ranges?

    • Yes, we do. Our experience shows that C-style for loops are not really needed (in the very rare cases where for doesn’t work, while is enough)

      • chushuhuch says:

        OK. Personally I do rather often write loops with incremented counter which have dynamic break condition. And also simultaneous iteration (both parallel and from two ends) seems to occur relatively often. Maybe there are some tricks which I don’t realize?

        • Well, I think there should be ways of expressing that through ranges etc, but we’d need to look into particular use cases to find exact solutions. In any case, such use cases do not seem to be very typical in most projects.

Comments are closed.