What's new in Kotlin 1.5.30

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Hello! My name is Anton Arhipov and in this  video, I will highlight the new features in Kotlin   1.5.30. First of all, I start with the disclaimer.  Pretty much everything I'm talking about in this   video is experimental. You either need to  enable the features using a compiler option   or you need to opt-in for the usage of the  experimental API. Either way the features are   in the preview state and are expected to stabilize  by Kotlin 1.6. I know you are watching this video   because you like Kotlin very much. But I also know  that every second person who watches this is not   subscribed to our awesome YouTube channel. So hit  that subscribe button! It's a great indication   for us that we are doing a good job. There are  a few changes to the language. Specifically.   there are changes in how opt-in requirements work.  There are updates in the area of type inference;   we are adding the exhaustive behavior to the  when statement, and there is now a possibility   to use the suspend functions as supertype. For  the JVM target now it is possible to instantiate   annotation classes, and there are improvements  in handling the nullability annotations.   We also added a number of experimental functions  in the standard library. Specifically, there are   updates to the experimental Duration API, and the  new functions were added to the Regex API as well.   There are a few interesting updates in  Kotlin/Native. We added support for Apple   silicon, and now we are working on improving  the interoperability with Swift and Objective-C.   Kotlin/JS IR backend is promoted to Beta, and  it leads to the related tooling improvements. Let's talk about language-related changes.  But before we look into what's new, I think   it's important to recall what is it about.  Opt-in requirements is a tool for acquiring   and giving an explicit consent for using certain  elements of API. The library author can mark an   experimental API as requiring opt-in to inform the  users about the experimental state. The compiler   then raises a warning or an error on the API usage  and requires an explicit consent to suppress it.   In this example, you can see that the DateProvider  class is marked with MyDateTime annotation that is   actually a requirement annotation. The compiler  will raise a compilation error in this case.   I have to explicitly consent to the  use of DateProvider class by using an   OptIn annotation where I say that I'm  OK with using the experimental class   that is marked with MyDateTime annotation. I  could also use MyDateTime annotation directly   to mark the function instead of using the  OptIn annotation. However, it means that   I'm declaring my function as experimental and I  would have to opt-in for the use of this function   in some other location in my code. We may say  that MyDateTime annotation is a requirement,   and OptIn annotation is a consent to a specific  requirement. So if we consent to the usage of this   class that is marked as requiring opt-in, we don't  really propagate the requirements further. But   there are still situations where we may still use  this experimental class implicitly. For instance,   when you are using a function that either  accepts the experimental class as an argument or   specifies it as a return type. The compiler wasn't  detecting the implicit usage of experimental API   and didn't raise the warning. Starting from  1.5.30, the compiler detects such situations and   requires opt-in even for the implicit usages of  the experimental API. In this example, we can see   that the return type is marked as an experimental  API element hence the usage of the function   requires you to opt-in even if the declaration  is not marked as requiring an opt-in explicitly. As part of the stabilization  story for opt-in requirements,   Kotlin 1.5.30 presents the new rules for using  and declaring opt-in requirements annotations on   different targets. We are now limiting the number  of cases where these requirement annotations could   be used. So you wouldn't apply it in places where  these are not meant to be used. For instance,   marking local variables with opt-in requirement  annotations is now forbidden at the use site.   Also, marking an override is allowed only if  the corresponding declaration in the super type   is also marked with the requirement annotation.  Of course, you can find the full list of   the restrictions for the usages of opt-in  requirement annotations in the documentation. Let's now talk about type inference. Oh, this  one is interesting! In Kotlin or in Java you   can define a recursive generic type which  references itself in its type parameters.   Since Kotlin 1.5.30 the compiler can infer a  type argument based only on the upper bounds   of the corresponding type parameter if it's  a recursive generic. This enables various   patterns with recursive generic types that  are often used in Java to make a builder API.   Let's take a look at the example. I'm using  TestContainers Java library and they use   recursive generics quite extensively.  Previously, to use this library,   I had to use Nothing as a type parameter for  instantiating the types provided by the library.   This is because generic type information could  not be inferred. And there is no better option   this time than specifying Nothing as a parameter.  And then I had to use the apply function from   Kotlin standard library to call the sequence of  builder functions for that type. In Kotlin 1.5.30   we can now skip specifying the type parameter.  The compiler is able to infer the types for us   and we can use the builder API as designed by the  library authors. This is a great improvement for   Kotlin's interoperability with Java! However,  you remember that everything I talk about   in this video is experimental, right? So  this feature is not enabled by default yet,   and you can switch it on by passing the  -Xself-upper-bound-inference compiler option. Next on the list is builder inference. This is  a special kind of type inference which allows   to infer type arguments of a call based on the  type information from other calls inside its   lambda argument. This can be useful when  calling generic builder functions like   buildList() or sequence(). However, inside such  lambda argument there is currently a limitation   on using the type information that builder  inference tries to infer. You can only specify it   but you cannot "get" it. For example, you  cannot call get() function inside the lambda   argument of a buildList() function without  explicitly specifying the type arguments.   Now we remove these limitations with the  -Xunrestricted-builder-inference compiler option.   It is possible to skip specifying  the type parameter for the builder   and the compiler is able to infer the  type information for us. In our example,   it is now possible to call get() function inside  the parameter block for the buildList function. The 'when' statements for sealed classes and  boolean types are going to be exhaustive by   default. 'when' expression is a very useful  feature in Kotlin because it's exhaustive by   default when used with sealed classes, enums, and  boolean types. The exhaustive 'when' expression   contains branches for all the types of a subject  or some of the types plus an 'else' branch. If   not all the options are covered the result is a  compilation error. However, it is possible to use   when as a statement as opposed to expression.  In this case, we don't return any value and the   same situation results just in a weak warning  displayed in the IDE. The 'when' statement   is not exhaustive by default. Starting from Kotlin  1.5.30, if the 'when' statement is not exhaustive,   the compiler will warn you about it. There are  even plans to make it a compiler error in the   future versions of Kotlin. To see this behavior  you need to set the language version to 1.6 In Kotlin, it is possible to use functional  type as a super type. It is sometimes useful   when you are required to use a function but  you need to customize it somehow. For instance,   you need to pass an extra parameter. But the same  didn't work if the functional type was marked with   suspend keyword. This is a little bit unfortunate  because there are situations where you would want   to derive from such type. In 1.5.30, it is  now possible to use suspend functional type   as a super type, and of course, you have to  enable this feature via the compiler option. Now let's take a look at the  updates for the Kotlin/JVM target.   Null-safety is one of those Kotlin features that  people like the most. The Kotlin compiler can read   various types of nullability annotations  to get nullability information from Java.   This information allows it to report nullability  mismatches in Kotlin when calling Java code.   Since 1.5.30 you can specify whether the  compiler reports a nullability mismatch   based on the information from the specific type of  nullability annotations. To make it work, use the   compiler option, -Xnullability-annotations, where  you specify the package name and reporting level.   You can find a full list of packages in our  documentation for nullability annotations.   And the report level is one of the following:  'ignore' to ignore nullability mismatches,   'warn' to report warnings, 'strict' to  report errors. And here is an example of   how you can enable error reporting for newly  supported RxJava 3 nullability annotations. In Java, annotations are presented  as interfaces, and therefore it is   possible to implement those interfaces. We  can see that if we decompile the class file   of a Java annotation. Various Java frameworks  and libraries make use of this and require   an instance of annotation interface for  operations. For instance, a framework may   use annotations to create in-memory configuration  for the application. Interoperability with Java   frameworks and libraries is a priority for  us. With Kotlin 1.5.30, you can now call   constructors of annotation classes in  arbitrary code to obtain the resulting   instance. The feature covers the same use cases  as implementing the annotation interface in   Java. To enable this feature you need to set the  language version to 1.6 as a compiler parameter. Kotlin 1.5.30 is introducing the native  support for Apple silicon. Previously,   the Kotlin/Native compiler and tooling required  the Rosetta translation environment for working   with Apple silicon hosts. Since 1.5.30, it is  not needed anymore. We are also introducing the   new targets that make Kotlin code run on Apple  silicon natively. These are available on both   Intel-based and Apple silicon hosts.  Note that in 1.5.30 we provide only   basic support for Apple silicon targets in  the Kotlin multi-platform Gradle plugin. We have added the support for Kotlin's suspending  functions from Objective-C and Swift in Kotlin   1.4. Now we are improving it to keep up with the  new feature in Swift 5.5 - the concurrency with   async and await modifiers. The Kotlin/Native  compiler now emits the _Nullable_result   attribute in the generated Objective-C headers for  suspending functions with nullable return types.   This makes them available for calling from Swift  as async functions with the proper nullability.   Please note that this feature is  experimental and can be affected   in the future by changes in both Kotlin and  Swift. For now, we are offering a preview   that has certain limitations and we  are eager to hear how it works for you. Now it is possible to refer at the objects  and companion objects in a more authentic   way for native iOS developers. For example,  if you have in Kotlin the following objects,   to access the object in Swift you can  use 'shared' or 'companion' properties. And finally, IR based compiler back-end  for Kotlin/JS has reached Beta!   Previously, we published the  migration guide for the JS IR backend   to help migrate your projects to the new backend.  Now we also present the Kotlin/JS inspection   pack IDE plugin that shows the  required changes directly in the IDE The Kotlin/JS inspection pack plugin is available  in the plugins marketplace and is just one click   to install! This plugin adds useful inspections,  intentions, quick fixes for working with   Kotlin/JS. It also provides helpful functionality  when you are building new applications using   Kotlin/JS and it helps you to migrate existing  applications to the new Kotlin/JS IR compiler Kotlin 1.5.30 brings JavaScript source  maps generation for Kotlin/JS improving the   debugging experience. This enables debugging  support including breakpoints, stepping,   and even readable stack traces  with proper source references Now let's see what's new in the standard  library. Before this release, Duration.toString()   function was supposed to return a string  representation of its argument duration value   expressed in the unit that yields the  most compact and readable number value. Oh well, the intention was a good one but you  can obviously see that it didn't really work   out. So now we fixed it! Now it returns a string  representation of its duration value expressed   as a combination of numeric components, each  of its own unit. Each component is a number   followed by the unit abbreviation name. A  negative duration is prefixed with minus sign   and if it consists of multiple components  it is surrounded with parenthesis.   If you want to express duration as a single unit  you can use the overloaded version of toString   function which allows specifying the duration  unit and the number of decimals after the dot. We added the new Duration.toIsoString()  function that we recommend using in cases   of serialization or when you need  to interchange the data somehow.   This function uses a more strict ISO-8601  format instead of duration to string. We also added the new functions for parsing  the duration from a string representation.   You can see the examples of parse() and  parseOrNull() usages. As you can see,   the parse() function is a universal one.  It accepts the duration in any format   if the duration is formatted incorrectly then  parse() function fails and throws an exception.   Alternatively, you can use parseOrNull()  function that returns null in case of   incorrectly formatted input. Besides  parse() and parseOrNull() functions,   we also added the functions for working  with ISO-formatted durations. In this case,   the functions assume that the input is correctly  formatted according to ISO specification. There are new experimental functions  in the Regex standard library class,   matchAt() and matchesAt(). These functions  provide a way to check if a regular expression   has an exact match at a particular position in  a string or a ChartSequence. Here is an example   usage of both functions. The functions  try matching a given pattern at a specific   position in a string. The difference is that  matchesAt() function returns a boolean result,   and matchAt() function returns a substring that it  matches or a null value if it can't find the match The new function splitToSequence()  is a lazy counterpart of split()   function. It splits the string around  matches of the given regular expression   but returns the result as a sequence. So that all  the operations to the result are executed lazily.   So this is the list of new things in  Kotlin 1.5.30. As I mentioned earlier,   pretty much everything in this list is still  experimental and we are eager to collect your   feedback. So give this new version a try and let  us know what works for you, what doesn't work,   what you like, what you don't like. Thanks  for your time and have a nice Kotlin!
Info
Channel: Kotlin by JetBrains
Views: 9,582
Rating: 4.9481864 out of 5
Keywords: Kotlin, Kotlin Release, Kotlin 1.5.30, JS IR backend, Kotlin/JVM, Kotlin/Native, Kotlin/JS, Regex, Apple silicon support, annotation classes, nullability annotations, JavaScript IR compiler, Kotlin/JS inspection pack, Swift/Objective-C mapping, Swift Interop, Kotlin DSL
Id: rNbb3A9IdOo
Channel Id: undefined
Length: 18min 24sec (1104 seconds)
Published: Wed Aug 25 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.