Am I the only one that really doesn't mind semi-colons?
I find it to be a drawback when they aren't required, because it introduces unnecessary ambiguity. If I have to wrap a long line, then there's extra syntax I have to remember to make sure the language realizes that this is all "really" a single line.
I write LiveScript and never had a problem with this.
I prefer lesser symbols on screen.
On the other hand, LS has syntactically significant whitespace which lets you indent wrapped stuff so the compiler sees that it still belongs to the previous command, in many cases.
Specifically in Python, if you're appending lines of text, for example, then you have to add a \ before the newline. Also in Javascript if you omit the semi-colon then sometimes the interpreter gets confused and functionality gets jumbled.
Sorry if that's not that specific. I just in general prefer semi-colons being required, because then it fails fast rather than producing subtle bugs later.
A detail I've noticed when compiling to JavaScript is that Kotlin is not a reserved word, and if you bind something to it, it breaks the generated JavaScript.
It was really interesting to see Prezi on the list. They hired the creator of Elm and are one of the very few places if not the only place using it in production. If they're using this too they must be a linguistically fearless shop.
With Google's move to InteliJ for Android development, I kind of hoped that they might sponsor Kotlin, but alas Google IO 2014 comes by, and they reaffirm at the Android Team Fireside that only Java and C++ have an welcoming place in Android development. With no official plans for Java 7+ support.
Well, Google have officially dropped Dalvik (i.e. a JVM) in favour of ART (pre-compilation to native code). This is the perfect opportunity to open up the platform to a plethora of new programming languages without needing to worry about being JVM compatible. Instead an LLVM back-end can be produced to compile straight down to ART ABI compatible native code.
ART is a JVM, it's just not a just-in-time compiling JVM.
The JVM is fine for multiple programming languages, as Kotlin nicely proves. And Kotlin targets Java 6 so it should work fine on Android, even though now Android supports Java 7 language features. The missing parts are the Java 7 API's: unfortunately the class library, being based on Apache Harmony (a dead project) does not move forward on Android. However this does not have any effect on Kotlin.
ART is still heavily bound by many JVMisms. All of the framework code is Java as well, so whatever you intend to use with ART has to have some understanding of the Java world as well.
Looks similar to Haxe, in that they're targeting interoperability. But with less platform support.
I personally have yet to use Haxe, but the people I know who use it love it. I'm keeping it in mind for a good use case! Such as sharing application logic across applications, though in practice last time I did that things got very messy, it was easier just to duplicate application logic across applications. Kotlin/Haxe would be great for cross platform libraries though.
Both Kotlin and Haxe do have GADT, which is a feature I'm finding harder to live without :D Also Kotlin appears to have record types!
Kotlin seems to be a good deal simpler than Haxe. Haxe seems to be closer to Scala in terms of complexity, while Kotlin really just boils down to a few extra features relative to Java 8.
As far as I know, Kotlin does not have algebreic data types. It does have the nullable type `T?` which is basically Option or Maybe, but you can't define your own.
Haxe's enums are algebreic types, but I don't think it has full support for generalized algebreic data types.
Duplicating app logic is not so bad if it's just a simple one off, and you know the languages well.
Haxe is pretty awesome once you start working a server/client app from a single code base. You save so much mental energy not having to do context switching on a language, and you're not afraid to make drastic changes to logic or data structures because you're making both changes at the same time.
It seems interesting but I find myself comparing it to Eclipse's Xtend (http://www.eclipse.org/xtend/ ). Does anyone know if it has an advantage over Xtend?
Cool thing about Xtend is that you can actually understand the Java it generates. So once you've used Xtend to generate the Java you can forget about Xtend if you want to. You are not "married" to it.
You can later take a Xtend-generated Java-method and start manually modifying it if needed.
I just wish Xtend had more support from others besides Eclipse. Also I hope it gets its Ant -support to a better shape, maybe it already is. It is simply a smarter simpler way to write Java. And you don't need to go Java 8 to benefit from "Lambdas".
minaandrawos's question is really good. I don't know at which situations Xtend would make more sense than Kotlin or vice versa, but I would like to know if it compiles as slow as Scala.
How good are Kotlin's async options? It's not like Java threads I hope. I like Kotlin, but a good asynchronous mechanism or real coroutines are really important.
You might want to check out Quasar. (https://github.com/puniverse/quasar) While it might not be something built into Kotlin, I would assume that Kotlin's interop with Java would make it easy to use. There's also a library called Pulsar for Clojure that wraps Quasar nicely. (written by the developers who are making Quasar)
I looked a quick tutorial - it seems to be just a normal continuation-based approach. If want to have a single try/catch block for a bunch of code that calls many different async tasks among other things, how does that work?
It all flows through flatMap and other methods on CompletableFuture and you can catch the failures only once at the top level future that collects it all. That is the value of promises over callbacks generally. This might be a little convoluted to see what I am talking about:
The basic idea is that if you have a bunch of Futures you can flatMap them all together and have only a single exception handling block if that is what you want. Or you can handle the exceptions at any level and convert them. Makes it very nice to handle partial failures and the like.
The distinction between this and the coroutine-esqe approach provided by something like Quasar (linked in a sibling comment) is that even with the best of future/promise APIs, the callbacks/futures/promises paradigm of code is still... viral. Inverting the flow of one region of a project to bounce callbacks/futures/promises solves problems there, but when it's exposed at the end as a future/promise, now your calling code has two choices:
- Block a thread again on that promise
- Keep chaining out more promises
The former choice works, but limits scalability just like the poorly parallelized code we're trying to escape from. The latter choice is infectious: it keeps pushing the inversion of flow and scheduling concerns farther and farther out.
Using Quasar's fibers to call code that's "blocking" (but secretly just jumps back into use via the scheduler) scales the same way async callbacks do -- threads are always doing real work instead of blocking -- but it doesn't have the "viral" problem. When you take a stacktrace, it's exactly the same as your old blocking code: it's an actual record of how you got here! Callback based code invariably loses that feature of stacktraces, no matter how fine of an implementation of future/promise patterns is wrapped around it.
Incidentally, lest this read as a pitch for Quasar in particular, I should mention that this entire comment could all be regex'd into a pitch for Golang's goroutines and scheduler. Quasar is just the only good implementation of it for the JVM I'm currently aware of. (Other libraries have implemented some of the backing components, like Apache JavaFlow as long ago as 2006, but I experimented with it once and found it to be a far cry from the high-level APIs I actually want to use.)
The sample looks like any other closure-based framework, to me. Compare to C#, for instance, I can just do this:
try {
var a = await Function1Async()
var b = await Function2Async(a);
try {
var c = nonAsync(a,b);
await AnotherThingAsync(c);
} catch { ... }
} catch {
...
}
finally {
...
}
This generates the callback mess (every await is an async call), figures out the right parts of the exception/finally handlers to run, etc. etc. I don't see how this can be remotely approached if the only syntax you have is lambdas. You need some sort of rewriting system, either by a special keyword (C#), or monad-like thing (F# workflows) or something.
They say up front that it compiles to JavaScript but there should be more documentation about that. Where are the HTML5 API's? How does JavaScript interoperability work?
What things would you like documented? We're working on providing more tutorials, docs and information. The API docs are being revamped. Old ones have info about DOM/HTML/Browser support:
If I want to write a web application and I go to the API reference, it's unclear where to start. It should say whether each library is browser-only, server-only, or works in both places. For example, is kotlin.dom a client or server API? How about kotlin.io? It says that kotlin.io writes to System.out which is a server-side concept, so I'd guess it's server-only?
It would also be nice to see examples of how to embed kotlin-based JavaScript in a web page, how to call JavaScript from kotlin, and how to expose a callback function to JavaScript.
A good way to help web developers get started might be to port the examples from the React front page to Kotlin.
Thanks. The API docs are being revamped as I mentioned and those things we hope to solve. We're also working on tutorials for JS. Right now you can see info on JS here:
Kotlin's for building large software systems using the tightly-integrated IntelliJ plugin, both from Jetbrains. It was built with that use case firmly in mind, and even had contributions from James Strachan (Groovy's creator) and Alex Tkachman (creator of Groovy 2.0's, ummm..., inspiration Groovy++).
Groovy's for gluing together Java and JVM apps, testing Java objects, scripting for Grails, 20-line Gradle build scripts, and what not, anything that doesn't scale.
What large software systems have been written in Kotlin? I was under the impression that until at least v1.0 (sometime next year?) there is no guarantee of API stability (i.e. there have been and will be breaking changes).
Perhaps Kotlin will be for building large software systems is a bit more accurate.
As for Groovy, Grails performs surprisingly well[1] with Groovy as the primary language (i.e. that the developer uses to create controllers, models, etc.). Would have expected it to fall on its face with a dynamic language in use, but no, hangs in there right around the middle of the pack.
> Perhaps Kotlin will be for building large software systems
Are you arguing over what tense I used? When Jetbrains first announced it was building Kotlin, they wrote it would be designed to be used with IntelliJ, and that they'd then use it for their own internal software product builds. So it is for building large systems, that's its purpose.
When Groovy's creator announced Groovy, it was to be used to script Java. When Graeme Rocher took it over, he put in a MOP so it could be used with Grails, and later a DSL syntax for Gradle and a static compilation mode because it was there.
Is that remotely true? It's been a long time since I benchmarked it but groovy performance (outside of primitives) was dreadful last time I looked. I'd be pleasantly shocked if it could overcome the dynamic language costs.
Not sure when you last looked, but it gets a performance boost from invokedynamic on JDK 1.7 [1] and another from @CompileStatic [2]. Groovy 2.0+ is much better than previous versions.
Related, Grails 2.4 adds support for using @CompileStatic in controllers and services, whereas previously you had to keep that in separate classes in src/groovy.
A lot of modern languages look like this now. You could as well say they both look like Scala. But then, Scala also riffs off languages like Haskell in some vague syntaxy way.
Swift, I think, is strongly influenced by design trends in modern programming languages. I didn't see a whole that in it that was new though.
data class Customer(val name: String, val email: String)
fun main(args: Array<String>){
val customer = Customer("John Smith", "john.smith@somewhere.com")
println(customer)
println("Hello Kotlin")
}
A "data" keyword, "val" and "fun" instead of "def", types postfixed with a colon after the identifier, no "new" keyword for initialization.
Well, thanks to that "url editing" we get to know about posts that have gone unoticed before. Or posts that always get lots of new readers interested, despite having been discussed before.
If anything, the "duplicate submission logic" is not needed, except if we're talking about real abuse (tons of postings of the same thing that interests noone).
the original submission isn't showing up on search, and if I try to submit the normal url (kotlinlang.org), all I get is "Please try again". Calling this a wilful duplicate is stretching it.
If those things are interesting enough to people (including those reading them for the first time on the nth posting), to be upvoted multiple times, then it's not "gaming the system".
What we should care about is if we have interesting articles to read -- and if people that might have missed something in the past have a chance to see it, that's for the better.
There have beens lots of very lively discussions on the 3rd and 4th posting of the same story, and I wouldn't want those people to miss the post entirely, or those conversations to never happen.
As for the duplicate poster getting points from something he knows will be popular again, well, nobody cares if he does get the points. HN is not some silly high score competition.
Has there really been that much actual progress made lately, though?
I'd say that C++, Erlang and perhaps Haskell are the most recent languages to bring anything new to the table in a way that's at least somewhat usable in practice. And they're decades old at this point.
C++ helped make OO and generic programming feasible. Erlang helped with developing concurrent, distributed, fault-tolerant software. Haskell brought pure functional programming and laziness to a wider audience.
Otherwise, the widely-hyped languages of today, including Scala, Ruby, JavaScript, Go, Rust and even Kotlin generally just rehash what C++, Erlang, Haskell and other languages offered several decades ago.
Some of those languages, like JavaScript and even Go, are arguably worse in many ways than languages developed in the 1980s or way earlier.
At best, we're seeing small, incremental improvements. More realistically, we're just seeing old ideas rehashed again and again, with minor syntactic differences. Thus we aren't really seeing real "experimentation", and we aren't witnessing much "progress".
This sort of conversation is usually pretty subjective so it will be impossible to actually come to any agreement.
That said, ignoring the JVM in this conversation is near criminal. High performance GC, JIT, standardized profiling, etc. are all major steps forward. Are they language improvements? No, but they proved that a VM is a viable target platform and that was under serious debate in the late 90s.
I ignored the JVM because it really isn't that special at all, and its supposed benefits haven't been proven to exist in reality.
Various types of VMs predated it by decades, including ones that used various forms of GC and JIT compilation. See some of the Pascal and Smalltalk implementations from decades ago as an example of these systems. These did see a fair amount of use, in practice.
The JVM isn't particularly portable. It may support most of the major mainstream OSes used today, but it's not like portable C or C++ code (including other language implementations for Perl, Python, and so forth) that can run on all sorts of obscure and ancient systems.
Its performance isn't particularly remarkable, either, even with all of the effort that some very large companies have put into it. Its been pretty much relegated to server-side use at this point, and even then we're seeing more and more effort made to move away from it. People are realizing that it's often better to go native, as we're seeing with newer languages like Go and Rust.
The JVM did get a lot of hype, and has seen a lot of use, but it's mediocre at best. There's nothing particularly earth-shattering about it.
I hate to debate you about Rust; but no other practical language offers same memory-safety with no garbage collection that Rust provides, the lifetime and ownership systems are fairly unique. AIUI, Cyclone had something similar to lifetimes, but in a different manner, and without the considerations for concurrency/data races that Rust has.
If all the languages and frameworks that are being developed were progress, then sure. If they were meant as just experiments, then more power to them.
Here's the deal, we'll see a flood of "Why I chose (X) language" posts. A year later we'll see a flood of "Why I left (X) language" posts. Developers read too many blogs and follow too many fads. They are like golfers! "This'll get you an extra 10 yards on your swing!" B.S.
So what? I don't know about you, but I started programming for fun. Where's the fun if you never experiment or try new things?
You can't discourage people from experimenting with new languages, frameworks, design patterns, etcetera, just because some people might use it and fail.
I am not assuming that at all. Re-read my first two sentences.
The problem that I see is that developers only want to work on what is new. They don't want to work with C++ because it's old. They don't want to work with Java because it's old. They don't want to work with Ruby because even it is old. It's the same thing with frameworks. There has been an explosion of frameworks because developers can't be caught dead working on something older than 6 months.
If one's intention is to rewrite entire applications every year, knock yourself out. But if you're writing apps for customers who expect it to be solid and remain in the field for a useful amount of time, then you need the reliability of C++ or Java or C. Not some language someone whipped together in a handful of weekends.
Another commenter mentioned beginning development because it was fun. I did too. It still is, but I also grew to care about the products I develop. And no, it's not fun to chase issues with immature technology when a customer is wanting answers.
I agree with the positivity. It is always easiest to critique and stick with the familiar.
Something we can quantitatively take away from the slur of new languages is that new languages are easier now than ever to create/implement. This should be a good thing. This means faster iteration can occur. Even if that iteration is not necessarily taking place, the creation of new languages verifies this ability.
I find it to be a drawback when they aren't required, because it introduces unnecessary ambiguity. If I have to wrap a long line, then there's extra syntax I have to remember to make sure the language realizes that this is all "really" a single line.