It's getting easier
I think clojure is also actor based.
I'm not crazy about the syntax and I avoid build.sbt files, but as a tool it's very pragmatic and takes care of my needs perfectly. It has incremental compilation and continous testing built in. For testing within SBT with something like say ScalaCheck simply works out of the box with no configuration necessary, by simply slapping a ScalaCheck test in the test directory. SBT has cross compilation support, something that is needed for Scala. Some of the best Maven plugins have been ported to it (I enjoy sbt-release for example). I tried my hand at writing a simple SBT plugin and it really isn't bad. Dependency management is based on Maven repositories, again something that I miss a lot on other platforms. Publishing stuff on Sonatype has been painless. SBT's support for sub-projects in the same repository worked flawlessly for me and it is easy to setup. The console support is great too, allowing one to easily open a Scala console with the right classpath loaded (compile/runtime versus test). And in general I like how it just works out of the box.
Every time I end up interacting with Python for example, I get headaches from the clusterfuck that is setuptools, easy_install, pip, wheels, virtualenv, virtualenvwrapper or whatever the fuck they are using these days. Every time I interact with Ruby, I get headaches from rake, gem and gemspecs, bundler, rbenv, rvm or whatever else they are doing these days. I don't even want to remember Javascript and the clusterfuck that is npm, bowler, brunch.io, grunt.js, closure, amd, commonjs, browserify or whatever else they are doing these days. Or about .NET that's still in the Ant/Delphi age with MSBuild.
For Scala, the only fair competition that SBT has is Maven. And the only (other) pragmatic build/packaging/dependency management tool that I used has been Clojure's Lein, but lein lacks for example the capability of keeping a JVM process loaded, so you suffer the startup time every time you invoke a command, plus it seemed weird that lein doesn't offer things like continous testing out of the box. And speaking of configuration formats, lein's profiles are simply confusing.
You don't have to use SBT if you don't like it. Maven works fine and SBT's secret sauce, which was the incremental compilation, has been extracted in project Zinc and so it now works with Maven. But I still prefer SBT over Maven and when switching to other platforms it now feels like going back to 1999.
And for those working in Scala and building with Maven still, I second the recommendation to download & run Ivy, turn on the useZincCompiler option in maven-scala-plugin's configuration, and enjoy substantially faster build times (and automatically falling back to a normal build if Zinc isn't running). You don't even need to specify a scala home directory for Zinc like it claims; scala-maven-plugin will tell Zinc to use the Scala libs from your Maven repo.
I like this a lot. Setting up your own Maven repository on your own server, that can be internal or whatever, can be as simple as setting up a server that serves static files and the publishing itself is just copying files by means of SFTP or whatever. The protocol for finding all the listed dependencies on that server is also simple, so in case of problems you can usually understand what's going on.
This is much saner than the alternatives I've encountered on other platforms.
I'd argue that today, you are better off with the .NET VM, as far as features are concerned. But being stuck in windowsland is really a non-starter for all kinds of applications. I can send a major task that will take 400 computers for a week to Amazon if my code relies on the JVM. If I write it in .NET, not so much
See my blog post: http://blog.richdougherty.com/2009/04/tail-calls-tailrec-and...
I'm excited to see tail-call optimisation ("proper tail calls") coming to JavaScript. Hopefully a bit of competition will encourage the JVM to clean up its act too.
http://bbenvie.com/articles/2013-01-06/JavaScript-ES6-Has-Ta...
(* Heap-allocated frames can help with other things though, e.g continuations.)
Yes you do have to use trampolines for mutual tail recursive function, because the JVM currently lacks support for it, however if you take a look at the Da Vinci sub-projects in OpenJDK, a prototype has been in the works for quite some time, led by none other than John Rose and given the attention that invokeDynamic is getting, I have no doubt that this will also happen on the JVM: http://openjdk.java.net/projects/mlvm/subprojects.html
Also, Scalaz great as it may be, it simply sucks in terms of the actual implementation, as it has loads of functionality that breaks when that shouldn't have been a possibility in the first place. Every time I happened to investigate issues related to Scalaz, I always ended up with a "WTF were they thinking" moment.
> I'd argue that today, you are better off with the .NET VM, as far as features are concerned.
That's bullshit. Speaking of tail calls optimizations, the bytecode available in .NET didn't even work at all on 64 bits .NET, prior to version 4.5 - that's right, before 4.5 the tailcall bytecode was considered more of a guideline. And Because C# doesn't use it, they never bothered to optimize it, so it has a pretty dramatic performance hit in comparison with normal function calls. And Mono probably doesn't do tailcalls properly even today, with F# being unusable on top of Mono for several years.
In terms of features - for example the CLR doesn't optimize virtual method calls. This is killing dynamic languages, or static languages that diverge from the C# OOP flavor in terms of polymorphism. IronRuby was never even close to what JRuby could do even when Microsoft was funding its development, simply by virtue of JRuby running on top of the JVM. And now ever since JDK 7 with invokeDynamic, the performance boost is so amazing at times compared to Ruby MRI, that people are running apps on top of JRuby for performance reasons ;-) The JVM for example can inline virtual method calls at runtime and can de-optimize those call sites in case invariants change or in case it notices that there are no performance benefits. This is something that really few other VMs can do.
invokeDynamic is amazing. It provides a way to override the default method resolution that the JVM does, while still benefiting from the same optimizations that the JVM does for normal method calls. It even has benefits for static languages such as Scala, for dealing with closures and Java 8 introduces a facility for initializing a value that can afterwards be treated as a constant, so there are big wins ahead for Scala in terms of performance for things like "lazy val", or structural/dynamic types and others.
Functional languages use a lot of persistent data-structures and persistent data-structures are by their nature wasteful in terms of short-term junk. You need a really good garbage collector to not suffer from this and the JVM really has the best garbage collectors available. You should see what it can do in a server-side environment with server instances being hit with thousands of reqs/sec per JVM process of real traffic. I have and it's freaking sweet.
Also, it's actually good that Java's generics aren't reified. Reification is only needed for languages like Java in which the type system sucks and stays in the way for more expressive/advanced type systems. Language implementers have to pull off a lot of tricks in order to work around CLR's reified generics. F# has 2 generics type systems in the same language, as Hindley-Milner can't be piggybacked on top of CLR's reified generics.
.NET still has some niceties, like stack-allocated value types, which is sweet if you want numbers that diverge from the standard primitives offered and to avoid boxing (and JRuby suffers a little because of this). But btw, here's another thing that the JVM can do - it can do escape analysis and for example it can decide to allocate certain short-lived objects straight on the stack if it sees that those objects don't escape their context.
>Aside from terrific performance, the JVM gives you the best concurrency platform out there (though not the easiest to use)
Though I'd probably still reserve that accolade for Erlang OTP/BEAM.
I would absolutely not. Erlang/OTP/BEAM might be the best distributed computing platform (though Akka is making huge inroads), but Erlang is actually a pretty terrible at single-box concurrency.
Erlang has one concurrency primitive - message passing. Which is great, but it's not always the right one.
Consider a a producer process which solves a PDE or does a big Bayesian computation (output is an Array[Float] or Array[Double]). You have consumer processes which read from the array and compute sums over subsets of the elements.
In Erlang you are just passing around copies of arrays. In the JVM, you'll probably have a single mutable array. You'll either wrap the appropriate calls in arr.synchronize {...}. Or you can use memory barriers and let the consumers freely read from the array, and invalidate their computation if the producer wrote to the array between the start and end of their read.
1. State-of-the-art garbage collectors, which enable good implementations of lock-free data structures.
2. Excellent implementations of lock-free data structures (like ConcurrentLinkedQueue and ConcurrentSkipListMap) and other concurrent data structures (like ConcurrentHashMap).
3. A state-of-the-art work-stealing scheduler (ForkJoinPool), excellent for both parallelism (as used by Java 8's streams) and concurrency.
4. A cross-platform memory model specifying memory visibility across threads.
5. Access to CPU concurrency primitives like CAS and memory fences.
These building blocks are a great foundation for any concurrent application.
http://stackoverflow.com/questions/18063599/has-ever-anythin...
I think part of the reason for this ultra-conservative approach might be that alternate JVM implementations could in theory have well-implemented versions of deprecated methods such as the above-mentioned Thread ones.
Later they saw sense and re-implemented it and un-deprecated it.
Would you recommend Java for building cross-platform desktop apps with near native UI performance?
The IntelliJ IDE looks great but most Java desktop apps I've come across just look and feel weird. Not sure why there is such a big difference.
Two of my company's three products are a Java desktop app for Mac, and they look and feel like typical Mac apps.
Best practice? IMO you should spend significant time on the GUI making sure it feels native. Otherwise, Swing is still about as good as it gets for Java GUIs. JavaFX is supposed to be more modern and superior, but lacks the large-scale support and third-party component ecosystem that you find the Swing. Although I'd be mighty pleased to be proved wrong on that one!
I've never seen any Java desktop app that I cannot easily tell it's Java. With most of those apps, even on i7/16GB/SSD systems, you get laggy behavior with Swing and the GC. And SWT still has the "uncanny valley" look going.
It took several seconds of whited-out buttons and stuck UI for every CPU intensive operation -- all on the same thread. And that was from IBM, and from tools that you paid for a small fortune.
I'd also venture to say a lot more than 1%. Modern world (finally) recognizes that design/experience are core to any product, enterprise or not. That's part of the reason there's a whole new breed of funded enterprise companies out there -- they're taking lessons from the web/apps and applying them to replace old-school solutions. [I'm personally hoping more people recognize this need for developer tools which typically are the worst offenders of all, particularly on the database side.]
Part of having a good framework is what allows apps/applications to excel -- it helps you raise your own bar because the tools are just so much better that nicer UI/UX can be had without being a nightmare in code. That's a win for everyone.
More seriously, as a recent example you will find that what bitcoin.org offers you as the first option for a wallet (multibit) is written in java.
That may not be mainstream, but it's definitely not the classic enterprise java shop.
I've been writing UI code for years, including in Java, .NET, Android/iOS, web, etc, so I have a pretty decent clue about building complex apps in all of these frameworks. Java just isn't a modern environment, and by being cross-platform you end up with an ugly lower common denominator that doesn't have useful APIs for non-trivial designs. iOS is probably the best framework/api out there and even that has many issues (luckily obj-c's categories help you fill in the holes).
Downsides are all the usual ones, of course: updates don't happen automatically, you may need some sort of licensing/DRM if you want people to pay for your application, and your testing story is a lot more complex. (Plus: look-and-feel on various platforms, reverse engineering is that much easier, etc., etc.)
There is a lot to be said for taking an environment with a big following and making it cross-platform vs making a cross-platform environment and hoping for adoption.
And that's for the more basic widgets -- more advanced widgets have custom implementation from primitives in SWT, so they are hit and miss with regards to native look and feel.
It's hardly any "best practice" or "standard", but it looks like people are managing to ship projects with it. Performance is reasonable; on the inside, it's openGL via lwjgl.
Another option is libGDX: http://libgdx.badlogicgames.com/
Their presentations appear to be oriented largely around games, but the parts could be used for a desktop application just as well. There's a number of mobile games in both the app stores using it.
This pattern, by the way, has been going on in lots of tech companies. They always end up going back to the JVM.
Aside from terrific performance, the JVM gives you the best concurrency platform out there (though not the easiest to use), cool and extremely useful capabilities like dynamic linking and bytecode instrumentation, and unparalleled monitoring and profiling tools. It's the most professional platform you can choose (unless you're limited to Windows, in which case .Net is also an option). It's so far ahead than anything else out there, that the competition can only beat it in very specific use cases (e.g. Go is much better at startup time as well as standalone packaging, and C has better performance, though mostly in single-threaded programs). But nothing else gives you the whole package of performance, flexibility, maturity and monitoring.