I tried Kotlin during the Surprise Language round of Codeforces, a programming competition.
I found it to be more verbose than a typical modern scripting language. Maybe it's the result of choosing the least of the evils for what it's trying to accomplish.
The other drawback: the documentation. Kotlin's reference documentation (looking up how to properly use a call) does not have any examples. I'm not even talking about full compilable examples - although that would be nice, it doesn't even have one-liner examples. FWIW, I was trying to look up how to use a comparator to sort a MutableArray<Int,Int>.
Personally I don't much mind the added verbosity, coming from Ruby/Python/JS, so long as I don't have to write so many damn tests. Speaking from minimal experience, Kotlin still seems like a big net win here. Same is true of other languages with lightweight, static type systems like TypeScript/Flow, Swift, and Go.
I agree about the documentation – I think it's one of the biggest reasons the language has seen such little adoption given its benefits.
I couldn't even find how to integrate Kotlin files into a Java project without using IntelliJ. Kotlin is developed by Jetbrains, so of course they're used to IDE-driven-development, and have a financial stake in people using their products for development. But coming from scripting languages, this sort of documentation gap was a real turn-off for me.
The compiler guarantees it won't happen. Such a test would be a test of the compiler and in my opinion unnecessary. And in Haskell at least... impossible. You can't write the the test because IT won't compile!
> I couldn't even find how to integrate Kotlin files into a Java project without using IntelliJ.
I would suggest (and I'm not trying to bag on you with this) that this concern is more your unfamiliarity with the JVM than a failure of Kotlin, which is generally targeting Java and Scala developers. Kotlin operates pretty idiomatically in the Java universe and, as an experienced JVM developer who's comfortable with all of Maven, Gradle, and SBT, I dropped Kotlin into a Maven project, side-by-side with Java, with a cursory glance at the documentation--"oh, it's another pre-compile-step thing". (Which I then consume via IntelliJ, because IntelliJ imports Maven projects nicely, but Maven allows others to use their IDE of choice.)
The pre-compile-step thing sucks, I'll be the first to say that, and it's a problem with multi-language, multi-compiler projects that none of the major build systems on the JVM really handle admirably. I prefer to use multi-module Maven projects and separate out Java and Kotlin--or Scala, for that matter--code into separate ones. But that's a different beast entirely from the initial bootstrap when learning.
> a problem with multi-language, multi-compiler projects that none of the major build systems on the JVM really handle admirably
A bummer to hear – though I'm glad it's not just me. I tried using Kotlin with the Play Framework and did not have a great time. The hot-reloading features of Play didn't work with Kotlin at all, even with my attempts to `touch` a Java file whenever my Kotlin file changed (presumably they're recompiling more intelligently than I was).
Perhaps having SomeController.java and SomeController.kt in parallel, where the former imports the latter, and receives a `touch` or similar whenever the Kotlin file changes, might work? Or would you recon such a project to be a fool's errand?
Play isn't built for Kotlin and SBT is kind of a tire fire in general. I would suggest something more like Dropwizard for use with non-Scala JVM languages.
I've never used Spring Boot - feel like plugging it a little? Dropwizard is the de facto in my neck of the woods, but I'm always looking for an improvement.
What sort of tests don't you end up writing? I ask because I work in both dynamic and static languages, and find myself writing very similiar tests in each case.
Tests that verify the behavior of functions when they are passed data of a type that does not support the behavior that the function expects to be supported. I find this to be a very common case.
The underlying idea is that it shouldn't handle the wrong type at all, it should fail.
If some function A calls function B with a wrong type, the problem is with function A. So basically, there should be only type tests after IO functions (probably after parsing), the rest can be assertions.
At some point you have to assume something is there and correct (e.g., you don't write tests to check whether the tests are there, also you assume the testing tools work, ...).
In static languages you also assume the programmer set the right type for the function argument, so you might as well assume to have an assertion in the critical code of the functional languages.
> At some point you have to assume something is there and correct
If you excel at compositional design then this may work OK but a lot of code bases I have worked on just need a good ol' refactor to sort the mess out. And then the "there and correct" part could fail due to human error, or the new person not knowing the old assumptions etc. The asserts are a step in the right direction in documenting the assumptions though. Types go one level better by both documenting the interface, and enforcing that contract at compile time.
Do you need a test to verify that your compiler correctly checks the type signature? (Actually, that could be occasionally useful in the face of implicit conversions)
You can't get true 100% coverage* on digital hardware. (on quantum maybe!) so what to test or not is always a judgement call. Most of the time I'd assume the software stack is trustworthy but if you are doing something extreme you may want to test the compiler or even formally prove the compiler works as expected.
* true as in all possible inputs and outputs rather than merely all code paths
For sure, and if you're someone who loves runtime assertions for type mis-matches, then I think you'd really love static type assertions, which are basically the same thing, but checked earlier, making bugs they find cheaper.
I agree that writing specific tests for that is very inefficient, and that few people (myself included) actually do it. I just also think the fact that people don't really write tests for a (anecdotally) common cause of bugs, and instead wait to see them in their production logs, is an anti-pattern, rather than a positive thing.
I find this to be a rare case. Of course, YMMV. But I don't see or write tests in dynamic languages that verify behavior when I pass an inappropriate type. I trust that it'll produce an error when it tries to use operations that the type doesn't support.
Maybe I'm misunderstanding you, but it sounds like you mean that you trust it to produce that error when it's running (ie. in production). If that's the case, couldn't you do the same for all kinds of bugs and not bother writing tests at all? Put another way, what is different from this class of bug, which you don't think is worth testing, and other classes of bugs, which it sounds like you do?
I want the function to fail when it is passed the wrong arguments, but I don't really care about how exactly it fails. If the wrong types get passed to a function, I'm already screwed and there's no way to do the right thing at that point. I only care that I get enough information to debug what happened.
In pretty much any other case, I want to function return some precise value or do some precise action. These are situations that the code will encounter during normal execution, and so I do care about what exactly it does.
You might find https://spin.atomicobject.com/2014/12/09/typed-language-tdd-... enlightening (note that in modern typed languages there's a lot less overhead to using type technique than there is in Java - but even in Java you can do some of this stuff)
Can you actually give an example of a test that would be realistically written in a dynamic language that would be something encoded into the types of values?
You give me an example of a test that would realistically be written in a dynamic language then. I've been out of dynamic languages for so long that I've forgotten how to produce working code in them (seriously, I tried to write some Django because I used to be quite good at it and it seemed like a good fit for a specific problem, and I just wrote code that had stupid bugs everywhere).
Here's a test I wrote recently. The code in question is part of a nodejs service that talks to a database and produces json objects to be used by a web client application.
There is a definition for the schema to a fruit table.
Fruit: {
list_id: 32
}
The list_id indicates that this isn't a real table, but is actually stored in the list_options table. So my code has to generate a different query then for a normal table.
Ok, good example on some levels, though it's doing a lot of interfacing with untyped parts. In a real-world scenario I would be looking to extend the type safety by using thrift or similar rather than json, and ideally a strongly typed datastore (for a static list like this, probably plain old code rather than a database).
That aside, what pieces could actually go wrong in a statically typed language? You can't typo field names or the like. You could typo the names, but I don't believe typing them into the computer twice adds value - better to check them once in code review. People aren't going to be editing this code in a way that could lead to getting the names wrong.
You couldn't go down the wrong code path and end up with the "normal table" query, because having list_id instead of something else is part of the type. You couldn't pass some other number as the list id, because list ID is a typed thing that is different from all other IDs, and in any case where would an outside number come from? And you're definitely going to return a response that's formatted with a record list, because that's part of the type of the method. (You might need to test the JSON <-> String piece, but that's generic, so you only need an O(1) test for that, you don't have to test every JSON endpoint. In practice you're likely using an existing well-tested library. Similar reasoning applies to the database querying part). Assuming you have warn-for-unused-parameters enabled, you couldn't forget to apply the criterion and just return everything in the list.
So yeah, assuming this was for part of an existing system where I'd already tested generic facilities like database access and JSON serialization, I wouldn't feel the need to write this test at all.
> So yeah, assuming this was for part of an existing system where I'd already tested generic facilities like database access and JSON serialization, I wouldn't feel the need to write this test at all.
But this is the generic facility for database access. This is just an additional special case it has to handle. Does that change your perspective on whether you would write a test for it?
> That aside, what pieces could actually go wrong in a statically typed language?
Well, I could type the SQL wrong, but let's assume we are working in a sufficiently awesome statically typed language that would catch that kind of error.
I could filter on the wrong column, with the wrong operator, with the wrong value, on the wrong table. I could decode the name column using the wrong encoding. I could return multiple rows per option. I could do a huge number of other things that I couldn't think of. These may not be really likely to be mistakes I'd make (this is a pretty simple task), but several refactorings down the line, I can easily see an issue being introduced.
At the end of the day, even in a statically typed language where much of the functionality would be verified by the compiler, I'd still like to have a test on this.
> Ok, good example on some levels, though it's doing a lot of interfacing with untyped parts
Hmm... the fact that it deals with the boundary of the system and the fact that it deals only with converting data from one format to another might render it a poor sample (i.e. there's not really much interesting logic). I can come up with another if you are interested.
> But this is the generic facility for database access. This is just an additional special case it has to handle.
Presumably it would be using a lower layer - or more likely an existing library - for doing the actual query though?
> I could filter on the wrong column,
Not if you've got a typed representation of which column's which
> with the wrong operator,
Not if equality is the only operator available. This is one of my biggest reasons for using wrapper types around IDs - you shouldn't treat IDs as integers, because the idea of adding or multiplying or <=ing an ID makes no sense.
> with the wrong value,
How? You have to use the passed ID for something, and it can't do anything else.
> on the wrong table.
So make the table part of the type. A list ID is a different thing from a user ID, they shouldn't be compatible.
> I could decode the name column using the wrong encoding.
Encoding should absolutely be handled with types.
> I could return multiple rows per option.
Hmm, maybe. But I can't see how you'd do that by accident.
> At the end of the day, even in a statically typed language where much of the functionality would be verified by the compiler, I'd still like to have a test on this.
I started out thinking the same thing (I moved from Java/Python to Scala). I've gradually reduced the amount of tests I write over four years as I've found them to not add value. I was as surprised as anyone, and even privately entertained the thought that maybe I was some kind of super-programmer who was smarter than all those people who needed tests, but that month or two of trying to do stuff in Django made it very clear that it wasn't me, it was the language.
> Hmm... the fact that it deals with the boundary of the system and the fact that it deals only with converting data from one format to another might render it a poor sample (i.e. there's not really much interesting logic). I can come up with another if you are interested.
Yeah, happy to if you're interested. It's a useful exercise in thinking it through for myself as much as anything.
> I started out thinking the same thing (I moved from Java/Python to Scala).
Ah, Scala. I could be prepared to believe that this is true for Scala (and similarly advanced typed systems). It is when people claim they write fewer tests in java than in python that I found it really dubious.
> Yeah, happy to if you're interested. It's a useful exercise in thinking it through for myself as much as anything.
Ok here's another test:
These are action objects, they represent a sequence of user actions on a JobExtra.
Yep. Ensuring something is valid is a great fit for use of types - you make sure that the type is inherently valid and it's impossible to construct in an invalid state.
For 1., you could have a non-zero number type, or you could settle for a check in the JobExtra constructor. For 2., it sounds like this is a coproduct situation - a JobExtra is either certifiedFormanRelated or has an appliedPercentage. Scala doesn't quite have native support for coproducts the way it does for tuples, but you could represent it with a sealed class hierarchy:
sealed trait ForemanOrPercentage
case class ForemanRelated() extends ForemanOrPercentage
case class AppliedPercentage(value: Decimal) extends ForemanOrPercentage
or being a bit lazier you could just use an Option[Decimal] and say that if it's Some it's the applied percentage and if it's None then it's certified foreman related.
In Java there isn't a "sealed" keyword, but you can emulate it with the visitor pattern - you'd define a ForemanOrPercentageVisitor and only ever operate on ForemanOrPercentages via the visitor. That way if someone creates their own subtype of ForemanOrPercentage it still has to behave like one or the other, because they still have to implement visit().
Since the user input modifies this object, the user can put the object into an invalid state. In fact, when the object is first created it is in an invalid state. So I can't simply define my types so that invalid state is impossible.
If your object has distinct possible states, maybe it should be two different objects. I don't think of user input as modifying my object (after all, this kind of object should be an immutable value) - rather I think of mapping my object to a set of form fields and mapping a set of form fields into a new object. (This goes well with having a component hierarchy model - just as my object is a value made of simpler values, its corresponding editor form is made of simpler editor forms). So I'd only create the (domain-level) object when the user's provided the right input to create the object. If you need a model of the user input in code, that's fine, but make that its own distinct type - then you have a single point at which to do validation, and the types make it very clear whether a given value is a business object (in which case it is necessarily valid) or unvalidated user input.
That's very interesting, and shows how types can go much further then what we see in languages like Java. I'll have to try out one of these languages some day and see how well it works in practice.
Even in Java it's possible (but it's not a great environment to learn these techniques in - they usually end up being very verbose when expressed in Java) .
If you always declare object fields as final then you're forced to initialize them in the constructor, so there's no risk of null there. Reading a field in the constructor should be a red flag, as should literal null in your code. Local variables should of course be final too. At that point you only need to check for null around library calls. I'm not sure how much a test actually helps with that - if you don't think of the possibility that a library call might return null then you wouldn't write a test for it either, if you do think of it then you wrap the call in a null test in the same line (don't try to get clever and store possibly-null values in variables).
> if you don't think of the possibility that a library call might return null then you wouldn't write a test for it either
No, I don't think so. I'll write a test that uses the library. If the library returns null when I don't expect it, it'll go into my code an cause an exception to tbe thrown. I'm not deliberately testing for nulls, I'm testing generally that my code does what I think it does.
> No, I don't think so. I'll write a test that uses the library. If the library returns null when I don't expect it, it'll go into my code an cause an exception to tbe thrown. I'm not deliberately testing for nulls, I'm testing generally that my code does what I think it does.
The kind of library function that returns null doesn't usually return it on the "happy path", it usually returns null for some weird condition you haven't thought of. I mean, if it's a function that returns null often or that you'd expect to sometimes return null, you'll wrap up the return value in an option straight away even without having written a test. The kind of library function that causes you to get exceptions in production is the kind that returns null in some weird corner case - but unless you think of the weird corner case, you wouldn't hit it in a test either.
If I was using a library with some complex stateful interface I might write tests for the interaction with that (I'd probably put a facade on it, keeping it separate from the business logic, and the facade would have unit tests) - but I'd try to avoid using such a library. And I'll always have a few high-level end-to-end tests (not really "unit" tests) as a basic "does it work at all", because that kind of mistake is easy to make. But the bread-and-butter unit tests that I wrote when I worked in Python just don't seem valuable or necessary.
I think you are assuming saner code then I'm used to.
Honestly, I can't say how it would work if I was using a java code base that consistently applied these kinds of ideas. You may be right, but at this point I have hard time believing.
I've worked on some bad codebases. You can convert a little bit at a time, treating the remainder of the codebase as a large library with a poorly factored interface. You absolutely will need unit test coverage at the boundary, which will probably exist for several years.
Absolutely. Dynamic languages only seem terse because you don't see all the associated test code inline. I've been programming in a mix of dynamic and statically typed languages for more than 15 years now and I'll take a modern statically typed language over a dynamic language any time if I have my choice.
It's a lot harder to design a static type system that's both expressive enough to be pleasant to use and strict enough to be useful. But we're getting there in modern languages like Rust, Kotlin, Swift etc.
"integrate Kotlin files into a Java project without using IntelliJ" - compilation of a mixed project is not a trivial tasks, many things must be set up. A detailed description of this takes a chapter in a book.
From what I understand Kotlin is the language that was designed to be used in house by JetBrains to simplify their Java code. It wasn't born to be the revolutionary, just practical for Java developers.
The Kotlin reference is not supposed to be used for finding methods.
The way to go is to use auto completion in an IDE. If you type `myArray.sort<ctrl+space>`, you get all one needs, including `sort`, `sorted`, `sortBy` (which you needed).
The docs are arranged in a way that one reads them in the order they are written (at least the first half). I supposed that would take more than half an hour given at the competition.
I don't think Kotlin is the best choice for programming challenges like codeforces - they really don't let him shine (although I use it whenever I can). But if this is a valid case, we can collaborate and write a short tutorial for C/C++ to Kotlin programmers.
I really liked Scala when I played around with it (bare with me here), but when deciding on what to use on a project I'm starting, targeting the JVM is a downside. Can I depend on the JVM being on the target machine? If not, I'll have to deal with the dependency. However, if I choose a compiled language like Rust, I don't have to worry about that.
Most people writing Java will be able to control the presence of the JVM. Only B2C desktop apps, which are fairly rare these days, will have to worry much about the dependency.
Under what circumstances are you writing software for deployment in places you don't have administration access on (i.e., your servers, which should be deployed with CM as-is and make adding dependencies trivial) where you cannot package OpenJDK (this is trivial on Windows, OS X, and Linux), cannot expect a system administrator to install the JVM, and can expect Rust to run?
There is a slice of the universe where this exists, but it's not really Kotlin's target in the first place (and I think that's basically self-evident from everything around it) so I'm not sure why you'd try to jam that square peg in the round hole to begin with.
You just package the JVM with the application itself. Create a .bat/.exe/.sh/binary file that calls the JVM with your program as the argument. It's simple, but it will increase the download size of your program significantly (unless your program is huge - then it doesn't matter)
Wow!I don't like the JVM and I'm a rust fan... But you've touched a nerve here, this is my biggest disappointment with rust. The JVM runs on A LOT more platforms than LLVM currently supports!
Scala native exists, and is probably a similar overall maturity to Rust (scala native itself is newer, but much of the ecosystem has been around longer).
(Why are you running things on uncontrolled machines? Don't you have puppet or the like set up so that every machine has whatever it needs to run whatever you put there?)
As far as I know, all CoffeeScript did was add bunch of syntactic sugar on top of JavaScript.
I believe Kotlin actually adds programming paradigm that's not in Java on top of terse syntax, i.e. real closure, operator overloading, pure object orientation, and more.
And also may become obsolete after Java 8/9 (as Coffeescript after ES6/7). Problem is that noone in Java body shops ever touched Java 8, they're still migrating from Java 5 to Java 6.
I am a bit in a hurry, so I acknowledge I only quickly scanned the article. But it struck me as damning by faint praise.
Like a waiter advising, "Choose the chicken parm. It doesn't have any bones, all the salmonella has been cooked out, and it doesn't have any bad flavor."
If I'm going to be successfully pitched a programming language, I will need to see its power of expression or be shown how it solves some problems that other languages don't address well. Some "special sauce."
No offense intended ... that's just my quick take.
> If I'm going to be successfully pitched a programming language, I will need to see its power of expression or be shown how it solves some problems that other languages don't address well. Some "special sauce."
I think that is wrong approach. Kotlin has nothing special or innovative, everything was already here. But it is well balanced and industrial strength (something like java). It is simply good workhorse for most tasks. It is excellent replacement for java, that is all.
Now that JDK8 has made Java more expressive, and Oracle's trolling has come to nothing, I expect Kotlin and Ceylon to fade away. If you want Java, just use it, already.
Java 8 improved things, but it's still far behind the rest. Also, both Kotlin and Ceylon (and Scala and Clojure) would be affected by the Oracle trolling, since they all run on the JVM.
I think that might be what's needed for a really good programming language. If you want a general-purpose language, you probably don't want something unique and envelope-pushing - you just want a language that avoids all the mistakes that are so common, that learns from what's gone before. Like buying a table - you usually don't want a radical table that can do something other tables can't, you just want a good solid table.
(I don't think Kotlin is such a language - I think Ceylon might be. I work in Scala at the moment)
* Null-handling in Ceylon falls out naturally from union types. Null handling in Kotlin is a hacky special case with a bunch of specific operators. In particular this means it's impossible to write a method in Kotlin that works with both traditional nullable values and Optionals, which will make interop a lot worse as the Java ecosystem adopts Optionals.
* Ceylon has actually listened to the lessons of Scala tuples and built theirs the way ours should have been all along (HLists), making them much easier to abstract over. (NB not actually an issue in Scala in practice - you import Shapeless and then everything works the way it should - but it's nicer to have the right thing by default, as will hopefully be the case in Scala 3.x)
* Ceylon has higher-kinded type support done right - multiple parameter lists to avoid Scala's unification issues that lead to the use of "type lambdas" (hopefully fixed in Scala 2.12).
Kotlin simply doesn't support higher-kinded types; combined with the lack of union types this means magical annotations with bytecode manipulation where suddenly the code you wrote isn't the code that runs, because just like Java that's the only way to do a lot of things in Kotlin. Async is a special case with language-level dedicated support code. Error handling is done solely through unchecked exceptions which is fine for system failures but not a good way to handle "expected" failures like input validation.
It is interesting that when I considered next language to write a side-project in, I was choosing between Ceylon and Kotlin.
In the end I did choose Kotlin. My reasons included:
* support in IDEA
* focus on java interoperability
* nice interop with android
but the main thing probably was, that I trust JetBrains that they will support Kotlin in the long term, while I don't think RedHat has any projects depending on the language.
Well in reality I choose Scala, largely because it has a level of maturity and ecosystem support (both libraries and other tools) that neither Ceylon nor Kotlin can match. But I'd use Ceylon rather than Kotlin because I think it's a much better designed actual language (see cousin post for examples). I personally dislike IDEA (prefer Eclipse), and I don't think Kotlin actually has any better Java or android interop than Ceylon (or Scala), they just make more of a fuss about it in their marketing.
>Like a waiter advising, "Choose the chicken parm. It doesn't have any bones, all the salmonella has been cooked out, and it doesn't have any bad flavor."
I'd blame the author for this. He's obviously not a salesperson. To me it seems more like he's a coder who found a new-ish language and he's happy that it solves some of his problems that he's encountered.
>If I'm going to be successfully pitched a programming language, I will need to see its power of expression or be shown how it solves some problems that other languages don't address well. Some "special sauce."
For me this was pretty open/shut. Kotlin usage appears to rely upon a lot of side projects. I rarely find that beneficial. Too many cooks.
I had never heard of Kotlin before, despite reading Hacker News daily and otherwise being generally plugged-in to programming discussion on the Internet. So for many people this will be their first introduction to the language.
Are there any decent languages that compile to readable Java? I think such a language would have a place in conservative Java shops, where management insists "we only use plain old Java around here". You could program in a "cleaner Java" translate it to vanilla Java, then commit, and nobody would know the difference.
> Linj is a Common Lisp-like language that tries to be as similar to Common Lisp as possible but allowing Linj programs to be compiled into human-readable Java code
If you ever tried to push some Java-generated code in the repository I will never ever approve your pull request.
It's simply one of the most wrong thing that you can do on so many levels that I really don't know from where to start.
You will need to keep track separately of the kotlin code and Java code and keep them in synch.
You cannot use the repository because, per your admission, you are doing this in secret, so if your machine dies then you lose all the original kotlin code.
Even if you didn't lose the original kotlin source future iterations of the language may change the generated code, so even if you simply remove a comment your pull request will have changes in pretty much all the generated files.
A simple refactoring can have similar effects.
Generated Java code in my experience can be spotted immediately given that usually is very verbose.
I simply can't imagine what huge amount of code that thing will generate for a simple one liner using streams, given that it's targeting Java 6.
Probably there are many more other reasons that I cannot think of early in the morning.
Last but not least, I'd rather never work with someone that tries to deceive all his colleagues and pushes in the repository awful code.
If you don't want to use Java then find another job, nobody is forcing you to work there.
Yes. At one job my predecessor had done significant work in Java and somehow the only the compiled files were left behind. We reverse compiled them and that was my starting point for the project. As you can imaging the generated code was perfectly formated, with a very consistent style, and generic variable names. It wasn't terrible to work with.
The language I'm proposing probably couldn't be too different than Java. But one trivial example would be to make all variables final by default unless they were marked "notfinal". This would be different than Java, and thus would be a new language. And it would be trivial to translate back and forth between this language and Java. Nobody could ever tell the difference. Granted all you would really be changing is syntax, which may or may not be worth while.
I see the biggest market for Kotlin being Android. It manages to provide features that Java will likely never have while still having a fairly small impact on run time, deploy, and APK size. The conversion tool is really great too. It makes it much easier to migrate a project to kotlin, especially when trying to figure out more complex stuff like annotations. I see Kotlin being Android's Swift in the future.
I would love to see that happen (or something similar, like Swift).
I fear that it will be hard to move in that direction as long as Google does not push in that direction though.
The official word is that we don't need their support in order to write Android apps in Kotlin, which is true and that the gap between objC and Swift was large enough to justify the change but that Java is not that old, which is debatable.
In all cases, it is hard to argument the move to a new language in an existing codebase when there is no official push in that direction.
If I have to create a new app in the near future, I will strongly consider Kotlin, but for the 8 eight old codebase I have to deal with + the 15 engineers working on it, my hands are tied.
> In all cases, it is hard to argument the move to a new language in an existing codebase when there is no official push in that direction.
I don't understand the logic behind this sentence? Why do you need Google to push you somewhere instead of you youself choosing a more productive option?
Kotlin is designed to be easy to integrate into existing Java codebase and our introduction to a largeish Android codebase has been a great success.
For a personal project or for creating a new app from scratch where I am lead engineer, sure Kotlin would be an easy choice.
However, right now I am a senior engineer working on a 8 years old android app alongside 15 other Android devs.
The switch to another language is not even something that the current lead or the CTO are willing to consider.
In their defense, we would have to train the whole team, this would be a major task and build times are already a big issue so anything degrading them is hard to push for.
A push from Google would help a lot, it would remove a lot of objections like "this is hipster shit" or "I am not going to learn the language of the month" (coming from people who have not learned any language in years) and force them to take it seriously.
Even the iOS team barely use Swift though, so I don't see it in a near future.
I guess I just have to search for another company.
> our introduction to a largeish Android codebase has been a great success.
Do you mind sharing some details ?
> Kotlin comes from industry, not academia. It solves problems faced by working programmers today. As an example, the type system helps you avoid null pointer exceptions.
I'm sorry but you just undercut your own anti-intellectualism better than I could right there.
(There exist languages which have guarded against this without loss of expressive power since before Java and, oh, are from academia.)
A better example of 'engineering not academy' would be explicit vectorization, memory layout support and a good FFI. (all the stuff that in theory is better managed by compilers, in practice it either doesn't matter at all or else should be left to humans).
Please correct me if I'm wrong, but Kotlin doesn't improve on Java in these areas.
It would be awesome if there would be some JVM language that supported explicit vectorization, memory layout support and a good FFI. But it also seems impossible. How would any JVM language have memory layout support while at the same time running in the memory managed sandbox of the JVM?
Despite its young age it creates really fast, tight code (they have issues benchmarking things because Dotty Linker + LLVM gets rid of too much stuff).
Indeed this is more an aspect inspired by academia
the point would have been better made by pointing out the excellent and extensive tooling built by jetbrains for kotlin. that's something the maker of the intellij platform has more experience with than academics
Also there is a tradeoff between advanced language features and good tooling, which is why you will sometimes miss the former inside kotlin
The reason they disavow academia is not because there is anything wrong with academia but to make a contrast with their closest competitor, Scala. It's a subtle way of saying "we may look like Scala, because like Scala we are a better Java, but the difference is we are actually useful in the real world. "
Sometimes I think I should change that paragraph because it too often gets interpreted as generically anti-academia, which then triggers people who think I'm anti-intellectual.
Note the very important part of that statement: It solves problems faced by working programmers today.
Academic PL research can have that property. Pizza went on to be the foundation of Java generics, there's a ton of excellent compiler and GC theory that comes from academic research and so on. And of course a few of the ideas in Haskell and others are leaking into the mainstream.
But when it comes to handling null pointer errors, sorry, it's insufficient to say "some languages popular in academia don't have null". So what? Working programmers today hardly use such languages. They very much rely on languages which do have nulls, and APIs which use them, and yet the only language that came out of academia in recent times which has serious production usage is Scala, which has ... nothing to say on the topic. Except, oh, an option type. Which can also be null, and which even C programmers can easily have. It's simply not comparable to language integrated support with backwards compatibility.
It would have been nice if academic research had identified up front the best set of usability tradeoffs for adding optionality into a backwards compatible language, but nobody did, so JetBrains had to do it themselves.
A few? Don't you feel like you're underselling the impact Haskell had had on other languages?
> he only language that came out of academia in recent times which has serious production usage is Scala,
What are your qualifications for serious production usage? Would ocaml count by your standards? Haskell also has increasing production usage, though I'm sure you don't count it. Swift (if you don't count it now, you will)? Rust?
> It would have been nice if academic research had identified up front the best set of usability tradeoffs for adding optionality into a backwards compatible language,
That's not enough. It would have to be more convenient to use optionals than null or programmers in that language would have to be convinced optionals are better.
In an existing language that uses null pervasively, it would be hard to get a critical mass of legacy code which uses optional.
Not really, to be honest. Haskell gets hype well out of proportion to its real impact.
What are the key ideas that make Haskell unique? I'd say they are pure functional by default, lazyness by default, an extremely terse syntax that relies heavily on symbols, effects in the type system, type classes, and a few other smaller things. As a non-Haskell expert at least, these are the ideas I associate with the language.
Writing code in a more functional style is steadily becoming more popular, but functional by default does not seem to be the choice of any modern language targeted at the mainstream. Swift, Rust, Kotlin, Ceylon, Go are all examples of industrial languages developed outside of academia that do not follow this design choice, and their functional programming support primarily consists of map/filter/fold/etc type methods on collections and sometimes (as with Kotlin/Java) a lazy sequences library. Meanwhilst, whilst often convenient and intuitively helpful, the evidence that fully pure functional code is of much higher quality than mixed or mostly imperative code is ... lacking. Certainly it's difficult to get clear evidence without controlling for other factors like experience of the programmers.
Lazyness by default is an equally un-influential choice. It seems Idris is the newest cutting edge academic pure FP language and it's strict by default. Lazyness by default creates an entirely new class of bugs that developers didn't have to think about before, for little obvious benefit (it lets you write in a certain style more easily, but does that style really give better software? again, it's difficult to get robust data on this).
The extremely terse syntax that relies heavily on symbolic operators is widely regarded as a bad choice. Modern industrial languages like the ones I named have all shunned this type of design and Kotlin, for instance, doesn't let you define arbitrary new operators. Haskell code is often rendered much harder to read than necessary due to its abuse of symbolic operators.
Effects in the type system do feel nice, but the impact of this idea has likewise been limited. You could argue that Rust's borrow checker is perhaps somehow inspired by this, although it's sufficiently different that I'd describe it as original work rather than idea that comes from Haskell. Other languages haven't focused on it so much.
I suspect the next idea to cross over from Haskell will be type classes, or a variant of them. But probably as an obscure feature not many people use, rather than a fundamental building block as in Haskell.
All in all, given the level of attention Haskell has received for many years, I feel its ideas have had surprisingly little impact.
With respect to "serious production usage", that was obviously a lax description. As far as I know there's much more usage of Scala in the non-academic world than O'Caml or Haskell, but it's still quite a small amount relative to languages like Python or Java. I don't have any specific thresholds, it was an intuitive description.
> In an existing language that uses null pervasively, it would be hard to get a critical mass of legacy code which uses optional.
Exactly, but that's what Kotlin is trying to do through its auto-convert from Java to Kotlin, the backwards compatible type system, support for nullity annotations and so on. It's got the closest yet.
>Kotlin costs nothing to adopt! It’s open source, but that’s not what I mean here. What I mean is there’s a high quality, one-click Java to Kotlin converter tool, and a strong focus on Java binary compatibility.
The costs of adopting a new language are greatly more significant than implied here. The time it takes to learn it. The time it turns to learn the tools that are specific to it. And if you put it into production, the technical debt you've created by adding another language to the codebase, etc.
If the OP had said that you don't have to start a green-field project to use it, that would be more accurate.
My experience has been that the learning curve for Kotlin is extremely shallow if you're an experienced Java developer. This is not just my experience but also the experience of building a team that's working with Kotlin all day.
One reason the cost is low, is that there aren't really many tools specific to Kotlin (or any, really). You can use the same IDEs, the same build toolchains, the same libraries, even the same standard library as regular Java.
Upvoted you, but adding on: a competent Java developer can pick up Kotlin in, literally, three hours. The mappings to Java concepts are trivial, but the language's niceties quickly bear themselves out as you go.
Scala is still there, still growing, and a much better language. Kotlin is founded on this anti-intellectual rejection of Scala's advanced features... only to then add them back in piecemeal. So rather than a single powerful general feature like implicits or higher-kinded types you have language-level special cases like extension methods and specific nullness operators.
(Don't get me wrong, there are plenty of things Scala would do differently if it were made today - there's space for a language like Ceylon that makes a genuine effort to simplify on what's in Scala)
Anti-intellectual? More like complexity, let's be honest about motives here: it isn't "we hate types" it is "I have no idea what is going on here anymore." The "start over again and try do it right this time" is quite pervasive in PL, and even if it keeps on leading to the same problem, the motivation is always well meaning.
The line about "Kotlin comes from industry, not academia. It solves problems faced by working programmers today." is pretty naked anti-intellectualism IMO.
You have a lower standard for anti-intellectualism than I do, I guess. From wiki:
> Anti-intellectualism is hostility towards and mistrust of intellect, intellectuals, and intellectual pursuits, usually expressed as the derision of education, philosophy, literature, art, and science, as impractical and contemptible. ... In public discourse, anti-intellectuals are usually perceived and publicly present themselves as champions of the common folk—populists against political elitism and academic elitism—proposing that the educated are a social class detached from the everyday concerns of the majority, and that they dominate political discourse and higher education.
The above sentence fails that test, it merely states its roots and goals can be different from academic pursuits. And it is mostly correct: at best academic work is focused on tomorrow, not today..and at worst it is focused on today but should be focused on tomorrow.
The implication is that languages with academic involvement do not solve problems faced by working programmers today (otherwise it would make no sense to list this as a reason to use Kotlin) - very much derision of [academia] as impractical. I would say that the majority of academic work on programming is and should be focused on problems faced by working programmers today - simply because we have an ample supply of such problems. I guess theoretically I can imagine there being valuable academic work done on problems that working programmers weren't yet facing but were expected to face in the future, but I can't actually think of any examples of such work - certainly not examples that have made it into any language that could reasonably be thought of as a competitor to Kotlin.
> Scala is still there, still growing, and a much better language. Kotlin is founded on this anti-intellectual rejection of Scala's advanced features...
Each time someone brings up Scala there comes this weird "people who don't like it are anti-intellectual" - well no, people don't like it because it looks weird, had for the longest time abyssimal IDE support, tries to do things which have been solved in production by itself (see SBT vs Maven) and is a mishmash of more or less every idea that was floating around mixed into one language.
Kotlin has a very specific focus: Being usable for a working Java programmer, who doesn't have three years to learn every weird idea Scala tries to shove down your throat. It uses existing tools, existing Java collections and enhances them instead of saying "well, we do everything new, because we know how to do it 'better' and we don't care for your existing code."
Ultimately, you don't need to learn every single Scala feature to get started using it. As a Java developer you only need to learn a few differences before you can start using it as a "Java with better syntax" (var/val/def, static/object, Object/AnyRef, void/Unit, interface/trait, <>/[], []/()), learning the Scalaisms later on as you go.
You don't need Scalaz to write Scala code. You can even ignore most of the standard library while you're starting out, and use the Java equivalents.
SBT might seem pointless at first, but the same thing applies there. You don't need to use it, plugins for Maven and Gradle are available. But once you do switch, you'll see how much nicer it is.
> Each time someone brings up Scala there comes this weird "people who don't like it are anti-intellectual"
The whole "Kotlin comes from industry, not academia. It solves problems faced by working programmers today." is pretty clearly anti-intellectual. I come from industry, not academia, and the Scala type system solves problems I face as a working programmer every day that I couldn't solve in Kotlin (or any other language without higher-kinded types), thank you very much.
> people don't like it because it looks weird
Weird how? I find it looks very much like Python or Ruby.
> had for the longest time abyssimal IDE support
Shrug. Not my experience.
> tries to do things which have been solved in production by itself (see SBT vs Maven)
Just ignore that nonsense and use maven.
> and is a mishmash of more or less every idea that was floating around mixed into one language.
Hardly. It's got a small number of powerful features that get out of your way and let libraries get on with it. Kotlin is far more of a mishmash because it has a whole bunch of special-case functions in the language (e.g. special operators for dealing with nulls, rather than just being a language that people can write an optional type in).
> Kotlin has a very specific focus: Being usable for a working Java programmer, who doesn't have three years to learn every weird idea Scala tries to shove down your throat. It uses existing tools, existing Java collections and enhances them instead of saying "well, we do everything new, because we know how to do it 'better' and we don't care for your existing code."
Scala doesn't shove anything down your throat. You can use the Java collections in Scala if you want - I did when getting started - it's just that it's really valuable to have immutable collection types (actually even in pure Java this is true - one of the reasons Guava is used in almost every project is to be able to have ImmutableList etc. types - but it's better if you can do it without having half the class be "throw new MethodNotSupported()").
If Brainfuck had the marketing dollars that Typesafe spent then you would see real-world shipping Brainfuck projects. It wouldn't make Brainfuck a good language.
I don't think marketing comes into it? Companies that I've worked at that have adopted Scala have done so because a) the developers wanted to and/or b) they wanted to use Spark. Kotlin seems to be much more a matter of marketing - I've only spoken to one person who'd heard of Ceylon and preferred Kotlin, and it turned out they worked for Quasar.
When I tried Kotlin some time ago on a side project I wasn't very impressed. To me the problems Kotlin is addressing are not that huge. It feels like having to switch to another language (albeit very similar to Java) just to fix some annoyances is just not worth it.
Maybe prior to Java 8 this would've been more interesting.
I also wonder how much time it will take Kotlin to start benefiting from Java 9 features when that gets released.
Hmm, this does seem like a pretty tasteful design in many ways.
The declaration-site variance for generics is a pretty good idea, but is still inadequate to deal with functional collections. (I use the term "functional" as opposed to simply "immutable": an immutable collection has no update operations at all, while a functional collection has functional update operations: for example, given a set S and an element X, to compute a new set whose elements are those of S together with X (S ∪ {X}). This usage is certainly not universal, but the distinction needs to be drawn somehow.)
Anyway, the point is this. Kotlin has in its collections API
interface Set<out E> ...
where the use of 'out' says that given types A and B where B is a subtype of A, 'Set<B>' is a subtype of 'Set<A>'. But then if you wanted to add a 'with' operation as described above:
interface FunctionalSet<out E> : Set<E> {
fun with(E elt)
}
you can't do it, because type parameters marked with 'out' can't be used for method parameters.
That's an interesting suggestion, but I don't see any indication that Kotlin provides for type lower bounds in generic function constraints. (It does have type upper bounds; see the bottom of this page: http://kotlinlang.org/docs/reference/generics.html).
I've switched from Scala to Kotlin after 8y of Scala. There are some things I miss (e.g. Options and Futures) but Kotlin feels much more focused on real world problems.
And Gradle is so much easier than the monster that is SBT.
Gradle 3.0, due out soon, will provide Kotlin as an alternative language for writing build scripts, so you'll be able to use a single language for development, as you did when you used Scala with SBT.
For me Kotlin is almost a perfect replacement for Java. It has very few drawbacks, but generally it's much better and it's a pleasure to use it. Not to mention solid IDE support. I've used Kotlin in two small projects. One project was completed year ago and now I'm improving it. Kotlin is just awesome when it comes to refactoring or generalising. Much better than Java.
I don't want to compare it to Scala, they target different auditories, IMO. I tried Scala, it's a lovely language, but it's too complex. I had to spend a month before I was able to write a quality code using Scala and I still had a lot of problems reading scala collections source code or even understand scalaz. On the other side I spent one evening reading about Kotlin (awesome and very complete, yet small documentation definitely helps) and I knew the language, could read its standard library and write production-quality code. For me that's a deal breaker.
Yes scala is complex, but your scala code doesnt have to be. The reason that std collection lib and scalaz code is hard to read is their inclination to push the limit of utilizing the advanced scala features to make their usage really easy.
That being said scala is not for one who wants to plateau quickly. It takes years.
The Android community has already adopted it pretty significantly (join the #android Kotlin slack and see for yourself).
And this was done without any official support for Google because... it's not necessary: Kotlin works out of the box. Which is one of Kotlin's strengths.
Do you have any adoption numbers though ? From what I see in the local companies, kotlin is still very rare, except for a couple of startups (which makes them very attractive tbh).
That anecdotal evidence of course and I would love to see a tide change but hard numbers would be an huge help.
Groovy was named by its creator, James Strachan, in 2003. By 2006 (i.e. 10 years ago), he had been managed out and a business sort without technical knowledge had taken over. He's since slowly wrecked Groovy's sexy brand and placed it firmly in the Java camp. I tried reversing the trend with stuff like "grOOvy", and the Groovy grrrrrrowl, Ooooooooo, and Vy (for "victory") but that business person running Groovy skuttled the effort, appearing far more interested in retaining his centralized control over Groovy branding. Groovy's since been handed over to Apache, being run by a 10-member "Project Management Committee", only 4 of which actually do any technical work on Groovy's code base. The other 6, including the "PMC Chair", just do administrative fuss.
With dart news in the past 4 years, the knee-jerk reaction has been that Google will abandon it, which unfortunately means that not much discussion ever went to its merits. Adopting the language has provided a huge productivity boost for me and many other developers, in or outside Google.
Features:
=========
* compiles to Java and Javascript
* null safety (optionality)
* Lean syntax
* Exceptions are unchecked.
* Extension functions let you add methods to classes without modifying their source code.
* Operator overloading
* No macros
* Markdown instead of HTML for your API docs
* Better Java generics.
* Delegation (forwarding methods)
* String interpolation
It seems like a very pragmatic language, aimed at anything above "systems programming" and not suitable for high-performance (scientific) programming. Not many theoretical advancements in programming language design, if any. Too much of a hodge-podge of features. I would say this language may become interesting only if it gets enough traction from a community.
I initially used Kotlin for a project at work, and I would agree that it is underwhelming. Pivotal had announced official support for Kotlin with Spring Boot, which is what motivated me to give it a try. However, there was no support for the @Transactional annotation in Kotlin at the time, so I ended up writing a decent amount of Java anyways. Then there was a compatibility issue with one of our internal libraries, and I had to rewrite all of the controllers in Java. By the time the project was finished, the majority of the code was in Java, and I hadn't really gotten any benefit out of the Kotlin, so I decided to just use Lombok and replace all of the Kotlin code with Java. My builds got about 3 times faster after that because Kotlin seems to have performance issues with Gradle.
As of 1.0 Kotlin has solid Java compatibility, @Transactional definitely shouldn't be an issue. What features are compelling for you in 1.1? They are nice, but generally just a nice sugar. I don't really miss any of those. I suggest you to try it now, if you have a chance.
The @Transactional problem was fixed, I shouldn't have left that out. I had first tried to do this pretty much immediately after the 1.0 release. Async/await is cool, but it's really the idea of adding channels and coroutines that I'm a fan of. We've also generally stopped using that library that didn't work with Kotlin controllers for any new projects, so Kotlin is definitely something I look forward to using again.
I know they don't have the 'production-ready' stamp, but if I were to jump back into the JVM world it would be Frege at this point. It is basically a Haskell on the JVM. It compiles to Java source code, so you can work it in slowly to your real project [1]. You can call Java from Frege, or Frege functions from Java.
ABCL - Armed Bear Common Lisp is another, but Lisp on the JVM instead of Haskell. It's been around for a while, and has become fast for a Lisp on the JVM, though it's not SBCL in speed. It does however support full 32 bit integers on 32 bits sytems compared with SBCL's 29 bits on 32 bit systems due to boxing. Again, not used much in production, although, there are some great testimonials of some cool implementations [2]. I particularly like the Keck telescope code written in Lisp in 1994, ported to ABCL and using Java for some image work and display.
Kotlin is getting rapid adoption in the Android community and is quickly getting the same status as Swift has in the iOS world.
The main reasons for the rapid adoption are:
- It's designed to easily integrate into existing Java codebases. This means that starting to use Kotlin is pretty much a case of adding two Gradle dependencies and source files into `src/kotlin`. Interop with Java is painless and doesn't require any special boxing as opposed to some other languages.
- It's standard library is small (~700KB), which is a stark contrast to Scala and some other JVM languages, which pretty much demand usage of ProGuard while developing due to large method count.
- It's performance characteristics are close to Java and doesn't cause catastrophic GC collection issues like some Clojure code does.
- It has pretty much all the features expected from a modern language (nullability, const values, concise syntax) while still keeping code very readable for people who already know Java. The adoption in our Java codebase has thus been rather painless, since code doesn't do any additional magic you wouldn't expect.
- It compiles code to Java bytecode which runs on Java 6 JVM, which is critical for Android.
- It has first-party support in IntelliJ IDEs, which includes Android Studio itself. The IDE experience is significantly better than Scala or Clojure one and almost on par with Java.
So in short, we got a modern language, which is easy to transition to from Java 6, gives seamless interoperability with existing Java code (you can just start writing Kotlin classes in your Java code base), doesn't add overhead to your Android application and doesn't behave strangely performance-wise. There are still some warts to fix (mostly related to static checkers), but Kotlin has been a huge win for Android world.
The fact that it would have to talk to Android via JNI bridge like C/C++/Go and other languages that don't compile to JVM.
And the fact that there's no standard library outside the Apple world for the language. Adoption of Swift makes pretty much no sense, technologically or politically.
It's a non starter as the main language since it's not JVM based.
As a C/C++ alternative for native development on Android... possibly.
This will be in great part decided by
1) How frustrated native Android developers currently are with C/C++ (I don't have the feeling they are much) and
2) How much resources Apple will dedicate to make Swift viable on Android (hard to imagine they would be that interested helping out the #1 player in that space while their #2 spot is shrinking on a daily basis).
> - It's standard library is small (~700KB), which is a stark contrast to Scala and some other JVM languages, which pretty much demand usage of ProGuard while developing due to large method count.
A Scala Hello World is around 30 kB, it can get more as you keep using more of the standard library, but to be realistic, it's around a few hundred kBs.
Not sure what's the big deal with ProGuard it's just a deployment detail. Compilation seems to be faster with SBT and ProGuard than Java/Kotlin/... without ProGuard.
You seem to know a few bits about Kotlin. I'm not well versed in Java land but why target Java 6 that's been unsupported for the last 3 years? Isn't that a problem?
The author talks a bit about how he ended up back in JVM world when they started on Android dev. I just want to note that Android does not use the JVM but Dalvik (I think it's actually called ART now). Maybe they just meant Android put them back in the world of Java.
184 comments
[ 3.1 ms ] story [ 219 ms ] threadI found it to be more verbose than a typical modern scripting language. Maybe it's the result of choosing the least of the evils for what it's trying to accomplish.
The other drawback: the documentation. Kotlin's reference documentation (looking up how to properly use a call) does not have any examples. I'm not even talking about full compilable examples - although that would be nice, it doesn't even have one-liner examples. FWIW, I was trying to look up how to use a comparator to sort a MutableArray<Int,Int>.
I agree about the documentation – I think it's one of the biggest reasons the language has seen such little adoption given its benefits.
I couldn't even find how to integrate Kotlin files into a Java project without using IntelliJ. Kotlin is developed by Jetbrains, so of course they're used to IDE-driven-development, and have a financial stake in people using their products for development. But coming from scripting languages, this sort of documentation gap was a real turn-off for me.
I would suggest (and I'm not trying to bag on you with this) that this concern is more your unfamiliarity with the JVM than a failure of Kotlin, which is generally targeting Java and Scala developers. Kotlin operates pretty idiomatically in the Java universe and, as an experienced JVM developer who's comfortable with all of Maven, Gradle, and SBT, I dropped Kotlin into a Maven project, side-by-side with Java, with a cursory glance at the documentation--"oh, it's another pre-compile-step thing". (Which I then consume via IntelliJ, because IntelliJ imports Maven projects nicely, but Maven allows others to use their IDE of choice.)
The pre-compile-step thing sucks, I'll be the first to say that, and it's a problem with multi-language, multi-compiler projects that none of the major build systems on the JVM really handle admirably. I prefer to use multi-module Maven projects and separate out Java and Kotlin--or Scala, for that matter--code into separate ones. But that's a different beast entirely from the initial bootstrap when learning.
Correct!
> a problem with multi-language, multi-compiler projects that none of the major build systems on the JVM really handle admirably
A bummer to hear – though I'm glad it's not just me. I tried using Kotlin with the Play Framework and did not have a great time. The hot-reloading features of Play didn't work with Kotlin at all, even with my attempts to `touch` a Java file whenever my Kotlin file changed (presumably they're recompiling more intelligently than I was).
Perhaps having SomeController.java and SomeController.kt in parallel, where the former imports the latter, and receives a `touch` or similar whenever the Kotlin file changes, might work? Or would you recon such a project to be a fool's errand?
Btw, the whole kotlinlang.org is OSS, and you can correct things you don't
Depending on where you are in the security vs efficiency spectrum, you may opt to ignore those assertions in production.
Writing specific tests for that looks very inefficient to me but maybe I am missing something.
If some function A calls function B with a wrong type, the problem is with function A. So basically, there should be only type tests after IO functions (probably after parsing), the rest can be assertions.
At some point you have to assume something is there and correct (e.g., you don't write tests to check whether the tests are there, also you assume the testing tools work, ...).
In static languages you also assume the programmer set the right type for the function argument, so you might as well assume to have an assertion in the critical code of the functional languages.
If you excel at compositional design then this may work OK but a lot of code bases I have worked on just need a good ol' refactor to sort the mess out. And then the "there and correct" part could fail due to human error, or the new person not knowing the old assumptions etc. The asserts are a step in the right direction in documenting the assumptions though. Types go one level better by both documenting the interface, and enforcing that contract at compile time.
* true as in all possible inputs and outputs rather than merely all code paths
Your comment just solved the problem by ignoring the latter, not much of a contribution to say the least.
I agree that writing specific tests for that is very inefficient, and that few people (myself included) actually do it. I just also think the fact that people don't really write tests for a (anecdotally) common cause of bugs, and instead wait to see them in their production logs, is an anti-pattern, rather than a positive thing.
I want the function to fail when it is passed the wrong arguments, but I don't really care about how exactly it fails. If the wrong types get passed to a function, I'm already screwed and there's no way to do the right thing at that point. I only care that I get enough information to debug what happened.
In pretty much any other case, I want to function return some precise value or do some precise action. These are situations that the code will encounter during normal execution, and so I do care about what exactly it does.
For the tests the check types of values, that's just a dumb test that you shouldn't write regardless of the language.
Then for rest of the post, he talks about having nicely-defined tests which is orthogonal to whether or not your types are static.
The thing is, almost all the tests you'd write in a dynamic language end up being something you can encode into the types of values.
Can you actually give an example of a test that would be realistically written in a dynamic language that would be something encoded into the types of values?
There is a definition for the schema to a fruit table.
The list_id indicates that this isn't a real table, but is actually stored in the list_options table. So my code has to generate a different query then for a normal table.The actual options are populated from a list:
These get inserted into the database. Note that the first column is the list_id from the schema.And for the actual test:
This actual sends the request to be processed.
Then I assert that the respone is exactly what I thought it would be: I would have written pretty much the exact same test if it were a statically typed language.That aside, what pieces could actually go wrong in a statically typed language? You can't typo field names or the like. You could typo the names, but I don't believe typing them into the computer twice adds value - better to check them once in code review. People aren't going to be editing this code in a way that could lead to getting the names wrong.
You couldn't go down the wrong code path and end up with the "normal table" query, because having list_id instead of something else is part of the type. You couldn't pass some other number as the list id, because list ID is a typed thing that is different from all other IDs, and in any case where would an outside number come from? And you're definitely going to return a response that's formatted with a record list, because that's part of the type of the method. (You might need to test the JSON <-> String piece, but that's generic, so you only need an O(1) test for that, you don't have to test every JSON endpoint. In practice you're likely using an existing well-tested library. Similar reasoning applies to the database querying part). Assuming you have warn-for-unused-parameters enabled, you couldn't forget to apply the criterion and just return everything in the list.
So yeah, assuming this was for part of an existing system where I'd already tested generic facilities like database access and JSON serialization, I wouldn't feel the need to write this test at all.
But this is the generic facility for database access. This is just an additional special case it has to handle. Does that change your perspective on whether you would write a test for it?
> That aside, what pieces could actually go wrong in a statically typed language?
Well, I could type the SQL wrong, but let's assume we are working in a sufficiently awesome statically typed language that would catch that kind of error.
I could filter on the wrong column, with the wrong operator, with the wrong value, on the wrong table. I could decode the name column using the wrong encoding. I could return multiple rows per option. I could do a huge number of other things that I couldn't think of. These may not be really likely to be mistakes I'd make (this is a pretty simple task), but several refactorings down the line, I can easily see an issue being introduced.
At the end of the day, even in a statically typed language where much of the functionality would be verified by the compiler, I'd still like to have a test on this.
> Ok, good example on some levels, though it's doing a lot of interfacing with untyped parts
Hmm... the fact that it deals with the boundary of the system and the fact that it deals only with converting data from one format to another might render it a poor sample (i.e. there's not really much interesting logic). I can come up with another if you are interested.
Presumably it would be using a lower layer - or more likely an existing library - for doing the actual query though?
> I could filter on the wrong column,
Not if you've got a typed representation of which column's which
> with the wrong operator,
Not if equality is the only operator available. This is one of my biggest reasons for using wrapper types around IDs - you shouldn't treat IDs as integers, because the idea of adding or multiplying or <=ing an ID makes no sense.
> with the wrong value,
How? You have to use the passed ID for something, and it can't do anything else.
> on the wrong table.
So make the table part of the type. A list ID is a different thing from a user ID, they shouldn't be compatible.
> I could decode the name column using the wrong encoding.
Encoding should absolutely be handled with types.
> I could return multiple rows per option.
Hmm, maybe. But I can't see how you'd do that by accident.
> At the end of the day, even in a statically typed language where much of the functionality would be verified by the compiler, I'd still like to have a test on this.
I started out thinking the same thing (I moved from Java/Python to Scala). I've gradually reduced the amount of tests I write over four years as I've found them to not add value. I was as surprised as anyone, and even privately entertained the thought that maybe I was some kind of super-programmer who was smarter than all those people who needed tests, but that month or two of trying to do stuff in Django made it very clear that it wasn't me, it was the language.
> Hmm... the fact that it deals with the boundary of the system and the fact that it deals only with converting data from one format to another might render it a poor sample (i.e. there's not really much interesting logic). I can come up with another if you are interested.
Yeah, happy to if you're interested. It's a useful exercise in thinking it through for myself as much as anything.
Ah, Scala. I could be prepared to believe that this is true for Scala (and similarly advanced typed systems). It is when people claim they write fewer tests in java than in python that I found it really dubious.
> Yeah, happy to if you're interested. It's a useful exercise in thinking it through for myself as much as anything.
Ok here's another test:
These are action objects, they represent a sequence of user actions on a JobExtra.
I construct the final state by reducing across all those actions I verify that the job extra is considered valid afterwards. To be considered valid:1. The changeAmount must be set to non-zero 2. The certifiedFormanRelated must be false or the appliedPercentage must be true
But, if the user modifies the appliedPercentage, the certifiedFormanRelated should be automatically set to true.
So this, and a number of related tests verify that under different sequences of actions I end up the result I expected.
Is there a way to push this into the type system?
For 1., you could have a non-zero number type, or you could settle for a check in the JobExtra constructor. For 2., it sounds like this is a coproduct situation - a JobExtra is either certifiedFormanRelated or has an appliedPercentage. Scala doesn't quite have native support for coproducts the way it does for tuples, but you could represent it with a sealed class hierarchy:
or being a bit lazier you could just use an Option[Decimal] and say that if it's Some it's the applied percentage and if it's None then it's certified foreman related.In Java there isn't a "sealed" keyword, but you can emulate it with the visitor pattern - you'd define a ForemanOrPercentageVisitor and only ever operate on ForemanOrPercentages via the visitor. That way if someone creates their own subtype of ForemanOrPercentage it still has to behave like one or the other, because they still have to implement visit().
Since the user input modifies this object, the user can put the object into an invalid state. In fact, when the object is first created it is in an invalid state. So I can't simply define my types so that invalid state is impossible.
That's very interesting, and shows how types can go much further then what we see in languages like Java. I'll have to try out one of these languages some day and see how well it works in practice.
No, I don't think so. I'll write a test that uses the library. If the library returns null when I don't expect it, it'll go into my code an cause an exception to tbe thrown. I'm not deliberately testing for nulls, I'm testing generally that my code does what I think it does.
The kind of library function that returns null doesn't usually return it on the "happy path", it usually returns null for some weird condition you haven't thought of. I mean, if it's a function that returns null often or that you'd expect to sometimes return null, you'll wrap up the return value in an option straight away even without having written a test. The kind of library function that causes you to get exceptions in production is the kind that returns null in some weird corner case - but unless you think of the weird corner case, you wouldn't hit it in a test either.
If I was using a library with some complex stateful interface I might write tests for the interaction with that (I'd probably put a facade on it, keeping it separate from the business logic, and the facade would have unit tests) - but I'd try to avoid using such a library. And I'll always have a few high-level end-to-end tests (not really "unit" tests) as a basic "does it work at all", because that kind of mistake is easy to make. But the bread-and-butter unit tests that I wrote when I worked in Python just don't seem valuable or necessary.
Honestly, I can't say how it would work if I was using a java code base that consistently applied these kinds of ideas. You may be right, but at this point I have hard time believing.
It's a lot harder to design a static type system that's both expressive enough to be pleasant to use and strict enough to be useful. But we're getting there in modern languages like Rust, Kotlin, Swift etc.
That's the reason one should use build tools, be it Ant, Maven, or Gradle. The process of setting them up without an IDE is narrowly described in the docs https://kotlinlang.org/docs/tutorials/build-tools.html
The way to go is to use auto completion in an IDE. If you type `myArray.sort<ctrl+space>`, you get all one needs, including `sort`, `sorted`, `sortBy` (which you needed).
Alternatively you could search the reference page for Array or MutableList or MutableMap, not sure what you wanted: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/ https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collecti... https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collecti...
The docs are arranged in a way that one reads them in the order they are written (at least the first half). I supposed that would take more than half an hour given at the competition.
I don't think Kotlin is the best choice for programming challenges like codeforces - they really don't let him shine (although I use it whenever I can). But if this is a valid case, we can collaborate and write a short tutorial for C/C++ to Kotlin programmers.
https://discuss.kotlinlang.org/t/examples-in-the-api-docs/16...
There is a slice of the universe where this exists, but it's not really Kotlin's target in the first place (and I think that's basically self-evident from everything around it) so I'm not sure why you'd try to jam that square peg in the round hole to begin with.
Is Kotlin not capable of being a client application?
Runescape also used to be a pretty big one, even if it's been shrinking lately AFAIK.
Many games on Android are also Java based obviously.
(Why are you running things on uncontrolled machines? Don't you have puppet or the like set up so that every machine has whatever it needs to run whatever you put there?)
https://www.youtube.com/watch?v=ArWWlwQl37A
I believe Kotlin actually adds programming paradigm that's not in Java on top of terse syntax, i.e. real closure, operator overloading, pure object orientation, and more.
Like a waiter advising, "Choose the chicken parm. It doesn't have any bones, all the salmonella has been cooked out, and it doesn't have any bad flavor."
If I'm going to be successfully pitched a programming language, I will need to see its power of expression or be shown how it solves some problems that other languages don't address well. Some "special sauce."
No offense intended ... that's just my quick take.
I think that is wrong approach. Kotlin has nothing special or innovative, everything was already here. But it is well balanced and industrial strength (something like java). It is simply good workhorse for most tasks. It is excellent replacement for java, that is all.
(I don't think Kotlin is such a language - I think Ceylon might be. I work in Scala at the moment)
* Ceylon has actually listened to the lessons of Scala tuples and built theirs the way ours should have been all along (HLists), making them much easier to abstract over. (NB not actually an issue in Scala in practice - you import Shapeless and then everything works the way it should - but it's nicer to have the right thing by default, as will hopefully be the case in Scala 3.x)
* Ceylon has higher-kinded type support done right - multiple parameter lists to avoid Scala's unification issues that lead to the use of "type lambdas" (hopefully fixed in Scala 2.12).
Kotlin simply doesn't support higher-kinded types; combined with the lack of union types this means magical annotations with bytecode manipulation where suddenly the code you wrote isn't the code that runs, because just like Java that's the only way to do a lot of things in Kotlin. Async is a special case with language-level dedicated support code. Error handling is done solely through unchecked exceptions which is fine for system failures but not a good way to handle "expected" failures like input validation.
In the end I did choose Kotlin. My reasons included:
* support in IDEA
* focus on java interoperability
* nice interop with android
but the main thing probably was, that I trust JetBrains that they will support Kotlin in the long term, while I don't think RedHat has any projects depending on the language.
So, why would you choose Ceylon?
This succinctly describes many aspects of Kotlin.
I'd blame the author for this. He's obviously not a salesperson. To me it seems more like he's a coder who found a new-ish language and he's happy that it solves some of his problems that he's encountered.
>If I'm going to be successfully pitched a programming language, I will need to see its power of expression or be shown how it solves some problems that other languages don't address well. Some "special sauce."
For me this was pretty open/shut. Kotlin usage appears to rely upon a lot of side projects. I rarely find that beneficial. Too many cooks.
http://www.eclipse.org/xtend/
Kotlin follows a very similar path as it does, but to greater success. I played with xtend a few years ago and now I use kotlin for my jvm tasks.
https://github.com/xach/linj
Yes. At one job my predecessor had done significant work in Java and somehow the only the compiled files were left behind. We reverse compiled them and that was my starting point for the project. As you can imaging the generated code was perfectly formated, with a very consistent style, and generic variable names. It wasn't terrible to work with.
The language I'm proposing probably couldn't be too different than Java. But one trivial example would be to make all variables final by default unless they were marked "notfinal". This would be different than Java, and thus would be a new language. And it would be trivial to translate back and forth between this language and Java. Nobody could ever tell the difference. Granted all you would really be changing is syntax, which may or may not be worth while.
I fear that it will be hard to move in that direction as long as Google does not push in that direction though.
The official word is that we don't need their support in order to write Android apps in Kotlin, which is true and that the gap between objC and Swift was large enough to justify the change but that Java is not that old, which is debatable.
In all cases, it is hard to argument the move to a new language in an existing codebase when there is no official push in that direction.
If I have to create a new app in the near future, I will strongly consider Kotlin, but for the 8 eight old codebase I have to deal with + the 15 engineers working on it, my hands are tied.
I don't understand the logic behind this sentence? Why do you need Google to push you somewhere instead of you youself choosing a more productive option?
Kotlin is designed to be easy to integrate into existing Java codebase and our introduction to a largeish Android codebase has been a great success.
However, right now I am a senior engineer working on a 8 years old android app alongside 15 other Android devs.
The switch to another language is not even something that the current lead or the CTO are willing to consider.
In their defense, we would have to train the whole team, this would be a major task and build times are already a big issue so anything degrading them is hard to push for.
A push from Google would help a lot, it would remove a lot of objections like "this is hipster shit" or "I am not going to learn the language of the month" (coming from people who have not learned any language in years) and force them to take it seriously.
Even the iOS team barely use Swift though, so I don't see it in a near future. I guess I just have to search for another company.
> our introduction to a largeish Android codebase has been a great success. Do you mind sharing some details ?
I'm sorry but you just undercut your own anti-intellectualism better than I could right there.
(There exist languages which have guarded against this without loss of expressive power since before Java and, oh, are from academia.)
Please correct me if I'm wrong, but Kotlin doesn't improve on Java in these areas.
Despite its young age it creates really fast, tight code (they have issues benchmarking things because Dotty Linker + LLVM gets rid of too much stuff).
the point would have been better made by pointing out the excellent and extensive tooling built by jetbrains for kotlin. that's something the maker of the intellij platform has more experience with than academics
Also there is a tradeoff between advanced language features and good tooling, which is why you will sometimes miss the former inside kotlin
So? Their academic status might solve this, but create other problems still.
E.g. lack of an actual commercial ecosystem, too much emphasis on research-y features, immature tooling, etc.
Note the very important part of that statement: It solves problems faced by working programmers today.
Academic PL research can have that property. Pizza went on to be the foundation of Java generics, there's a ton of excellent compiler and GC theory that comes from academic research and so on. And of course a few of the ideas in Haskell and others are leaking into the mainstream.
But when it comes to handling null pointer errors, sorry, it's insufficient to say "some languages popular in academia don't have null". So what? Working programmers today hardly use such languages. They very much rely on languages which do have nulls, and APIs which use them, and yet the only language that came out of academia in recent times which has serious production usage is Scala, which has ... nothing to say on the topic. Except, oh, an option type. Which can also be null, and which even C programmers can easily have. It's simply not comparable to language integrated support with backwards compatibility.
It would have been nice if academic research had identified up front the best set of usability tradeoffs for adding optionality into a backwards compatible language, but nobody did, so JetBrains had to do it themselves.
A few? Don't you feel like you're underselling the impact Haskell had had on other languages?
> he only language that came out of academia in recent times which has serious production usage is Scala,
What are your qualifications for serious production usage? Would ocaml count by your standards? Haskell also has increasing production usage, though I'm sure you don't count it. Swift (if you don't count it now, you will)? Rust?
> It would have been nice if academic research had identified up front the best set of usability tradeoffs for adding optionality into a backwards compatible language,
That's not enough. It would have to be more convenient to use optionals than null or programmers in that language would have to be convinced optionals are better.
In an existing language that uses null pervasively, it would be hard to get a critical mass of legacy code which uses optional.
What are the key ideas that make Haskell unique? I'd say they are pure functional by default, lazyness by default, an extremely terse syntax that relies heavily on symbols, effects in the type system, type classes, and a few other smaller things. As a non-Haskell expert at least, these are the ideas I associate with the language.
Writing code in a more functional style is steadily becoming more popular, but functional by default does not seem to be the choice of any modern language targeted at the mainstream. Swift, Rust, Kotlin, Ceylon, Go are all examples of industrial languages developed outside of academia that do not follow this design choice, and their functional programming support primarily consists of map/filter/fold/etc type methods on collections and sometimes (as with Kotlin/Java) a lazy sequences library. Meanwhilst, whilst often convenient and intuitively helpful, the evidence that fully pure functional code is of much higher quality than mixed or mostly imperative code is ... lacking. Certainly it's difficult to get clear evidence without controlling for other factors like experience of the programmers.
Lazyness by default is an equally un-influential choice. It seems Idris is the newest cutting edge academic pure FP language and it's strict by default. Lazyness by default creates an entirely new class of bugs that developers didn't have to think about before, for little obvious benefit (it lets you write in a certain style more easily, but does that style really give better software? again, it's difficult to get robust data on this).
The extremely terse syntax that relies heavily on symbolic operators is widely regarded as a bad choice. Modern industrial languages like the ones I named have all shunned this type of design and Kotlin, for instance, doesn't let you define arbitrary new operators. Haskell code is often rendered much harder to read than necessary due to its abuse of symbolic operators.
Effects in the type system do feel nice, but the impact of this idea has likewise been limited. You could argue that Rust's borrow checker is perhaps somehow inspired by this, although it's sufficiently different that I'd describe it as original work rather than idea that comes from Haskell. Other languages haven't focused on it so much.
I suspect the next idea to cross over from Haskell will be type classes, or a variant of them. But probably as an obscure feature not many people use, rather than a fundamental building block as in Haskell.
All in all, given the level of attention Haskell has received for many years, I feel its ideas have had surprisingly little impact.
With respect to "serious production usage", that was obviously a lax description. As far as I know there's much more usage of Scala in the non-academic world than O'Caml or Haskell, but it's still quite a small amount relative to languages like Python or Java. I don't have any specific thresholds, it was an intuitive description.
> In an existing language that uses null pervasively, it would be hard to get a critical mass of legacy code which uses optional.
Exactly, but that's what Kotlin is trying to do through its auto-convert from Java to Kotlin, the backwards compatible type system, support for nullity annotations and so on. It's got the closest yet.
The costs of adopting a new language are greatly more significant than implied here. The time it takes to learn it. The time it turns to learn the tools that are specific to it. And if you put it into production, the technical debt you've created by adding another language to the codebase, etc.
If the OP had said that you don't have to start a green-field project to use it, that would be more accurate.
One reason the cost is low, is that there aren't really many tools specific to Kotlin (or any, really). You can use the same IDEs, the same build toolchains, the same libraries, even the same standard library as regular Java.
I would love to learn more about languages and marketing. Off to Google!
(Don't get me wrong, there are plenty of things Scala would do differently if it were made today - there's space for a language like Ceylon that makes a genuine effort to simplify on what's in Scala)
> Anti-intellectualism is hostility towards and mistrust of intellect, intellectuals, and intellectual pursuits, usually expressed as the derision of education, philosophy, literature, art, and science, as impractical and contemptible. ... In public discourse, anti-intellectuals are usually perceived and publicly present themselves as champions of the common folk—populists against political elitism and academic elitism—proposing that the educated are a social class detached from the everyday concerns of the majority, and that they dominate political discourse and higher education.
The above sentence fails that test, it merely states its roots and goals can be different from academic pursuits. And it is mostly correct: at best academic work is focused on tomorrow, not today..and at worst it is focused on today but should be focused on tomorrow.
Each time someone brings up Scala there comes this weird "people who don't like it are anti-intellectual" - well no, people don't like it because it looks weird, had for the longest time abyssimal IDE support, tries to do things which have been solved in production by itself (see SBT vs Maven) and is a mishmash of more or less every idea that was floating around mixed into one language.
Kotlin has a very specific focus: Being usable for a working Java programmer, who doesn't have three years to learn every weird idea Scala tries to shove down your throat. It uses existing tools, existing Java collections and enhances them instead of saying "well, we do everything new, because we know how to do it 'better' and we don't care for your existing code."
You don't need Scalaz to write Scala code. You can even ignore most of the standard library while you're starting out, and use the Java equivalents.
SBT might seem pointless at first, but the same thing applies there. You don't need to use it, plugins for Maven and Gradle are available. But once you do switch, you'll see how much nicer it is.
The whole "Kotlin comes from industry, not academia. It solves problems faced by working programmers today." is pretty clearly anti-intellectual. I come from industry, not academia, and the Scala type system solves problems I face as a working programmer every day that I couldn't solve in Kotlin (or any other language without higher-kinded types), thank you very much.
> people don't like it because it looks weird
Weird how? I find it looks very much like Python or Ruby.
> had for the longest time abyssimal IDE support
Shrug. Not my experience.
> tries to do things which have been solved in production by itself (see SBT vs Maven)
Just ignore that nonsense and use maven.
> and is a mishmash of more or less every idea that was floating around mixed into one language.
Hardly. It's got a small number of powerful features that get out of your way and let libraries get on with it. Kotlin is far more of a mishmash because it has a whole bunch of special-case functions in the language (e.g. special operators for dealing with nulls, rather than just being a language that people can write an optional type in).
> Kotlin has a very specific focus: Being usable for a working Java programmer, who doesn't have three years to learn every weird idea Scala tries to shove down your throat. It uses existing tools, existing Java collections and enhances them instead of saying "well, we do everything new, because we know how to do it 'better' and we don't care for your existing code."
Scala doesn't shove anything down your throat. You can use the Java collections in Scala if you want - I did when getting started - it's just that it's really valuable to have immutable collection types (actually even in pure Java this is true - one of the reasons Guava is used in almost every project is to be able to have ImmutableList etc. types - but it's better if you can do it without having half the class be "throw new MethodNotSupported()").
Could you describe in detail the problems you had? What was unclear or misleading? Were those problems with the JVM setup or Kotlin itself?
Maybe prior to Java 8 this would've been more interesting. I also wonder how much time it will take Kotlin to start benefiting from Java 9 features when that gets released.
The declaration-site variance for generics is a pretty good idea, but is still inadequate to deal with functional collections. (I use the term "functional" as opposed to simply "immutable": an immutable collection has no update operations at all, while a functional collection has functional update operations: for example, given a set S and an element X, to compute a new set whose elements are those of S together with X (S ∪ {X}). This usage is certainly not universal, but the distinction needs to be drawn somehow.)
Anyway, the point is this. Kotlin has in its collections API
where the use of 'out' says that given types A and B where B is a subtype of A, 'Set<B>' is a subtype of 'Set<A>'. But then if you wanted to add a 'with' operation as described above: you can't do it, because type parameters marked with 'out' can't be used for method parameters.And Gradle is so much easier than the monster that is SBT.
Totally is, but I've had better luck using Maven than Gradle. Having multiple mutually compatible options is great.
I don't want to compare it to Scala, they target different auditories, IMO. I tried Scala, it's a lovely language, but it's too complex. I had to spend a month before I was able to write a quality code using Scala and I still had a lot of problems reading scala collections source code or even understand scalaz. On the other side I spent one evening reading about Kotlin (awesome and very complete, yet small documentation definitely helps) and I knew the language, could read its standard library and write production-quality code. For me that's a deal breaker.
That being said scala is not for one who wants to plateau quickly. It takes years.
I fear it might be very hard to make the Android community adopt it massively though, unless Google pitches in and supports it officially.
And this was done without any official support for Google because... it's not necessary: Kotlin works out of the box. Which is one of Kotlin's strengths.
Do you have any adoption numbers though ? From what I see in the local companies, kotlin is still very rare, except for a couple of startups (which makes them very attractive tbh). That anecdotal evidence of course and I would love to see a tide change but hard numbers would be an huge help.
With dart news in the past 4 years, the knee-jerk reaction has been that Google will abandon it, which unfortunately means that not much discussion ever went to its merits. Adopting the language has provided a huge productivity boost for me and many other developers, in or outside Google.
Seriously underwhelming....
The 1.1 release is promising many features that make me want to revisit it, though: https://blog.jetbrains.com/kotlin/2016/04/kotlin-post-1-0-ro...
So it will end as iOS only.
ABCL - Armed Bear Common Lisp is another, but Lisp on the JVM instead of Haskell. It's been around for a while, and has become fast for a Lisp on the JVM, though it's not SBCL in speed. It does however support full 32 bit integers on 32 bits sytems compared with SBCL's 29 bits on 32 bit systems due to boxing. Again, not used much in production, although, there are some great testimonials of some cool implementations [2]. I particularly like the Keck telescope code written in Lisp in 1994, ported to ABCL and using Java for some image work and display.
[1] https://github.com/frege/frege
[2] https://common-lisp.net/project/armedbear/testimonials.shtml
Kotlin is getting rapid adoption in the Android community and is quickly getting the same status as Swift has in the iOS world.
The main reasons for the rapid adoption are:
- It's designed to easily integrate into existing Java codebases. This means that starting to use Kotlin is pretty much a case of adding two Gradle dependencies and source files into `src/kotlin`. Interop with Java is painless and doesn't require any special boxing as opposed to some other languages.
- It's standard library is small (~700KB), which is a stark contrast to Scala and some other JVM languages, which pretty much demand usage of ProGuard while developing due to large method count.
- It's performance characteristics are close to Java and doesn't cause catastrophic GC collection issues like some Clojure code does.
- It has pretty much all the features expected from a modern language (nullability, const values, concise syntax) while still keeping code very readable for people who already know Java. The adoption in our Java codebase has thus been rather painless, since code doesn't do any additional magic you wouldn't expect.
- It compiles code to Java bytecode which runs on Java 6 JVM, which is critical for Android.
- It has first-party support in IntelliJ IDEs, which includes Android Studio itself. The IDE experience is significantly better than Scala or Clojure one and almost on par with Java.
So in short, we got a modern language, which is easy to transition to from Java 6, gives seamless interoperability with existing Java code (you can just start writing Kotlin classes in your Java code base), doesn't add overhead to your Android application and doesn't behave strangely performance-wise. There are still some warts to fix (mostly related to static checkers), but Kotlin has been a huge win for Android world.
What's keeping Swift itself from eventually becoming the preferred language for Android as well?
And the fact that there's no standard library outside the Apple world for the language. Adoption of Swift makes pretty much no sense, technologically or politically.
As a C/C++ alternative for native development on Android... possibly.
This will be in great part decided by
1) How frustrated native Android developers currently are with C/C++ (I don't have the feeling they are much) and
2) How much resources Apple will dedicate to make Swift viable on Android (hard to imagine they would be that interested helping out the #1 player in that space while their #2 spot is shrinking on a daily basis).
A Scala Hello World is around 30 kB, it can get more as you keep using more of the standard library, but to be realistic, it's around a few hundred kBs.
Not sure what's the big deal with ProGuard it's just a deployment detail. Compilation seems to be faster with SBT and ProGuard than Java/Kotlin/... without ProGuard.
EDIT: On the other hand Java 6 byte code might run just fine under I.E JRE 8?