Hacker News new | comments | show | ask | jobs | submit login
Kotlin 1.0 Released: Pragmatic Language for JVM and Android (jetbrains.com)
379 points by belovrv 529 days ago | hide | past | web | 110 comments | favorite



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.


By 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.


No, not that. I agree with you on structural typing.

What I mean is what the Scala doc calls "context bounds": http://docs.scala-lang.org/tutorials/FAQ/context-and-view-bo... (bit outdated: view bounds are deprecated)

You could think of it as "abstracting over the adapter pattern", i.e. being able to write methods that take as parameter things that can be adapted to an interface.

(And of course the main point of the Adapter pattern is retroactive implementation of interfaces.)

But, and this is important, you get to pass the actual object instead of the adapter. This matters when you need to required multiple adapters, or when you work with object equality. The object type can also flow through the type parameters (although that's sort of doable with adapters only).

Finally, because a typeclass instance is actually a single object per type satisfying an interface, you can use it for things like factory methods (what they call constructor classes in Haskell).

It's close to what I propose here: https://discuss.kotlinlang.org/t/kotlin-and-the-expression-p...

but there are differences. Scala typeclasses are based on implicits, this gives you more control to select the adapter you want depending on where the code runs. But, unlike what I propose, it's dependent on static typing, so it's not possible to select the adapter depending on the run-time type.


Right, I remember your thread, which is I guess why I'm a bit confused, as you said what you really wanted to do is make a type implement a new interface.

I do understand Haskell type classes but in a language like that, they're almost obligatory as it's not an OO language at all. But in something like Kotlin, you should need it far more rarely, so the automatic/implicit "conversion" (I realise it's not quite "conversion" in Haskell) is less vital. So some convenience for creation of adapters would seem to get you the same practical benefits in much the same way.

With respect to the difference between using a singleton vs a freshly allocated wrapper - is it really worth complicating the Java interop for what seems like an optimisation? Code that works with object identity is rare in all the code I've written and can't even be done at all in a pure functional language. And requiring multiple 'adapters', you mean interfaces I think (?) can be done already by imposing multiple generic type constraints (the where clause). The VM should be able to optimise out the overhead of the wrapper class in many cases.

That leaves implicit conversion. But Kotlin doesn't even auto-convert Int to Long. I doubt that implicit conversion will ever be a part of the language outside of a few special cases like toString().

I guess for my use cases, a wrapper class + an extension method on the existing type that adds a toFoo() is sufficient.


Both OOP and type-classes are a form of ad-hoc polymorphism, but OOP is not a replacement for type-classes. The scope overlaps and personally I find both useful, but you're making the mistake to think that type-classes are about subtyping. They are not.

Also, type-classes in Scala are not implemented by means of "implicit conversions". It has nothing to do with it. Type-classes in Scala are implemented by means of implicit parameters, also called context bounds, but that's different.

Of course, you don't really need implicit parameters to work with type-classes. That's just syntactic sugar, because you can just pass dictionaries (type-class instances) around manually.

No, the far bigger problem that Kotlin has is that it doesn't support higher-kinded types. Without higher-kinded types you can't express generic code for containers (e.g. M[T]). And without that, you can't do do type-classes and you can kiss most FP abstractions goodbye.

If you don't believe me, try coming up with an interface for things that have "map", "filter" or "flatMap.


I find typeclasses are vital when you want to give your classes secondary functionality e.g. serialization, database persistance. You need only look at the modules, mixin annotations, reflection and XML configs that Jackson or Hibernate have implemented - for good reason! - to see that traditional OO is inadequate for that kind of use case (particularly when you have a generally usable library datatype e.g. joda-time - no-one would want to have joda-time depend on Hibernate or Jackson, but at the same time the code to use it with those things should be in some library, so how do you safely connect them up?)


The point of the class instance (the "singleton") is not performance, it's that it exists independently of any instance of the type, so it can be used for factories and such.

This however, is not my main concern, and as you remarked, it does not fit very well in OO, which is why it isn't in my proposal.

On to the interesting part.

You want multiple adapters, rather than multiple interfaces, precisely because you want retroactive interface implementation. That's really the crux here. So either you pass two adapters, or you make a class combining the two adapters. I think both solution create too much bloat to be acceptable.

For me, equality isn't so rare. Both identity (==) and structural equality (equals(), done right) pop up with some regularity. Each time you use a map, for instance. And functional languages are perfectly capable of structural equality.

While Scala typeclases are implemented with implicit objects, typeclasses precisely avoid using implicit conversions. You still have the original object, the typeclasses just provides functions to work with it. It's only an implicit conversion in the same sense that passing an ArrayList to a function expecting a List is implicit conversion. This is manifest in Scala where you require a typeclass using some sort of type bound.


Thanks for the explanations. Yes, there seems to be an impedence mismatch when trying to import the concept of Haskell type classes to OOP languages.

WRT a combined adapter class, it'd look like this in Kotlin:

  class FooBarAdapter(val x: Baz, private val y = Foo(x), private val z = Bar(x)) : Foo by y, Bar by z
A bit bloaty, but still a single line of code.

(I know you already know this, I'm writing it here for Kotlin newbies).


The problem there is composability. Foo and Bar might come from different libraries. Also it's very common to define one typeclass in terms of another, often several layers deep. It's easy enough to define a wrapper at an outer layer, but when you have an EitherT[WriterT[Future, MyLog, ?], MyError, MyValue] it becomes quite clunky to apply wrappers to MyLog and Future.


Wow, actually this hadn't made it to my bag of trick yet.

It's very nice, though I can see that becoming quite heavyweight when you nest these calls (either heavy from the overhead, or from the syntax - at least you get to decide).


It's nothing like duck typing -- type classes are a major thing in Haskell, which should tell you how far from duck typing it is ;) They're also present in Scala (as the OP mentioned), in Rust as Traits, and C++11 had a proposal for Concepts, which are quite similar as well.

The short but slightly inaccurate description is that type classes are a way to allow interfaces to be implemented separately from the way you define types.


No. 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).


> The best known typeclass implementation is that of Haskell

Oh, I don't know about that one. In Scala type-classes are interfaces and you can put that OOP to good use. For example in the Cats library, you get an Applicative type-class inheriting from Apply, a FlatMap inheriting from Apply and a Monad inheriting from FlatMap and Applicative. By comparison in Haskell a Monad is not automatically an Applicative and you get duplicate functions with different names, duplicate code, duplicate tests, etc.

Another advantage is that in Scala type-class instances are actual values that you can pass around. And because type-class instances are actual values, along with implicits which are lexically scoped, you can always provide another instance of a type-class, depending on context. You do not have the modularity problems arising from usage of type-classes in Haskell.

"The best implementation" is entirely subjective IMHO.

EDIT: got down-votes, not complaining, but I'd like to know where I'm mistaken. Thanks.


Didn't downvote, just FYI: Haskell's Applicative is a superclass of Monad now.


Which means you are now forced to write the boilerplate

pure = return

(<*>) = liftM2 ($)

In Scala, you get it for free for any monad.


Since GHC-7.10, the minimal complete definition for a Monad instance has been (>>=) (bind) only. So you can simply move the old definition for "return" into the Applicative instance as "pure" and you're good.


He means best-known, not best known. It's a statement about which is better known, not which is better.


Oh, sorry. I'm not a native English speaker, sometimes I have parsing issues :-)


i wouldn't sweat it, there's a fair amount of ambiguity in the english grammar D:


But 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.


It'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.


While it's an excellent example, I wonder if people don't see "endoMonoid" and run away screaming.

I really wonder if people would have different reactions if this was presented as "Addable" instead.


Yeah, I wonder about calling it "addable" or "mergeable". But neither of those really captures the full generality of it - would you expect composing functions to count as "adding" or "merging"?


"Combinable"?

Integers can also be combined with other operations, like multiplication, min or max. None of those sound like "adding" or "merging" them to me.


Good point. Though a good side effect is that when you see it used that way you "a-ha!", or you figure it yourself you feel smart. Something like "endoMonoid" doesn't immediately suggest these use cases either (unless you're a math buff) but if you get to the explanation you're just left with the feeling that this is what was intended all along, not a neat breakthrough.

That's reverse API psychology for you :D


Go's interfaces are not type-classes and type-classes aren't about structural typing.


> ...what I'd call "crispness": you can write terse code that is actually understandable.

What an awesome term, I love it.


There is also Xtend [http://xtend-lang.org], which is similar to Kotlin, but compiles down to Java.


Congratulations to Andrey and the rest of the JetBrains team. This really has been a long time coming. I've been following and experimenting with Kotlin now for the past year or so and it definitely solves a lot of Java's pain points without having to reinvent the way one thinks about programming languages.

The interoperability and backward compatibility is one of the most useful features, meaning I don't have to wait for an entire ecosystem to develop around it.

The tooling is also incredible and will only get better.

Concurrency support with Quasar and Comsat makes it relatively effortless without reinventing new libraries.

Overall, Kotlin, IMHO, is one of those items in the "Pro"s section on any shop seriously evaluating a JVM stack. Especially with Java9 on its way, it's only going to get better.


> Especially with Java9 on its way, it's only going to get better.

What's Java 9 going to add that Kotlin can benefit from?


Not much, other than VarHandles, JIT plugins and the overall JVM improvements maybe.

The real juice will be in Java 10, assuming value types, proper generics, JNI replacement and AOT support get delivered.


Presumably, they coexist; if you have a lot of old Java code, upgrading to Java 9 will likely be much easier than translating to Kotlin, but you still have a healthy codebase.


Kotlin is currently my favorite alternative JVM language. Kudos to all collaborators for the great work. After 5 years of hard work, you finally made it!

Here's a little starter project for Kotlin webapps using Spring Boot and React.js, I made a while ago:

https://github.com/winterbe/spring-kotlin-react-demo


My humble contribution to the hipster-stack-starter-pack: https://github.com/herval/gradle-kotlin-docker-multiproject-... :-)


>Building a JVM container with Docker. So you can put your interpreter inside your JVM inside your Docker container inside your Kubernetes inside your VPS inside your OS and be happy.

I want to cry.


IT has to be satire right?


yes, I tried my best to make it obviously satire...


Kotlin sort of feels like Groovy "done properly" (with no disrespect to the authors of Groovy). Groovy kind of evolved in an opportunistic, unplanned manner and ended up with millions of features, cool whiz bang aspects that look awesome that don't always turn out well when you use them on a large scale. Kotlin seems to capture the same ideas (highly pragmatic, maintain perfect bidirectional compatibility with Java), but done in a much more thoughtful manner. Fingers crossed it works out.


I like Kotlin, but I prefer Xtend. I find it to have even less verbosity and more expressiveness, and it uses the same Java types. I'm using Eclipse with it for now, but I prefer Android Studio. Congrats on the release!


One example is Kotlin was designed to be statically typed from the ground up, whereas Groovy's static typing was added 9 yrs later (mid-2012) as an afterthought.


I understand the author of Groovy said he'd never have started the language if he'd known about Scala.


"I can honestly say if someone had shown me the Programming in Scala book by Martin Odersky, Lex Spoon & Bill Venners back in 2003 I'd probably have never created Groovy."

http://macstrac.blogspot.co.uk/2009/04/scala-as-long-term-re...


Shortly after saying that, he went on to work on the Kotlin libraries and compiler (not any more, though).


And I'm pretty sure if he had known that line would be incessantly quoted as a slur of Groovy every single time it gets mentioned on Hacker News, he would probably have never said it!


One of authors of groovy works on kotlin.


This used to be the case a while back, but James is no longer working with us.


Kotlin is a beautifully designed language: small, modern + statically typed that's naturally terse and elegant - ideal for both OOP and LINQ-like/functional programming:

https://github.com/mythz/kotlin-linq-examples

Thanks to JetBrain's tooling prowess it also has great integration with Android Studio - Light years better for functional programming than Java 1.7:

https://github.com/mythz/java-linq-examples

Which can seamlessly integrates with Java within the same project. Google/Java/Android Devs are sitting on a unrealized gold-mine of productivity with Kotlin, should be the modern successor for Android.


You're really comparing a small subset of what "LINQ-like functional programming" is to the (small) pieces that Kotlin can do.

LINQ is not (just) an interface over some collections. It is a comprehension syntax (that kotlin doesn't have) that works on any types that have Select/SelectMany/Where.

This gives you a lot more power than what Kotlin gives you, as you can 'extend' other things that don't inherit from an IEnumerable<T>; for instance Task or a custom data type that has its own inheritance hierarchy.

The 'comprehension' part means you can deeply nest things (similar to scala's for compehension) without building up a stack of {}. This is quite common when doing asynchronous programming, and Kotlin doesn't really help you out at all here.


It's not a small subset, it's the most popular subset that .NET developers use LINQ for everyday as identified by C#'s 101 LINQ Examples and compares them against the equivalent code in Kotlin. The C# examples does use the LINQ SQL-like DSL whereas other languages get by with a more readable and less indirection version using functional API's available on collections. It's up to the developer which they prefer however the LINQ DSL is no more powerful than regular function chaining with lambdas.

LINQ also allows capturing Expression Trees however that's only useful for developers creating LINQ providers or where they need to capture and rewrite/reproject the expression. None of these examples are in the published LINQ 101 examples as they're usefulness is limited to a small niche of use-cases.


>languages get by with a more readable

I'd love to see how you think the kotlin (or java) version of the following would be more 'readable'

     var result = 
         from a in taska
         from b in taskb
         from c in taskc(b) where c.Contains("blah")
       select c + a;


Again you're just cherry picking a rarely used niche example that benefits from a SQL-like cross join, that you couldn't even map to a real-world example. What's the point, to show it has terse syntax for rare use-cases?

Whilst the code is terse it's also deceptive as it's not obvious it's performing a cross-join over multiple collections - so even in this case I'd prefer using a nested maps which IMO is more readable as it's clearer what's actually happening. Readability != terseness, it's clarity of intent.


>Whilst the code is terse it's also deceptive as it's not obvious it's performing a cross-join over multiple collections - so even in this case I'd prefer using a nested maps which IMO is more readable as it's clearer what's actually happening. Readability != terseness, it's clarity of intent.

It has nothing to do with SQL cross joins across multiple collections.

LINQ is useful for things that aren't even collections! In my example I was using them on a Task<T> to represent an asynchronous computation. This is common code we would write in a large C# application I was on at my previous job.


It's not exactly helping your case that it isn't at all clear what that sample is actually doing and what kind of practical task it might be used for.

I've been doing C# for years, use and enjoy Linq, and I can't remember the last time I touched the comprehension syntax. IIRC, it does make a few relatively obscure things easier than they would be with method and lambda syntax, while there are a few different obscure things that are easier without it. On balance, I lean against it as being yet another sub-language for you and the rest of your team to learn and understand what it's really doing under the hood.


The sample is not clear?! How would you write the same asynchronous code in C# without the LINQ syntax? Can you give an example? All the code does is get a from async taska, b from async task b, feed the result of b into task c to get c, and if c contains blah return c+a asynchronously.


If you understand it, then exactly what are the return types of these tasks and the types of a, b, and c? Are they single objects or IEnumerables?

If they are enumerable, then what exactly does c + a do? It is creating a new enuerable of every a added to every c, like a SQL cross join?

If it is a single object, then what exactly does the where clause do? What does it return if c does not contain blah, and what becomes of a in that case? Does it get returned, added to null, disappear into the ether, or does it figure out that it doesn't need it, and never actually evaluate taska? What happens if taska modified some other state somewhere? For that matter, if it's figuring that out, that would control the order that the tasks are evaluated in. What is that, exactly? Is taska run at the same time as taskb, or does it wait to see if there is actually a c to add to it's result? Or maybe it gets evaluated before or after taskb, or at the same time.

That stuff matters. I'd rather make it clear at a glance what's going on than write something super short and clever that nobody can figure out the details of.



> "LINQ also allows capturing Expression Trees however that's only useful for developers creating LINQ providers or where they need to capture and rewrite/reproject the expression."

As far as I know, LINQ to SQL uses Expression Trees under the hood, I'd argue that even if you're not using them directly, LINQ to SQL is a pretty useful application of LINQ.

Effectively, Expression Trees are what enables custom macros for LINQ. Even if not everyone writes macros, the number of users of those macros is much more widespread.


even more interesting is that Spring Boot now supports Kotlin [1]. So you can use https://start.spring.io/#!language=kotlin to generate a gradle project with Spring Boot.

[1] https://spring.io/blog/2016/02/15/developing-spring-boot-app...


Been using it for a while, glad 1.0 is out! This is an amazing replacement for Java on Android and hope it gets more public recognition now that it's officially out.


I designed my reactive mvvm micro-library (https://github.com/zserge/anvil) for Android with kotlin in mind, and so far it saved me lots time. Kotlin+Android is a great choice.


And here are some examples of using Anvil with Kotling: https://github.com/zserge/anvil-kotlin-demos


I heard about Anvil, it rocks! Great job man!


Been working with it as well since last summer and following it for a lot longer than that. Glad to see they've reached 1.0!


actually I'm still unsure about kotlin. some things are really great some things are not. I mean i will still use kotlin, especially for libraries since it is great for that. however somehow I still missed something on top of Executors and CompletionStage. And I'm totally unhappy about "So, why doesn’t Kotlin have its own package manager, or its own build system? Because there’s already Maven and Gradle, and re-using their huge number of plugins is crucial for many projects." The answer would be totally valid, however people who worked with maven, gradle, ant or even sbt (which isn't offically supported) could be unhappy. all of these build systems are useful, but not actually great. I mean you could work with them but it's not actually great to use them.


Maven is fantastic in my book. Literally the best build system I've seen. But even if you disagree with me on the specifics, if there's something you want to change about one of those tools, surely you'd want to make the same change when building Java? I don't see any value in rewriting one of those tools in Kotlin to make it Kotlin. (And if some particular idea is easier to express in Kotlin, I've written Maven plugins in Scala, I'm sure you could do it in Kotlin too)


currently I use sbt and as said they are okai to work with, but they are not great, else there would've been only one. ;) Actually I like many things on sbt, but It has some clear downsides and it's not hard to figure them out. Actually I would favor gradle from all of them however I started with sbt and I think I actually will stick with it a while, even if there are some downsides.


That's a very unconstructive post. Please be more specific about upsides and downsides rather than just saying "It has some clear downsides and it's not hard to figure them out".


sbt downsides:

    - slow resolution (could be really really really slow)
    - transitive dependencies could be a mess since it could actually will mostly give you a evicition but it's hard to actually resolve that.
    - however if you have two plugins a evicition is not printed, so you will actually get a funny stack trace if you actually use a library that resolve something via reflections. (i.e. closure compiler)
    - sbt is slow
    - sbt has some wierd operators.
    - has problem with dynamic ranged versions
    - scoped settings are cool, but could be wierd to understand, especially for new people
    - sbt-web which tries to use npm which it packages as webjars which actually is a total mess since you actually run into the great world of npm packaging and try to force it into a completly different format.
there are more, however these are the ones I often deal with


How does Maven compare to Haskell's Stack in your opinion?


I haven't used Stack enough to compare. The key points for Maven I think are: no arbitrary code in the build, strong adherence to conventions, extending that to the rest of the project lifecycle (e.g. the maven release plugin has a standard format for tags), immutable releases and consistent resolution.


how do you do conditionals or loops in maven?


You don't. If you need to run custom code in the build you have to encapsulate that as a plugin (which will be a first-class maven module in its own right, which naturally nudges you to writing unit tests, having a proper release process with semver and so on for your build step). But mostly you keep your build simple and declarative and you put any business logic in the actual code. It's wonderful.


> how do you do conditionals or loops in maven?

What you're asking for is Turing-complete XML.

History has shown that this is usually a mistake.


Or maybe he's asking for a non-XML Turing-complete configuration.


You can use the maven polyglot plugin [1] to write your POM in something other than XML. It's fairly new, but it's there. We use it in JRuby to write our POMs in Ruby. As an example of a loop:

https://github.com/jruby/jruby/blob/8e29ae1302e7aa989b8808f7...

[1] -- https://github.com/takari/polyglot-maven


Why can't I use Java with Polyglot?


I don't know much about the development of the project, simply that it exists and is usable. I'd file an issue with the project and see what comes of it.


Kobalt is a clever and fast build tool written in Kotlin. It is much simpler to use than the others you mention and still works with maven repos


Can you name any criticism of Gradle? I've used it for years now (for Android development). It's steadily being improved, and is really good in my opinion.


There's no clear separation between build config and random Groovy expressions. There's not even a spec for what a .gradle file looks like. That's fine for "get this done quickly", but ultimately it encourages people to put one-off hacks in the build file that become a maintainability nightmare.

(And because its "config" files are arbitrary turing-complete code, its IDE integration is never going to be as good as Maven's)


So I think gradle has a lot of problems, but having access to Groovy anywhere is a good thing. You can always make your builds do what you want.

And as in all things if your code gets too complicated you need to refactor, extract logic into methods/classes, etc.


You can always make your builds do what you want, but the flipside is you can never understand what someone else is doing with their build. I don't think the build system is the place for turing-complete code. Business logic certainly doesn't belong there. Keep the build simple and standardized, and keep code in code.


I've arrived at the opposite opinion over time ... I think people need to recognise that a build system is code. When we pretend it isn't we ultimately end up contorting the system to make up for the missing flexibility. A lot of it looks declarative, but it is not always the case. Sometimes you want imperative constructs. The build should be recognized as code, maintained as code and use a first class language suited to the job.

I do have a problem with Gradle which is that it is almost entirely magical unless you are a pretty advanced Groovy programmer to understand how it is doing what it is doing. I have never felt more disoriented than when trying to learn how to customise a simple aspect of my build and having people post snippets that work but seem completely disconnected from anything else in the build process.


I think that when you do need code in your build that code should be first-class. Which means it should have test coverage, a release process, follow your coding standards and all the rest of it. The maven plugin model encourages that.

And maybe this is making a virtue of necessity, but I find the overhead of creating a plugin stops people from putting random "different compiler arguments on a Wednesday" conditionals in every build, which is all too common if you give them immediate access to a turing-complete language.


It's not "business logic", it's "build logic".

Your criticism applies equally to non-build code. Don't approve PRs for bad/inscrutable code.

In gradle you can build plugins just like maven. But a simple 'if then' doesn't require all the heavy lifting of a plugin.


> Your criticism applies equally to non-build code. Don't approve PRs for bad/inscrutable code.

But code is where logic goes. People expect logic there. It's the same objection as to logic/conditionals/looping in web templates, or routing config files, or persistence object mappers. If it's logic, it belongs in code!


There's a "spec" for Groovy at its website groovy-lang.org but that site's owned by a private individual so it could be pushing it to call it a real spec.


He means there's no spec for gradle files which are written using groovy.


Actually criticism is mostly personal however there are a few:

    - I dislike the DSL // not a really useful criticism I know.
    - Some things needs Groovy which isn't a mainstream language
    - Had Bad support for Scala, which I use heavily mostly resolved since 2.2 and thanks to linkedin newer version even have twirl + playframework support.
    - sometimes the syntax file of the DSL couldn't be highlighted in eclipse / intellij
    - Bigger build files could be really slow (mostly resolved in newer versions)
Btw. whats really really good on Gradle is the dependency resolution, which is really fast compared to something like sbt.


> Groovy which isn't a mainstream language

Originally on Gradle.org's website, they wrote they'd encourage anyone who wanted to enable Gradle to allow another scripting language for writing build files, and that they'd help them with bundling it. But since Gradle 2, it looks like too much of Gradle's own source and plugin code is written in Groovy for that to still be feasible. Gradleware also employed one of the former developers who used to work on Groovy when they were retrenched by VMWare a year ago, and I suspect he'd actually sabotage any outside attempt to make Gradle polyglot, like, say, Vert.x is. So it looks like you're stuck with Groovy if you want to use Gradle. With the good comes the bad, as they say!


Right now, with the Grails hype gone from German's JUG meetings, I would say Gradle is the only thing keeping Groovy alive.


- Takes up GB of memory compared with any other JVM build tool

- It is the slowest of all JVM build tools available.

- Hard to know what DSL should look like in each version.

- Seems like the only thing keeping Groovy afloat


The documentation for Gradle is very thorough but man is it a PITA to find answers for stuff, like, for example, how do I GZIP compress the output the application plugins distTar task. The answer is not something you would just arrive at when you do figure it out and it's also not documented anywhere.

Gradle's biggest problem is that it's too flexible.


  > I still missed something on top of Executors and CompletionStage.
You could use RxKotlin. It has Schedulers and Observables/Single/Completable for interacting with async tasks. https://github.com/ReactiveX/RxKotlin


there is a kotlin build system

http://beust.com/kobalt/home/index.html


> however people who worked with maven, gradle, ant or even sbt (which isn't offically supported) could be unhappy.

Well yes they could be - but this isnt a project to build a general purpose build tool so this is not really relevant


kotlin looks like swift for java. I hope google will remove java and start adding kotlin as a first citizen :)


The trouble between google and oracle wasn't about Java, it was about the Java Standard Library and Harmony. Which wouldn't really be solved by Kotlin.


Irrelevant, Kotlin is still better than Java


I’m already using Kotlin in my Android projects. So far it’s great! I’d also done a presentation about Kotlin during our company’s Lightning talks. Take a look here – Kotlin Developer Starter in Android projects.

https://t.co/oVPJw1YIGa


Congratulations to everyone involved. I like Kotlin and I hope to see it as my main language for Java platform. I used it and it really "clicked" for me. Almost everything was designed the right way in my opinion.


I started looking at Kotlin docs [1]. For higher order functions support,

fun lock(lock: Lock, body: () -> T): T {

}

Is there any technical reasons why normal function declarations are not using '->' as a return operator ?

fun hello(name: String) -> String {

     println(name)
}

Swift [2], Rust & others are using it.

It will just make the experience uniform with consistent Functional Types

[1] https://kotlinlang.org/docs/reference/lambdas.html

[2] http://fuckingswiftblocksyntax.com


: T is consistent with values, it's the way of saying a thing has a type. It makes for much more consistency when refactoring a function, and (at least in Scala) supports the Uniform Access Principle style.

    def lock(...): T = ...
    val lockResult = lock(...): T
In Scala at least "=> T" is the syntax for a lazy T (i.e. a function of no arguments that returns T), and so your "hello" reads like a function that returns a lazy String.


Congratulations on this release.

I see with Project Rider, JetBrains clear strategy to support major platforms - JVM, Native, Web, CLR.

Is there a CLR backend planned for Kotlin ?


The Kotlin team does not have any near-term plans to work on the CLR backend. However, there are people at JetBrains who want one, so it's possible that it will appear at some point in the future.


It would make a great portable language between Android and Windows Store, removing the need to touch JNI in Android like we are currently forced to do for any major OS APIS via C++.


request: a dex of the compiler and any needed jars, so you can compile on an android device.


Must admit I wish Jetbrains just contributed more of their time on existing open source languages instead of creating a complete new one. There is enough languages out there and this is one more thing i wont have time to look at :)

Congrats though well done on release.


Mostly Kotlin brings a real alternative to Android. The other languages either don't run on JVM or are somehow else unsuitable, such as due to unacceptable startup times.

It's almost like Kotlin was designed for Android to bring new life to its ancient Java version.


> Talking about [Kotlin] lines of code, the number of these in open repositories on GitHub is growing exponentially over time.

This could also mean you've designed a verbose and turgid language. A better metric might be # of projects using Kotlin. (For the record, I'm actually really excited about using Kotlin, I just found it somewhat hilarious to boast about exponential growth of LOC.)




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact

Search: