JDK 8 Release Notes
oracle.com
oracle.com
If the standard library was cleaned up and the warts were all removed and filled in, even if it broke compatibility (call it Java X or the Latte language or something) I'd be okay with that. There's too much old 90's cruft hanging around making usage of different pieces non-standard and lots of over-objectizing everything so you end up having to assemble lots of things out of little pieces, boilerplate-like, that should just be a single import and instantiation.
The modern JVM is surprisingly quick and robust technology and I've been pretty happy with it in my limited tests. I ported some old Perl algorithms to it and got some really good speed out of it once I benchmarked some of the collections a little.
Some things should just be outright fixed, like a proper regex literal so I don\\'t have to \\e\\s\\ca\\\p\\\\e everything so much\\\\\//\/\\.
It's "got good bones" and a refurb of the entire thing to bring it focus could breath a lot of long-term life into it.
edit
I guess what I'm trying to say is it would be great if the language was informed a bit more with what's going on in the dynamic languages space like Go has been. I like how Python is about as clear as Java code is, but it's always seemed a little more quick and breezy to work with. This is something I think Go got right and it'd be great if Java sort of caught onto this.
this is what groovy and kotlin attempt to do. groovy is backwards compatible with java as well, in most cases java code is valid groovy code.
Groovy is optionally typed, you can have as much safety as you wish.
> and performance to do so
If you use static types, you can use @CompileStatic to get most of the performance back.
So, okay, you're technically correct, which is every nerd's favorite kind of correct, but writing it that way sucks. Groovy isn't a bad scripting language (or wouldn't be if discobot ever got done), but it's unserious as a Java competitor where Java is good.
(I'm a big fan of Scala - its sheer power is second to none - but it definitely has its ugly parts and many of them can't be fixed as long as it's to remain compatible with the Java standard library)
Whenever I read that meme I get damn suspicious about why java code isn't valid groovy code in all cases. Why only most cases? It all sounds like a recipe for spending half a day debugging simple scenarios where things don't run as intended.
To be taken seriously (or as seriously as a language called Groovy can be taken), embrace and extend Java fully, don't embrace only 99% of it before extending. That's what Microsoft tried with J++ and lost a lot of trust with developers that took them a decade to win back.
projectlombok.org also makes a lot of the language syntax ugliness quite bearable.
Suppose you have a webpage asking users for their birth date. What data type do you store that value in? Hint: You aren't going to prompt the user for the time zone they were born in.
I know most IDEs just ship with all that stuff included, but I've found it makes packaging up things to give to somebody else a little more complicated than I'd like...which would be resolved in the standard libraries.
Really, NEVER has so much effort been spent for SO LITTLE REWARD.
My production systems don't generally log; they're busy serving (I once worked on a hard real-time embedded air traffic control system where production logging was literally a single bit of information - a logic level that went high when the processor was busy, and low on idle - so we could measure our timing safety margin with an oscilloscope)
Test systems log at debug except for low level packages that insist on ridiculous logging (Hibernate, http client - and both of those have ANOTHER level of hacks to do wire-level logging in addition to the standard stuff).
Logging is just so painful, and not just in Java. Debian switched to rsyslog some time ago and I am still seeing no benefit at all, yet have to learn yet another half-arsed buggy scripting language to achieve simple things like, oh, not having my DHCPD logs showing up in three different files. FFS people.
Very useful to find out what inefficient code people have generated with Hibernate. Occasionally useful to find out what Spring is doing.
Try debugging systems for which you can't access the system directly ... say in a product that you redistribute to customers. You will change your tune rather quickly.
For product development, having a good logging system is critical. And, honestly, other than rolling my own over the years (20+ years experience developing and distributing products), the Java logging systems are pretty decent. It can be a pain to get different logging systems to work together and properly configured, and I do wish it were better, but System.out.println() ain't the answer either. When I spend a little time getting them to work right, they do their job. And that is time well spent in my opinion for redistributed products.
I'm deep in the zone, half way through fixing something and it's not working. I start up my app and realize log4whatever can't find its configuration so it defaults to no logging. Now I need to unpop my mental stack all the way to switch gears so I can fix this logging configuration issue because for all I know the key to my problem is in the log message that log4whatever hides when it's in noop mode. Why not default to as verbose as possible?
From what I can tell, the majority of these crappy Java logging frameworks are made by this one guy who keeps on screwing up. Eventually he abandons ship and starts over again. log4j, logback and slf4j are all by the same guy.
Why are you so bitter ?
I am currently in what you could consider log hell with a product based on OSGi. We have been using ops4j logging which has done a fantastic job of adapting the prevalent logging frameworks (log4j, slf4j, logback, and JUL) into the SLF4J API and we don't even have to think about it anymore.
For many common tasks there are 5 or 6 different standard library calls that seem to do the same thing, but 4 of them are to be avoided at all cost, but there's no depreciation tag and the official javadocs don't contain any pointers to the newer classes.
For example, you'd go directly to Joda-Time or JSR-310. Date and Calendar wouldn't be present at all.
Whether Java should break compatibility to remove all the old cruft I'm not sure. The benefits of the cleaner design might not be worth the costs/inconvenience.
Things which come to mind (comparing roughly 2.8 (released 2010-07) to 2.11 (released 2013-03)):
Classes (just from the top-level scala.* package):
- Application
- Cell
- cloneable
- CountedIterator
- NotDefinedError
- NotNull
- Responder
- serializable
Complete packages: - scala.actors and subpackages
- scala.collection.interfaces
- scala.concurrent (still exists, but its contents have been replaced completely)
- scala.dbc and subpackages
- scala.mobile
- scala.reflect.generic
- scala.swing and subpackages
- scala.testing
- scala.text
- scala.util.automata
- scala.util.continuations
- scala.util.grammar
- scala.util.logging
- scala.util.parsing and subpackages (includes parser combinators and JSON)
- scala.util.regexp
- scala.xml
(This of course doesn't include things which were demoted from scala to other namespaces like scala.util, scala.runtime, scala.annotations ...)The list is certainly incomplete anyway...
It's like Soupstrain said: there are only two kinds of languages: the ones people complain about and the ones nobody uses.
A side effect of success is having a large body of existing code to consider when making changes.
PS: No, yet-another-js-library-to-replace-jquery is not considered tooling. No, yet-another-replacement-for-grunt/bower/yeoman is not a good sign of the ecosystems. Java has Maven since 2004.
Python tools don't even come close. Ditto with .NET NuGet. Find me a tool that can compare feature by feature with Maven and still relevant for a long time.
With Java, you write a lot of syntax to get static typing, but it's worth it because static typing! Then you throw static typing away (because now it's to restrictive I suppose?) to use XML files which must be structured a certain unpredictable way or you'll cry at the traceback you receive, and pray your imminent Google search can make sense of it all.
I'm not sure how I feel about Java so far, although there are problems that I want to solve in the Java backend at work for future scalability, since the quality of code is actually worse than our frontend code currently.
I'm a systems engineer, but I have to touch some Java code from time to time. I always have an hard time with the amount of indirection an average Java developer can reach. Luckily a few smart guys were hired recently and they have past experience in contributing to the JVM and their approach to the code is completely different and much, much more simple to understand, and since they came onboard the performance of critical parts of our main application increased dramatically with a few lines of code instead of the previous 400 or so.
It probably has to do with the "enterprise" culture that tends to err on the side of overgeneralising things and applying far too much abstraction (Java came into being at a time when the OOP fad was gaining significant traction.) The standard library also being in that style encourages this too.
But things like Java4K suggest that it's definitely possible to do a lot in a tiny amount of code.
The ecosystem is much better (more stable, higher quality, higher "engineering" effort) than Ruby or Python.
Might not suit to one's taste but we all have different taste buds.
Properties, delegates, proper generics, LINQ and so on.
JVM vs CLR its a different story - I am hearing Microsoft in negotiation with Xamarin to buy/invest, that may make Mono get feature/implementation parity with CLR. Till then JVM is the only thing close to platform agnostic environment in town.
Properties you could simulate with lambdas now. something like Property<String> name = get(() -> name).set(name -> this.name = name);
You would lose all the existing framework support that assumes getters and setters doing that though.
Some of the generics failure will likely be fixed in 9 (Primitive specialisation). Other things are not as bad as some people think (At least generic supertype params are available at runtime)
https://github.com/benjiman/expressions/blob/master/src/test...
https://github.com/benjiman/expressions/blob/master/src/main...
The thing that makes Java so great as a platform is that there are so many totally reasonable tools that you can just download and use. Eclipse, IntelliJ (community version, which is still pretty good), the myriad of excellent alternative JVM languages, all freely available and cross platform.
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.
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.
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.
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.
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.
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.
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!
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).
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.
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.
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.
>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.
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.
I agree about the regex literals. JavaScript does it right.
Just remove the legacy/ugly methods and packages from the autocomplete process, and warn with recommendations/flag as deprecated. You don't actually have to break anything.
There are things like http://docs.oracle.com/javase/7/docs/api/deprecated-list.htm... and IDE's know about this.
This. This is what I think of when I think of Java.
This is incredibly important and I never see any Java advocate addressing it. I _do_ see tons of people pointing out how easy it is to automate refactoring, and then they leave dozens of ugly, poorly-thought-out methods lying around...
There's (A) the brief pass you do to get the gist of what a class/method does, and (B) the deeper pass when you try to build a mental model and step through bits of code in your head.
While Java's verbosity does harm skimming, it also aids targeted comprehension, since it is easier to see the "one right behavior" that code has. Fewer sneaky surprises, leaky abstractions, weird type coercions, inferring which class-interface the designer intended to target, etc.
As mentioned already, the other big advantage to explicit-ness is all the static analysis the IDE can do for you.
Finding the balance between terseness and having a little bit of redundant information is of course very hard.
To my surprise it stuck around in Enterprise spaces and I ended up running a team that ported a pretty large-ish Perl project (about 20k lines of Perl) into a piece of Java middleware. I didn't do any of the coding, but I knew the Perl bits inside and out so I knew what kind of testing and performance to expect and getting the Java port up to 1/3rd to 1/2 the performance of the original Perl was a pretty big challenge at the time. This was about...8 year ago. But to the credit of the team and I guess the tooling, they were able to get the port done remarkably quick.
So I've been pretty surprised to see that Java code can get fast, really fast. I've also managed to bang out some pretty slow code if I wasn't paying attention. For my latest touch into it, I ended up spending a week just benchmarking various collections to see how they actually worked under the kind of real-world uses I'd be putting them through (vs. what their big-O sheets claimed) and came away with a set of practices for me to get going with.
I've also had to come to terms with benching code a bunch of times to give the JIT compiler or whatever runs under the hood in the JVM some time to optimize, the first few runs are invariably much slower than run 1000.
5 years ago those 3 languages were the talk of the town for alternate JVM languages, but things change. Scala's pulled way ahead of the pack, Clojure's consistent, and Groovy's on a downward trajectory, following in Beanshell's and JPython's footsteps. Eclipse users are drifting into Xtend, and IntelliJ users may look at Kotlin more. JDK 8's Nashorn is likely to scoop up those who just want to write quick-n-dirty's manipping Java classes.
Scala is the interesting one I'm interested to see if a simplified type system can be introduced ala http://www.infoq.com/presentations/data-types-issues
Within the Spring Framework 4.0 Reference [1], the Spring Expression Language takes up all of chapter 7, whereas Groovy takes up little section 28.3.3 only, with only one use case presented. Your statement didn't have any specifics, only sales adjectives like "great test frameworks."
[1] http://docs.spring.io/spring/docs/4.0.0.RELEASE/spring-frame...
Java has caught on to this, and a number of the new JDK 8 features reflect this (lambdas and everything related to them, default methods for interfaces, etc.) But Java isn't as unconstrained as a new language like Go is, because its got to support a huge stack of established code as well as making things more streamlined for new code.
http://jaxenter.com/java-is-the-world-s-1-programming-langua...
Yeah, it's a kinda vacuous statement I guess :o)
It has a very complicated type system, but doesn't even allow you to express things like function composition or generic sums at the language level.
Its syntax is stunningly verbose (e.g., no map literals; only now adding lambda literals; no type synonyms; no operator overloading).
There is no macro system or method_missing or any other way of really extending the language, except the ugly, unsafe reflection system ... so now all the libraries (Spring, Hibernate, etc.), use annotations and reflection to modify object behavior at runtime.
Object[] foo = new String[1]; foo[0] = new Integer(4); // exception thrown here instead of a compile error.
Yeah, sure, it doesn't have Haskell's . or algebraic datatypes, just like lots of other languages. I'm not sure what's complicated about the Java type system, but I suspect you're trying to say you don't like subtyping. Moving on...
> Its syntax is stunningly verbose (e.g., no map literals; only now adding lambda literals; no type synonyms; no operator overloading).
No map literals, but Guava has leveraged generics in a brilliant way to reduce the duplicate declaration of types. Also, it brings a little bit of functional-style goodness with transform/filter. It turns even JDK 6 into something you can be productive with. I'm not sure the lack of type synonyms is really an issue, the type signatures are rarely complex enough that you need to obfuscate them. On the other hand, I'd give somebody else's right arm for an equivalent to newtype and deriving.
> There is no macro system or method_missing or any other way of really extending the language, except the ugly, unsafe reflection system ... so now all the libraries (Spring, Hibernate, etc.), use annotations and reflection to modify object behavior at runtime.
Not to forget proxy objects and interceptors. But yes, Java could definitely use a macro system.
But you're missing the elephant in the room, the existence of null. The bane of every Java programmer, dreading NPEs at each function call.
Actually, I waffle on checked exceptions; it seems every 8 months or so I have a different opinion of them. Right now they suck.
I hear you.
Let's not forget about type-erasure generics. And the existence of arrays. And the fact that people still use arrays.
But type-erasure of generics - that's the decision with which we will need to live till the end of time.
- no multiple implementation of same generic interface
- http://stackoverflow.com/questions/2723397/java-generics-what-is-pecs
- small performance hits..
- casts
- a lot more but I'm just sleepy right now.
I use and like Java, I love the backwards compatibility which it has - but there are times when crust can be removed with scalpel - and if not, you will need an jackhammer later.Type-erasure generics are a fortuitous platform decision, because its what enables languages on the platform to have a good interop story while still having a more robust type system than Java does -- case in point, Scala, and why the .NET version died.
It always bothered me that Java forces me to explicitly handle/rethrow exceptions, yet happily overflows my ints without batting an eyelid.
Initially I threw a Runtime (ie: non compile time) exception. After going to production I realized that these were bubbling up to the UI and giving the user very intimidating error messages. So I changed the exception to a Compile time exception and then the compiler caught every place I let the error slip through to the UI. In my opinion it saved me a lot of time and made my code easier to maintain.
1: EG: Who is Java to say that this IOException should be handled in code? Perhaps this IOException should not happen and requires a developer's intervention.
I'm so tired of writing null checks ...
Could the null checks of Java be compared to the ones used in C#? My C# code is often littered with ternary operators to deal with null values. And that's still not as safe as the Objective-C approach where one can just send messages to nil[0] which is really awesome imo.I guess I kinda wonder if I could avoid the null checks in C# somehow ... I figured using a design by contract approach might be used to reduce the null checks somewhat.
[0]: http://stackoverflow.com/questions/156395/sending-a-message-...
Without seeing your code it is hard to say, but using an object extension might work?
On many occasions I've used object extensions to hide checking code deep inside the extension.
C# really got that feature right.
It's definitely NOT awesome. This stupid behaviour causes bugs all the time as you think you're doing an action but it's actually a no-op because something else failed and you get a nil. An NPE is awesome - it crashes immediately and you know exactly what is wrong. A silent no-op is the worst thing to debug.
https://github.com/benjiman/expressions/blob/master/src/test...
implementation
https://github.com/benjiman/expressions/blob/master/src/main...
http://download.java.net/jdk8/docs/api/java/util/Optional.ht...
resultOption match {
case Some(x) => println(x)
case None => println("error")
}
Without pattern match: if (resultOption.isDefined) {
println(resultOption.get)
} else {
println("Error")
}
The .get is the problem. import java.util.Optional;
public class Scratch {
public static void main(String... args) {
Optional<String> foo = Optional.of("foo");
Optional<String> bar = Optional.empty();
System.out.println(foo.orElse("Error"));
System.out.println(bar.orElse("Error"));
foo.map(Print::print).orElseGet(() -> Print.print("Error"));
bar.map(Print::print).orElseGet(() -> Print.print("Error"));
foo.ifPresent(Print::print);
}
static class Print {
public static <T> T print(T val) {
System.out.println(val);
return val;
}
}
} optionalF.map( _.whatever ).getOrElse(fallback)
or perhaps (optionalF <+> optionalFallback).getOrElse(finalFallback)
For those unfamiliar with <+>, see here: http://www.chrisstucchio.com/blog/2014/handle_failure_with_p... optional match {
case Some(x) => whatever(x)
case None => fallback
}
Second, I find the pattern matching code much clearer. Sure, it's also longer, but clarity trumps everything.The speed benefit is well known, as is the corollary, premature optimisation. I expect checking for null is even faster if speed is the main concern. It's an engineering tradeoff, just like making the abstraction to a monad (or monad plus). In the normal course of events I'm more concerned about flexibility than performance and would prefer the abstraction.
I assumed this was a reference to the unequal handling of "primitive" types vs Object types, with only the latter being able to be used with generics. Except for the weird "dual" object types which sortof are and sortof are not equivalents to the primitive types (int -> Integer, etc). WHich for methods needing to take actual primitives leads to having to do abominations of repetition such as http://www.docjar.com/docs/api/java/util/Arrays.html.
Some other bad things (not necessarily "complicated" but it does complicate the code that needs to be written):
Enumerations all have to have the same constructor params and therefore the same "shape". SOrt of defeats the purpose of enumerating ALTERNATIVES, I would say (this is part of the lack of sum types that was mentioned, though).
Others mentioned nullability. Some other things I didn't see others mention:
Botched covariance of arrays which leads to runtime failure where compile time should have been sufficient, http://k2java.blogspot.com/2011/07/parametrized-types-and-ar....
Some other minor things, such as botched clonability system, where Cloneable is a "marker" interface that doesn't tell you whether some type is really cloneable, a bizarre unforced error where a simple interface (you know, with an actual method called "clone") would have sufficed.
You pick a bunch of language flavour / syntactic sugar and say that Java is bad because it doesn't have those. Personally I like it because it doesn't have things like operator overloading. These are you own preferences, not inherent flaws with the language.
The original java architects took operator overloading and the macro preprocessor out for a reason - you can end up with orders-of-magnitude more ugly code if those features are abused.
I can see both side of this. My favorite language to work in is Perl, which is loaded with all kinds of little context sensitive literals. But Java "the language" is pretty quick to pick up and get working with if you're already familiar with another Algol family language, and you can usually read other people's code without too much fuss because the language doesn't support all sorts of ways of writing something.
But on the other hand, you do end up with lots of lines to do something that should be relatively few lines if a more context specific syntax was supported. For example, the last time I worked with Java, code was littered with a half dozen lines of Iterator mess every time you wanted to go through some collection, the new for syntax is very very nice...but there's still little hard corners it's not that well supported in, like maps, because the underlying structure of the map means I have to build some temporary object to handle an item on the map in the loop...even though the map collection I'm using is in the standard library and should be part of the language via some syntactic sugar.
I'm still stunned that operator overloading isn't supported, I have a few use-cases already where that would be very helpful.
I've used all three and after a few years of C#, the other two are just a distant memory.
Except any worthwhile platform where you're not a second class citizen.
If that was true, F# wouldn't have happened. (Nor IronRuby/IronPython). Even people who like the .NET platform often pine for something better for the task at hand than C#.
I think a simple enough solution would be to introduce raw strings which is how regex is usually done in python.
Much more flexible nicer and customizable (from a UI pov) than Eclipse-based IDEs.
The ruby language syntax with the power of the JVM and Java library interop.
As far as I am concerned that is a match made in heaven.
Both the language and the framework have likely improved since then, but after switching to Scala + Play there's simply no going back ;-)
p.s. Haskell + Yesod (or Snap) look interesting as an alternative web stack to explore, but otherwise not seeing much out there that would draw me away from Scala land.
There's a learning curve, can't hit the ground running as you can with Groovy, but with Groovy there's a ceiling; with Scala the only ceiling is (perhaps) Haskell and for that you have to leave the JVM.
The list of improvements is quite long, actually:
- Server Cipher Suite Preference
- Strong Server Ephemeral Diffie-Hellman Parameters
- Authenticated (GCM) Suites
- Hardware Acceleration on Intel and AMD processors
- Server-Side SNI Support
- Ability to disable client-initiated renegotiation
- TLS 1.2 enabled by default in client mode
- Clients support Ephemeral DH over 1024 bits
More details here: http://blog.ivanristic.com/2014/03/ssl-tls-improvements-in-j...
And there are more security improvements documented here: http://openjdk.java.net/projects/jdk8/features#core/sec
My favorite parts:
- invokedynamic : http://stackoverflow.com/questions/6638735/whats-invokedynam...
- Project Nashorn : http://openjdk.java.net/projects/nashorn/
- lambda expressions : http://openjdk.java.net/projects/lambda/
https://github.com/tadas-subonis/java-nashorn-performance-sa...
What gives? Wouldn't a real comparison to Rhino and V8 (at least) be interesting?
Edit: strike that. Found someone who ran Octane and SunSpider and compared it to V8 and Spidermonkey: http://wnameless.wordpress.com/2013/12/10/javascript-engine-...
v8 is not a browser engine either ,it's a javascript engine,just like Rhino. you are mixing up Webkit with v8.
- I think you're partly correct but also confused. Webkit is a rendering engine and yes V8 is a JavaScript engine not a browser engine that was created for Chrome Browser by Google. It's used for Node.JS etc now but it's sole purpose was to make Chrome faster and that is not the same purpose of Nashorn - nashorn is a replacement for Rhino. That is what I'm trying to say.
I realize this is not a real concern for them for e.g. servers, but I wish they had some developer- or desktop-specific configuration that would start about as fast as a Python VM. I don't even care if it runs code (a reasonable fraction) slower.
Clojure seems like a good fit for tiny projects that are little more than scripts, but the start up time makes them kind of annoying to manually test. Fortunately Clojure does have a REPL.
A JVM with smaller memory and cpu needs and faster startup would make me consider using Scala/Clojure again.
I think nrepl for emacs has been replaced by cider (which still uses nREPL)
"CIDER (formerly nrepl.el) is the Clojure IDE and REPL for Emacs, built on top of nREPL, the Clojure networked REPL server."
That and the availability of the packages on melpa:
cider 20140318.... available Clojure Integrated Development Environment and REPL
And the fact that technomancy's git repository for nrepl.el hasn't been touched in 2 years leads me to believe that cider is the better nREPL choice ;) Be happy to hear that nrepl.el is still maintained and is better in some way than cider, but I don't see cider as being that heavy (at least as compared to SLIME).I'm constantly amazed that make(1) can do successive recompiles of a 50k LOC project in less than a second, while gradle / maven / etc takes upwards of a minute.
For some low-level programs executed hundreds of time per session (like "ls") I agree it adds up and might cause frustration. Java is a bad choice for this niche, but you are not going to write them in Python anyway, aren't you?
PS: Just tested "LS" in Java, less than a second run, I could personally live with that.
[1] http://www.techempower.com/blog/2013/03/26/everything-about-...
Art is still experimental and not enabled by default.
This is total speculation, but they're also moving away from the DalvikVM to the new ART runtime. I'm hoping that they're keeping Java 8 in mind as that gets implemented.
There, I lose. Everybody can go home now. :-)
http://docs.oracle.com/javase/tutorial/java/annotations/type...
- Separation of language and libraries. Really the JDK should just ship with just a very small core of classes and everything else should be optional installed via a dependency or package manager. I know jigsaw is going in this direction, but I fear they are going to go the same way as J2ME with profiles. They should also clean up the cruft while they are doing this. This would allow the libraries to evolve separately from the JDK and even allow 3rd party framework to flourish while still keeping things reasonable manageable.
- Multiple return types. Scala has hacked around it, Python has them, Go has them. Bite the bullet and implement them so you can do sensible error handling without exceptions or returning `null`. While they are at it they could also fix the type system to finally allow `Integer hello()` and `String hello()` to exist in the same class.
- Implement Categories (or mix-ins). Seriously if I have to see another class called StringUtils or IntegerUtils I will gouge my eyes out.
- Get rid of the primitives. I read somewhere that this was on the cards for Java 10.
- Implement proper Generics.
- Implement @property just like Objective-C and .NET so that 80% of class files aren't getters and setters. I'm really surprised they never did this when they implemented annotations as this was the first obvious annotation to add. I know you can do it with Aspect J but you shouldn't have to. There was a JSR for this at one point but it seemed to disappear into the ether.
Categories: Default methods probably do what you want.
Get rid of primitives: Are you nuts? It turns out computers work on primitives. It's good to support them.
"Proper" generics: maybe you mean specialization, or maybe you mean reification. It's a choice.
Properties: If they irritate you that much, just use something that will generate them for you, using standard annotation processing.
For example a method to calculate the value of an asset portfolio could return the value of the portfolio and the set of assets that are missing prices in a single call rather than having to make two separate ones (and potentially two iterations through a data collection). Cleaner to be able to return a number (or a money class) and a set of assets rather than having to return CalculationResult. As a bonus you also get to dodge the hardest problem in programming, naming things ;)
Most of my issues with Java stem from violations of Occam's Razor of this manner.
Compare with say Python where introducing classes is much less necessary and ends up with cleaner and clearer designs.
Heh? How are these things related to each other? Who in their sane mind would use tuples for error handling?
f, err := os.Open("filename.ext") if err != nil { log.Fatal(err) }
How long till most people will target 8? I think we will wait for at least a few patches first.
[0] http://docs.oracle.com/javase/8/docs/technotes/guides/jweb/c...
It has been feature frozen for a long time and even the pre-release builds have had a lot more testing and stabilisation than other software that people don't think twice about using.
There is of course a risk adopting new technology early, it depends what kind of things you are building/running.
http://www.webupd8.org/2012/01/install-oracle-java-jdk-7-in-...
Pretty cool stuff! I hope someone makes an easy way to render FB react modules on the server without relying on a separate Node.js process.
If you have an environment where you need a full client, and the developer is trusted, use Webstart: You have to actively accept something on Webstart. If you do not trust the developer, make the interface in a regular webpage.
Dalvik does have support for all Java 7 features: http://tools.android.com/tech-docs/new-build-system/user-gui...
Dalvik will most likely be replaced with ART (Android Runtime) at some point: http://source.android.com/devices/tech/dalvik/art.html
ART has been in the works for at least two years now.
It's silly to compare Java8 with Java1.4? 1.3? from 2001.