Skip to end of metadata
Go to start of metadata

Two of the main 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.
If you are happy with Scala, you probably don't need Kotlin.

What Scala has that Kotlin has not

Things that may be added to Kotlin later:

  • Higher kinds
  • Structural types
  • Yield operator
  • Actors
  • Parallel collections
  • .NET target

What Kotlin has that Scala has not

What's next

Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Jul 20, 2011

    Anonymous

    I think you forgot to mention actors and paralell collections from Scala

    1. Jul 20, 2011

      Anonymous

      And a .NET backend.

    2. Jul 20, 2011

      Good point. Fixed

      1. Jul 23, 2011

        Anonymous

        and delimited continuations

        1. Jul 27, 2011

          We're not going to blame Scala for all compiler plug-ins available for it

  2. Jul 20, 2011

    Anonymous

    Scala doesn't wrap at runtime, it does an implicit conversion at compile time. Also, I don't think Option is a run-time wrapper..

    1. Jul 20, 2011

      implicit def stringWrapper(x: String) = new runtime.RichString(x)

      How's this not wrapping at runtime?

      1. Jul 21, 2011

        Anonymous

        implicit conversions are resolved at compile time, and conversion calls inserted by the compiler. this is static.

        no runtime involved.

        1. Jul 21, 2011

          Is there a new instance of RichString created at runtime?

  3. Jul 20, 2011

    Anonymous

    What about adding 'Comparison to Groovy+' page - I think that this is your direct competitor, not Scala. Please note that I mean Groovy+, not Groovy.

    1. Jul 20, 2011

      Thanks for the suggestion, Groovy++ is interesting, indeed.

      1. Jul 24, 2011

        Feel free to contact me if you need any help with comparison or Groovy++ in general

  4. Jul 20, 2011

    Anonymous

    Aren't automatic casts exactly what implicit conversions are for?

    Also, Scala has inline support, there's even a special annotation to make sure the compiler tries it's best to inline: http://www.scala-lang.org/api/current/scala/inline.html

    So please correct your comparison and also take the other comments here into account.

    1. Jul 20, 2011

      A cast and a run-time wrapper are pretty different, I believe.

      As for inlines, you are right, thanks.

      1. Jul 20, 2011

        Anonymous

        It looks like your automatic cast is more like what happens when dispatching on type in a match expression in Scala: 

        x match 

        Unknown macro: {   case s}
    2. Jul 20, 2011

      Anonymous

      Implicit conversions are more for what extension methods appear to be used for in Kotlin. And, as a long-time Scala user, I sometimes wish for extension methods (with inlining) in preference to implicit conversions, at least for performance-critical sections. The JVM does do a lot to mitigate the cost of implicit conversions, and there's a consistency argument that having one construct (implicits) that's useful for so many things is a positive thing, but I think the jury's still out on how to best handle high-performance extension syntax.

      The funny thing about extension methods is that they *are* just syntactic sugar - you can always call a method directly and pass it the object, rather than making it look like the method exists on the object itself, and I think there's an argument to be made that this is actually the clearest thing to do. Object oriented thinking seems to have so infected our minds though that a lot of people don't think to just do this simple thing.

  5. Jul 20, 2011

    Anonymous

    Explicit call-site variance

    Can be used in Scala without any special language support. You can just define

    and use it wherever it is needed.

    Zero-overhead nullability support

    Are there any measurements if the wrapping causes any significant performance drop? Regarding the syntax ... well, it is a plus for me that it is not a special language feature, but fully integrated into the collection framework and usable in for comprehensions.

    Automatic casts

    Well, when I grew up explicit control flow based on checking the runtime type was already considered an anti-pattern, has that changed again?

    Static extension functions

    This makes it impossible to make an existing class implement a new interface, which is a pretty bad limitation for a language without a class library. There isn't any wrapping happening at compile time, the JVM optimizes the whole thing to a single static invocation for more than a year already.

    Inline functions

    @inline in Scala

    String templates

    Instead of ${ use +". Hardly a difference...

    Without any further investigation, this leaves "First-class delegation" and "Modules" where at least the second one has an uncertain future (like Ceylon's "JBoss Module" integration) because of the work on Jigsaw.

    Good luck with your project!

    1. Jul 20, 2011

      > Explicit call-site variance
      Fixed, thanks

      > Automatic casts
      I though that pattern matching performs "explicit control flow based on checking the runtime type". Is it an anti-pattern?

      > Inline functions
      Got it, thanks

      > Good luck with your project!
      Thank you!

      1. Jul 20, 2011

        Anonymous

        > I thougt that pattern matching performs "explicit control flow based on checking the runtime type".

        I don't think pattern matching means what you think it means...

      2. Jul 20, 2011

        Anonymous

        There's a distinction in Scala with respect to pattern matching; you can use it two ways - the first is matching against a sealed supertype, in which case the compiler checks that all possible subtypes are accounted for in the match expression. This gives you much the same security as defining a method on the supertype or using the visitor pattern.

        The second case is exactly as you say, and it's an anti-pattern in Scala as well. In the tens of thousands of lines of Scala I've written, I think I can recall only two occasions upon which this was actually necessary, but I was glad it was there in those cases.

        This gets to a second point, about reified generics. In my opinion, the reason that reified generics are bad is that they *encourage* runtime introspection of the type, rather than relying upon compile-time guarantees. In Java, many programmers feel like they want reified generics because there is no good alternative, but in Scala the implicit typeclass pattern allows you to satisfy this need. I think that long-term, erasure is good for a codebase because it forces you to work with the compiler to ensure that you're getting static guarantees of your invariants. The easier it is to rely on runtime checking, the easier it is for a codebase to degrade to a point where you *have* to rely on runtime checking, at which point you might as well just use a dynamic language.

        1. Jul 21, 2011

          Anonymous

          Your argument against reified generics can be more concisely summed up as "they're bad, because they let you use instanceof with them". Which doesn't make any sense, since by the same token all runtime type information is bad for the same reason. It can be meaningfully argued that "instanceof" and similar constructs are bad (though I would still disagree - IMO, it's a long-standing OOP myth that virtual dispatch is the answer to every problem - you know how that old saying about hammer and nails goes...), but that doesn't mean that mechanisms that enable "instanceof" are bad.

        2. Jul 26, 2011

          Anonymous

          Without reified generics making some frameworks that needs to do some kind of introspection is more difficult, for example: OR mapping, remote method calls, XML mapping.

          You have a real example in Flex. If you transmit a Collection from Java to a Flex client, the framework doesn't know the type of the elements in the collection, because is lost at runtime. With reified generics that problem is easy to resolve.

  6. Jul 20, 2011

    Anonymous

    [Zero-overhead nullability support|../../../../../../../../../../display/Kotlin/Null-safety]

    I checked it out and cannot see the difference with Scala Option, except for the part that the compiler forces you to declare it as a different type in Kotlin. The overhead seems to be identical.

    In scala, you can use Option inside a for comprehension to provide safe calls. Nullability support seems to better in Kotlin primarily because Scala chose to use Option for the same purpose and does not try to fix the nullability issue that arises in regular objects. Kotlin is better, in that it tries to fix the nullability issue at the Java object level and is more transparent. However, I don't see any particular runtime benefits.bob?.department?.head?.name

    This is a simplified syntax for Option.map

    bob.map(.department.map(.head(_.name)))

    Some kind of right associative operator can simplify the syntax further. The operator is the monadic bind.

    def :?(a : Option[A], f : A => Option[B]) : Option[B] = a.map(_.f)

    bob:?.department:?.head:?_.name

    1. Jul 21, 2011

      What about this:

      val x : Int? = ... 
      x?.abs() // x is nullable 
      if (x != null) 
        x.foo() // no more...
      1. Jul 21, 2011

        Anonymous

        i kind of like that you can solve this _in_ the language. makes me wonder, why `if` is a language statement, anyway.

        i think development goes other direction --> see scala-virtualized

        1. Jul 21, 2011

          Anonymous

          err, well, kind of missed your point :)

          1. Jul 21, 2011

            Now, what about this:

            if (x == null) 
              return 
            x.foo()
            1. Jul 22, 2011

              Anonymous

              literally:

              this looks more verbose, but actually your example is flawed, from a control flow
              point of view. in a practical case, you will most certainly have the `foreach` style as
              in the previous post.

              Note that if foo has a Unit return type, you could equally do

              which is less verbose than your code :)

              These confusions come mostly from thinking in imperative programming style.

              1. Jul 22, 2011

                Anonymous

                That is to say, your real example will most likely look like this:

                no need for the return keyword at all here.

              2. Jul 23, 2011

                What do you mean by "flawed from a control flow point of view"?

                1. Jul 23, 2011

                  Anonymous

                  The hypothetical method you are describing is obviously imperative -- the return value is 'void' (or Unit in scala land).
                  The way it is written suggests that 'if x meets some condition, return early', which corresponds to my version with
                  the pattern matching. Instead ofif(x==null)  returnx.foo()

                  causing an unnessary extra control flow statement (return), it's better to think of
                  if(x!=null) x.foo()

                  corresponding with my foreach reply, showing that this equally elegant in scala.

                  What would be the purpose of x?.abs() by the way -- it also looks like a fabricated example. If x is not null,
                  take the absolute of its value, otherwise do nothing?

                  1. Jul 23, 2011

                    Anonymous

                    Cheez, can't you fix this editor? It's horrible

        2. Jul 25, 2013

          What about adding an ifNotNull method to class Object and one to the class in Scala from which null is instantiated? The lack of extension methods in Scala fosters bad OO design solutions. Implicits end up as emergency exit for all kinds of things. Worse than that people think what they are doing with implicits is smart when it is only creating a mess.

    2. Jul 22, 2011

      Anonymous

      You can do a monadic bind in Scala using 'for'. Try it in the REPL:

      scala> val onion = Option(Option(Option(42)))
      onion: Option[Option[Option[Int]]] = Some(Some(Some(42)))
      scala> for

      Unknown macro: { o1<-opts; o2<-o1; o3<-o2 }

      yield o3
      res0: Option[Int] = Some(42)
      scala> for ( o1<-opts; o2<-o1; o3<-o2 ) yield o3
      res1: Option[Int] = Some(42)
      scala> val onion = Option(Option(Option(42)))
      scala> for ( o1<- opts; o2 <- o1; o3<-o2 ) yield o3
      res1: Option[Int] = Some(42)

      1. Jul 22, 2011

        Anonymous

        Oh dear, what an lovely editor. Second attempt:

    3. Jul 22, 2011

      Anonymous

      I don't think that overhead is similar. Option, AFAIK, is a object wrapper around reference, which means 16 wasted bytes (or more on 64-bit jvm) each time you want to have 'null-safe' reference in Scala. Plus extra dereference on access, extra cpu cache misses due to access of unrelated places in memory, extra link for gc to follow, etc, etc. From what I understand, in Kotlin, nullability is just syntax sugar.

      Now, there was a discussion on Scala groups to make Option disappear and just have it as a virtual construct over nullable reference, but I think it failed.

      1. Jul 23, 2011

        Anonymous

        Object inlining in JVMs can resolve this issue. I am not sure how well it works currently.

  7. Jul 21, 2011

    Anonymous

    Hi.
    What features in "What Scala has that Kotlin has not" can't be restricted from normal Scala by the use of an IDE plugin?
    What features in "What Kotlin has that Scala has not" can't be added with an IDE plugin and/or a compiler plugin?
    From my naive point of view I think that all the differences between Scala and Kotlin that prove to be valuable could be achieved in Scala by some of the previously mentioned means.
    Regards,
    Germán
    Hi.

    What features in "What Scala has that Kotlin has not" can't be restricted from normal Scala by the use of an IDE plugin?

    What features in "What Kotlin has that Scala has not" can't be added with an IDE plugin and/or a compiler plugin?

    From my naive point of view I think that all the differences between Scala and Kotlin that prove to be valuable could be achieved in Scala by some of the previously mentioned means.

    Regards,

    Germán

    1. Jul 21, 2011

      Anonymous

      mmm apparently there is a bug with the rich text editor involving pasting text in the first line, the comment was not appearing duplicated in the editor...

  8. Jul 21, 2011

    Anonymous

    Hi,

    there is one feature(or set of features) of Scala you do not describe: Immutability.

    There are three features which enables it and those are deal breaker:

    1) Case classes with compiler generated 'copy', 'hashCode' and 'equals' methods

    2) Method arguments with default values. Without that creating case classes can be very verbose.

    3) Basic immutable/persistent collections: Vector, Map, Set. Those should be bundled in language library and imported in default namespace (probably under different names). Adding and removing an item should not require copying entire collection, it is well explained here: http://code.google.com/p/pcollections/

    By doing this, Kotlin would have one more killer feature from Scala. I know it does not look very important. But lot of Java programmers who turn to Scala absolute love this.

    1. Jul 21, 2011

      1) Case classes covered by Kotlin's enum classes: http://confluence.jetbrains.net/display/Kotlin/Enum+classes
      2) Function arguments indeed may have default values
      3) Collections library is non-existent yet though we'll certainly make sure immutability stuff is covered

  9. Jul 22, 2011

    Anonymous

    Three more things to be removed from the list of "What Kotlin has, but Scala has not"

    1. Jul 22, 2011

      Thanks! We'll there are disadvantages for the features to be added via plug-ins. For instance Enhanced String exposes backward incompatible syntax change.
      Kotlin modules are compilation time instances also, not just run-time.

  10. Jul 23, 2011

    Anonymous

    More unsupported Scala features to add:

    • view bounds
    • context bounds
    • a REPL!
    1. Aug 01, 2011

      Actually we do plan to provide a REPL for Kotlin.

  11. Aug 01, 2011

    Anonymous

    Does Kotlin has anything similar to Scala traits? I find traits particularly useful because they greatly reduce coupling and boilerplate - I don't need to explicitly define a delegate. Scala traits brings much of the power of dynamic languages to a statically checked language. I couldn't find anything similar to traits here or in the classes topic. Perhaps you mean traits can be done with object expressions and delegates, but that would be quite cumbersome.

    If you solve this, please provide an example.

    1. Aug 01, 2011

      Kotlin allows multiple inheritance, so traits are, well normal classes

      1. Aug 01, 2011

        Anonymous

        Forget about my last comment about traits! I confused traits with structural types. I'll post a new comment about this to start fresh.

  12. Aug 01, 2011

    Anonymous

    Does Kotlin has anything similar to Scala structural types? You can find examples here and here. I find structural types particularly useful because they greatly reduce coupling and boilerplate - I don't need to explicitly define a delegate. Structural types brings much of the power of dynamic languages to a statically checked language. I couldn't find anything similar to structural types here or in the classes topic. Perhaps you mean this can be done with object expressions and delegates, but that would be quite cumbersome.

    If you solve this, please provide an example.

    1. Aug 01, 2011

      Anonymous

    2. Aug 02, 2011

      Currently, there's no support for structural types in Kotlin, and one of the key reasons is performance: we don't know how to implement this efficiently (i.e. without using reflection). In Java 7, with invokedynamic it may be easier, though there're some performance problems in interpreter mode for now.

      1. Aug 03, 2011

        Anonymous

        Thanks for the answer. I agree that there will be a performance penalty when compared to interfaces and abstract classes, but in some scenarios it might be worth paying for it. Sometimes an acceptably slow feature is much better than having no feature at all. And I'm sure that Kotlin's implementation of structural types would be faster than any dynamic language, which means it would have excellent performance.

        About the implementation, I wouldn't use invokedynamic. For a given structural type ST, you could generate a normal Java interface ST. Then for each programmer class C whose instance is assigned to a variable of structural type ST, the compiler generates an internal delegate class CST, which implements ST with wrappers to C methods. This way, the original class C doesn't need to be touched. The CST class itself can be placed next to call sites, so that legacy or 3rd party classes can be used as well. With some cheap tweaks in CST and ST access, you can make it perfectly polymorphic (for example, the is operator and reflection would behave as if an ST instance were a C instance, allowing typecast to C, etc). And performance and memory consumption would be two or three orders of magnitude better than any dynamic language.

        I guess the challenge is about tooling and not runtime performance. IDE features such as "open call hierarchy" and refactorings get harder to implement with strucutral types around. These actions can be precise because structural types are indeed statically checked. But making them fast requires each call site to be remembered by the IDE, and this behavior is transitive (a variable of a given structural type can be assigned to a variable of another structural type) which further complicates. Refactorings might affect apparently unrelated classes as well, which may require asking some confirmations to the IDE user. But again, it's much better to have this feature with some limitations than having nothing similar at all.

        Structural types are the only solution I know for a statically checked language to be usable at scenarios that are well handled by dynamic languages. Please at least put this feature in the "may be added later" topic. I guess it's fair to tell visitors that this is unsupported by Kotlin.

        @fernacolo

        1. Aug 03, 2011

          On the implementation: generating adapters wouldn't work for the following reasons:

          • every class loader must have it's own set of adapter interfaces, and it's not clear how to pass a structurally typed value from one class loader to another
          • identity semantics breaks, and equals() too

          Thanks for suggesting to add this feature to the "maybe" list

          1. Aug 04, 2011

            every class loader must have it's own set of adapter interfaces, and it's not clear how to pass a structurally typed value from one class loader to another

            For a given structural type ST, the compiler should simply generate an ordinary interface ST, which are implemented by instance adapters instantiated at call sites. If ST is loaded by a shared parent classloader, then any child classloader can link it - there's no need to pass, reload or load something else. If ST is loaded by a child classloader, language semantics naturally insure that no parent or unrelated classloader will ever need to load the ST interface. In summary, any linkage scenario that works for explicit interfaces also works for structural types.

            Similar rules applies for compiler-generated instance adapters, which implement the ST interface. Again, because Kotlin must allow a programmer to explicitly code adapters, then any compiler-generated adapter should work just as well.

            identity semantics breaks, and equals() too

            If foo is a variable of structural type and bar isn't, the expression foo == bar should be compiled into bytecode-equivalent of foo.$identity() == bar. Here, $identity() is a compiler-generated method of the structural type interface, whose implementation in the instance adapters must return the actual object. If both variables are of structural types, then foo.$identity() == bar.$identity() is generated. So this works even with distinct, unrelated structural types. Other operations such as assignment, instanceof and parameter-passing have similar solutions. For instance, the statement Object obj = someSTInstance should be compiled to bytecode-equivalent of Object obj = someSTInstance.$identity().

            Perhaps you are not willing to "pollute" bytecode with compiler-generated classes, methods and implicit calls, because these might complicate debugging. But please consider that even when we debug Java programs, we face some pollution from accessor methods and implicit calls of string concatenation, auto-boxing and class loading mechanics. I think this will only be resolved when JVM spec provide a way to mark bytecode as "internal" or "debugger-skipable". Also, most Java debuggers are just UIs for the JVM debugger itself. I nice debugger should be aware of the language being debugged and automatically skip semantics enforcement code.

            Is there a dev forum where we can exchange some ideas?

            1. Aug 04, 2011

              > If ST is loaded by a child classloader, language semantics naturally insure that no parent or unrelated classloader will ever need to load the ST interface.

              I'm not sure about this. Could you explain?

              One other problem about wrappers is memory overhead: both PermGen space and heap. I don't see a reason why we should prefer this to invokedynamic.

              > Is there a dev forum where we can exchange some ideas?
              There's a issue tracker: http://youtrack.jetbrains.net/issues/KT

              1. Aug 05, 2011

                Anonymous

                Actually, I really don't care about how it's implemented! Given a set of nice features, you can start with an "easy" and "reasonable" implementation and then switch to something "sophisticated" in the future. But since we're evolving in the discussion, let's see where it gets.

                > If ST is loaded by a child classloader, language semantics naturally insure that no parent or unrelated classloader will ever need to load the ST interface.

                I'm not sure about this. Could you explain?

                Because structural types are statically checked, they behave almost as ordinary interfaces. The fundamental difference is that the programmer doesn't need to put implements clause in a given class to make it compatible with the structural type. Also, the compiler must not generate such implements clause under the hood, because that would break binary compatibility. Hence, a class that is compatible with a structural type does not have any reference to such type, and can be loaded by a classloader that doesn't know anything about the structural type - for example, a parent classloader loading a legacy class from an old JAR.

                The trick comes when the class instance is assigned to a structural type variable, or passed to a method that receives a structural type parameter. This code is required to know both the instance class and the structural type, otherwise it wouldn't be able to declare the structural type variable, nor link to a method which receives a structural type parameter. Because this code knows the structural type variable, its classloader must have access to the structural type interface, hence it can define a hidden adapter class which explicitly implements such interface, wrapping every call to the actual instance.

                Furthermore, if one puts the structural type in some parent classloader, which is shared by two unrelated child classloaders A and B, it's perfectly possible to pass an instance of a class defined by A, to a method from B which accepts a structural type parameter. In this case, the adapter class will be loaded by A, and because it implements the structural type interface (which is loaded by the parent classloader), then B can have full access to the methods.

                One other problem about wrappers is memory overhead: both PermGen space and heap.

                The wrapper will have just one reference, hence it will be a tiny object when compared to strings, arrays, lists, maps and other data objects. Even a HashMap entry will be greater than that. So I think the memory overhead is minimum. Also, the adapter instance is a perfect scenario for allocation of object in the stack (done with escape analysis), because it's typically used in generic methods and temporary processing. Using structural type objects as permanent data structures looks like bad design to me. Well defined classes or interfaces would be a better option for long living data structures.

                I don't see a reason why we should prefer this to invokedynamic.

                Notice that invokedynamic is targeted to dynamic languages, which hopefully is not the case of Kotlin! The problem with invokedynamic is that every call requires a custom method lookup, which is hugely slower and less optimizable than calling an interface method.

                If you look at structural types just as way to remove the boilerplate of defining well-behaved interfaces and implementing adapters, a design based on implicit interfaces and adapters becomes natural and almost obvious. But again, you can start with an easier implementation, then evolve to a better one latter. Just take care with semantics!

                1. Aug 05, 2011

                  Because this code knows the structural type variable, its classloader must have access to the structural type interface, hence it can define a hidden adapter class which explicitly implements such interface, wrapping every call to the actual instance.

                  My doubt was about the situation where there are two unrelated class loaders, both have their own generated interfaces for the structural type, and they are incompatible. Now I sort of see that it may be that we can guarantee that this does not happen, still not sure, but not so skeptical any more.

                  The fact that Scala does structural types via reflection makes me doubt more.

                  Notice that invokedynamic is targeted to dynamic languages, which hopefully is not the case of Kotlin! The problem with invokedynamic is that every call requires a custom method lookup, which is hugely slower and less optimizable than calling an interface method.

                  This is not exactly so. VM people say that currently JIT-compiled invokedynamic may be even faster than JIT-compiled invokeinterface. This does not hold for the interpreted mode. JSR-292 provides a lot of interesting machinery for function resolution, so I wouldn't call that "custom". E.g. it is seriously considered to use invokedynamic to instantiate lambdas in Java 8.

                  Do you mind filing an issue about structural types to our tracker? Thanks

  13. Sep 02, 2011

    Anonymous

    Can anyone post the differences here http://www.diffdiff.com/diffs/scala-kotlin

    It will be good to read and understand

    1. Sep 05, 2011

      Sure

    2. Oct 13, 2012

      Could you provide a different link or paste those Scala compiler issues here? Seems like the angry young man has disappeared ...

      Thanks, Oliver

  14. Dec 01, 2011

    Anonymous

    Will you also have optional parentheses in Kotlin?
    Instead of 
    if (validToken(s.toLowerCase().trim())) {
    you will have a more readable syntax
    if (validToken(s.toLowerCase.trim)) {
    and I think there is a proposal to introduce a then keyword to Scala 2.10 so you simply have:
    if validToken(s.toLowerCase.trim) then {
    I would love such a clear syntax
    Best Regards
    Eric
    P.S. I think Kotlin has the best chance to be a "Java replacement" of all the current JVM languages if you can also provide good Eclipse support.
    Will you also have optional parentheses in Kotlin?

    Instead of 

    you will have a more readable syntax

    and I think there is a proposal to introduce the then keyword to Scala 2.10 so you can simply write:

    I would love such a clear syntax

    Best Regards

    Eric

    P.S. I think Kotlin has the best chance to be a "Java replacement" of all the current JVM languages if you can also provide good Eclipse support.

    1. Dec 02, 2011

      Hi Eric,

      If you don't want to write parentheses, properties may be the right tool for you.

      And yes, we are planning to provide Eclipse support.

      Thanks.

      1. Dec 02, 2011

        Anonymous

        Hi Andrey,

        Properties will be a great addition of course, but what about simple method calls like List.size()?

        I am not an expert but the only advantage I can see is that you know it is a method call and maybe that is just an implementation detail.

        Are there other advantages for requiring open parenthesis?

        1. Dec 02, 2011

          There are two things:

          • Uniformity of usages: everybody either says size() or size
          • Clear distinction between properties and functions: everybody sees what they are using
          1. Dec 02, 2011

            Anonymous

            Clear distinction between properties and functions: everybody sees what they are using

            Ok that make sense, but if Java had Kotlin properties from day 1 then List.size might have been implemented as a field :-)

  15. May 14, 2012

    I think you might wish to update the info about string interpolation, because Scala 2.10 will support it: http://docs.scala-lang.org/sips/pending/string-interpolation.html.

    1. May 18, 2012

      Done. Thanks, Eugene!

  16. May 18, 2012

    I'd also revise the "type erasure" point and mention that Scala has manifests that enable selective reification of types.

    1. May 19, 2012

      Removed the "erasure" bullet alltogether. Thanks

  17. Mar 06, 2013

    This is what happens when your language is overengineered: http://scalapuzzlers.com/

    I've tried to reproduce several of them in Kotlin, but could not - Kotlin is much simplier and don't allow shooting yourself so easily.