5 ms·
I've been using Kotlin for work (I'm a PhD student, so work is to be understood in a peculiar fashion) and I'm really liking it. It's a much needed upgrade to
by norswap 11y ago
I've been using Kotlin for work (I'm a PhD student, so work is to be understood in a peculiar fashion) and I'm really liking it.
It's a much needed upgrade to Java whose fundamental advantage is what I'd call "crispness": you can write terse code that is actually understandable. In particular, the notion of inlining closures allows for efficient functional programming and great DSLs.
In comparison to Scala, Kotlin is much less advanced, but much much simpler. Like said earlier, it's easily as terse as Scala. Scala, however, is much more expressive (what I'd give for typeclasses...) and that sometimes hurts in Kotlin as it does in Java.
There's also Ceylon (JVM language by Red Hat) who is seemingly in the same niche and which I very much wants to experiment with. From what I've read so far, Ceylon seems conceptually more elegant and more powerful than Kotlin. The open question is whether it can match Kotlin's crispness.
It feels a bit early for a release however. The compiler is still completely wonky. Inference sometimes fails on things that should be completely trivial. It is particularly bad at taking return types into account. It's fully usable, but expect to work your way about some linguistic unpleasantness (or outright bugs).
Also, for some reason, Kotlin seems big in Japan.
- mike_hearn 11y agoBy typeclasses, do you mean structural typing a.k.a. duck typing a.k.a. Go-style interfaces? I don't personally understand why people care about that: a simple structural match on names/parameter types doesn't seem like a strong enough signal that someone actually intended to implement such an interface. But ... type classes can be implemented on the JVM relatively efficiently these days. I threw together a simple Kotlin version a few weeks ago that let you write something like: val foo = Foo() val bar = foo.dynamicCast<Bar>() where Bar was an interface that Foo could have implemented but didn't. It worked, but I didn't see any value in it for myself, and it didn't use the latest JVM reflection APIs so it was slower than a normal interface call. If there's some big population of people who really want this in Kotlin and would be much happier if they had it, then I might sit down and reimplement it on top of Remi Forax's proxy2 framework, which should give 1:1 native performance.
- lmm 11y agoNo. Structural types are called structural types. The best known typeclass implementation is that of Haskell where they're built into the language, but Scala has them as a pattern implemented with implicits; I can try to explain the concept here if you like but honestly there are probably better explanations out there. Typeclasses are more powerful than structural types in that the implementation doesn't have to be there already (i.e. you can have an automatically resolved adapter). You might be able to hack an implementation by combining extension methods with structural types (though given the internals of how extension methods are usually implemented on the JVM I doubt it). They also allow a way to do "static virtual methods" i.e. polymorphic methods that you don't need an instance to invoke, which are used for things like Monoid#zero. Finally they provide a nicer way to express F-bounded polymorphism (i.e. the constraint on Enum or Comparable that we try to express in Java as Enum<E extends Enum<E>> or Comparable<T extends Comparable<T>>, which is clunky and doesn't actually fully constrain implementations the way it's intended to).
- mike_hearn 11y agoBut both Java and Kotlin interfaces can provide default implementations. So when I say "make a class implement an interface even if it doesn't declare it as so", that included interface default methods coming along for the ride. The best explanation of Scala type classes IMO is here: http://danielwestheide.com/blog/2013/02/06/the-neophytes-guide-to-scala-part-12-type-classes.html But as you say, what Scala calls type classes are more of a pattern with some language support - you just define what is essentially an adapter, but one which is constructed/used implicitly. Being able to write: interface Foo { val prop: String fun someMethod() = "we are set to $prop" } and then being able to treat any Bar as Foo as long as it has some property "prop" but without regard for whether it has someMethod, sounds pretty much the same thing as Haskell/Scala's idea of type classes to me.
- lmm 11y agoIt's not just a default, you can provide an adapter specific to the type: implicit object IntMonoid extends Monoid[Int] { def zero = 0 def plus(a: Int, b: Int) = a + b } implicit def endoMonoid[A] = new Monoid[A => A] { def zero = identity def plus(a: A => A, b: A => A) = a andThen b } You can't do that with a default method.
- barbs 11y ago> ...what I'd call "crispness": you can write terse code that is actually understandable. What an awesome term, I love it.
- niutech 11y agoThere is also Xtend [http://xtend-lang.org http://xtend-lang.org], which is similar to Kotlin, but compiles down to Java.