Java for Everything (2014)
teamten.com
teamten.com
I really like Javascript, so I've been using Facebook's Flow type checker, and it's been great. I was already using Babel (with Browserify), so nothing about my build process even needed to change. It makes it easy to gradually add type-safety to a codebase. It doesn't get in the way of common Javascript patterns. Callbacks are still lightweight, but well-typed. I can still bypass the type-safety and monkey-patch a property onto an object while I'm testing something.
More like user posts complex JSON object, which takes me seconds to parse into a Python data structures, and hours or days to figure out complex mappings into Java classes. It's often the mapping of objects to serialized forms is where a huge amount of time gets spent in statically compiled languages. And it's NOT just a once of investment - those mapping change in future and some poor soul is going to have a fun time modifying your Java app, no matter how well named your variables are.
If you are writing glue code or IO bound web servers without a high performance requirement, the difference in productivity between Python and Java is not at all trivial.
If you're willing to settle for no type safety, there are untyped Java APIs like Jackson's tree API [1] that are, while definitely more verbose than Python's, similarly productive in my experience—and much, much faster.
[0] http://www.jsonschema2pojo.org/ [1] http://wiki.fasterxml.com/JacksonTreeModel
Check out Scala :) Its a pretty complex language, but its the sweet spot between Python and Java i've been looking for.
I actually just had the experience of starting a project in Go, and after a prototype the company decided to reboot it in Java (for business and not technical reasons, basically the project started as a server and ended up being a library, so language popularity matters). It took me a lot more code and time to get the Java implementation to where my Go prototype was.
It might just be me, but in terms of a sweet spot between being productive and having high performance, Go is the best of both worlds. It's on par with Java in terms of performance, and slower than python to write - but not as much as Java (and for big projects I suspect you end up more productive in Go than in Python).
A lot of my time is spent writing and reviewing Java code, which I still enjoy a bit.
http://stackoverflow.com/research/developer-survey-2016#tech...
http://stackoverflow.com/research/developer-survey-2016#tech...
Author is a douchebag
> Scala is too complex. And other languages like D and Go are too new to bet my work on.
So in the end you're talking about your work - the right language for the job.
Maybe Java is good for everything at your job, but not that good for most things at mine.
I prefer C++ over Java every single time.
Not because of the more power that it gives me, but because I'm experienced with it and I can get the job done.
I would use Javascript for a web application and Swift or Objective-C for an iOS app. And I can't imagine doing that with Java.
I have a few others I'd prioritize over verbosity:
- Generics
- Dependency conflicts
- Libraries that simply "fix" the language, i.e. Apache Commons, Google Guava
Disclaimer: your mileage may vary. This is simply my personal pet-peeve list.Map<String,User> userIdMap = new HashMap<String,User>();
is now just:
Map<String,User> userIdMap = new HashMap<>();
and Java Generics already saves a ton of type casting as well as checks and corrections IMO.
val userIdMap = new HashMap<String,User>();
Python can have similar issues, even with virtualenv.
For this reason, I tend to use Go these days. It completely avoids this cost. Also, unlike Java, any tools start up instantly and don't need to 'warm up'.
Or just buy one of the many AOT compilers available.
Not that I think Java should be used for everything.
Short list of TP 6.0 features in 1993!
- Real type safe enumerations
- Proper strings and vectors
- modules (units)
- Fast compilation (seconds)
- OOP
- Type safe reference parameters
- inline assembler, naked functions, absolute addresses, pointer manipulation functions, customizable memory allocator, overlays, procedure/function variables for systems programming tasks
C++ was already picking up steam in Windows and Mac OSes and with CORBA and DCOM for enterprise systems, the precursors to J2EE.
If it wasn't for the widespread of FOSS software based on UNIX and C culture, C would have slowly faded out.
(0) Compiler: Super-fast compilation times, unlike Visual C++; and super-fast generated executables, unlike Visual Basic.
(1) Libraries: Borland's VCL was vastly more sophisticated than either Visual Basic's controls [underpowered toys] or Visual C++'s MFC [barely more usable than the Windows API itself].
(2) Core language: Of course, from Pascal, Delphi inherited a real module system [not C++'s `#ifndef` nonsense], real strings [not C++'s `std::string`, let alone MFC's `CString` nonsense] and real dynamically allocated arrays [not C's pointer nonsense, although C++'s templatized containers hadn't taken off yet]. And Delphi's object system was something a normal human being could actually hope to understand, unlike C++'s multiple virtual inheritance mess.
Despite its many flaws, C/C++ is something you can use everywhere. You can write same piece of code to run on practically all possible platforms. Any mobile device, desktop environment, microcontroller, it's even possible to compile it to run on a web browser.
Writing libraries in Java has one gigantic flaw: those libraries can only be used in JVM languages. Sure, you could use RPC or use JNI. But those solutions are often completely impractical.
Edit: Fixed last sentence to be as originally intended, added word "often".
You can do loadable plugins in Java very nicely. If you're using Java for everything then the calling code is also Java and it works great.
> Can't write kernel drivers in Java.
Not if you need them to run in-process in an existing non-Java kernel, no - but that goes back to "use the same language for everything you do". (And IME drivers rarely actually need to be in-kernel).
> Impractical for most embedded applications.
People told me this six years ago when I was developing for a low-power ARM, and when I actually tried it I found it was complete nonsense - a lot of embedded CPUs had more than enough power back then to run Java, and they've only got faster since.
> Despite its many flaws, C/C++ is something you can use everywhere. You can write same piece of code to run on practically all possible platforms. Any mobile device, desktop environment, microcontroller, it's even possible to compile it to run on a web browser.
Sure, that's an advantage. But how often does it apply in practice? I'd far rather have low-defect-rate code that I can run on the platforms I care about than buggier code that can also run on some more obscure platforms.
> Sure, you could use RPC or use JNI. But those solutions are completely impractical.
Depends entirely on what you're doing. For many use cases they're perfectly adequate.
JVM classloader based libraries generate a lock-in effect. Those libraries you write are destined to be used almost exclusively from another JVM bytecode blob.
> People told me this six years ago when I was developing for a low-power ARM, and when I actually tried it I found it was complete nonsense - a lot of embedded CPUs had more than enough power back then to run Java, and they've only got faster since.
I'd like to see how a Java based IRQ handler looks like. Or (gather/scatter) DMA and memory mapped I/O. Can Java have same realtime characteristics AND same or lower memory RAM/flash overhead as a C/C++ based solution? Cost per unit matters.
> ...I'd far rather have low-defect-rate code that I can run on the platforms I care about than buggier code that can also run on some more obscure platforms.
This is why I have high hopes in Rust. If you can't run on those "obscure" platforms you're required to run, then you need to write the code twice. How's that a good thing?
>> Sure, you could use RPC or use JNI. But those solutions are completely impractical.
> Depends entirely on what you're doing. For many use cases they're perfectly adequate.
Well, now you're not just shipping a 200 kB dll, but also a JVM bridge of some sort (RPC or whatever), plus you need to vendor whole JRE in your installation package. 100 MB+, much higher runtime memory consumption and debugging challenges the bridge causes. How's this better?
Sure, but it's the same for C, or any other platform. (I mean, many languages have FFIs into C libraries, but they generally have APIs that are not at all natural for that language).
> I'd like to see how a Java based IRQ handler looks like. Or (gather/scatter) DMA and memory mapped I/O. Can Java have same realtime characteristics AND same or lower memory RAM/flash overhead as a C/C++ based solution?
None of that sounds impossible, or even necessarily much harder than it is in C. It won't look much like mainstream idiomatic Java, and it will involve a lot more bookkeeping - but so would doing it in C.
> Cost per unit matters.
It does, but so do development time and defect rate.
> If you can't run on those "obscure" platforms you're required to run, then you need to write the code twice. How's that a good thing?
I'm not advocating writing the code twice. If your code needs to run on a particular platform, you choose a language that you can find a way to make run on that platform. It's just that in my experience of the business circumstances (which are specific to my field, sure), "I might one day have to port this to a platform that you can't run Java on" is a long long way down the list of risk factors.
>Well, now you're not just shipping a 200 kB dll, but also a JVM bridge of some sort (RPC or whatever), plus you need to vendor whole JRE in your installation package. 100 MB+, much higher runtime memory consumption and debugging challenges the bridge causes. How's this better?
Those aspects are not better, but they're often an insignificant cost compared to the quality benefit you get from Java.
Few things:
- you can write the example if, elif, etc. in any language that supports pattern matching (dynamic or static) safely, it has nothing to do with type systems at all
- spinning up the JVM for CLI is still largely unsolved problem, this is why Python or Go is used for CLIs more
- verbosity does not matter? Seriously, the most annoying part of Java is verbosity, that fosters a mindset that it does not matter how long is something. In that verbose code we can hide few things: bugs and more bugs.
- not knowing anything else than Java and Python, even in 2014 is silly
I think there are many better solutions for the problems he mentioned in the article.
Only by those that ignore that there are quite a few Java AOT compilers to native code available.
The OpenJDK isn't the only option out there.
# Map from user ID to User object.
userIdMap = {}
Or as I would write this: userIdsToUserObjects = {}
Ctrl + n in vim completes this easily, so I don't care how long the name is.I agree about the general point of the article, being strong in one language, but poor naming will bite you in any language. Comments are apologies for bad code: only write comments when you can't write better code.
messagesByUser = {}
Is the key a user id, username, a user object, some sort of stripped down user hash, what? What about the messages? If you try to cram all this information into the variable name then you've invented a perverse form of hungarian notation. And of course you lose all that precious type information every time you pass it off to a function.Python is my go-to crutch for quickie projects that will never grow beyond a few hundred lines of code. Anything more complicated needs a typechecker. I only wish Java's was more robust.
> (python is) the wrong tool for code of any size written for pay, because you’re doing your employer a disservice
> For these scripts I decided to use JavaScript, primarily because it’s included in Java 6 and secondarily because many people know it
Apache Groovy isn't included in Java, and there's many incompatibilities between it and Java (e.g. behavior of ==), so perhaps that's why it lost out to Javascript for scripting.
The author should start writing a game in java.
The author should start writing a heavy matrix calculations in java.
The author should start implementing a small command-line tool ine java (grep?)
All these use-cases is where Java fails miserably.
Pick to right tool for the job. Is still the right answer.Minecraft did alright...
I'd like to add, though, that I don't generally see a problem with programming games in Java. I just prefer C++ for that, with portability being only one of the reasons.
Virtually any cheap phone (non-smartphone) comes with Java ME available. Nowadays you find Android and the millions of Java-based games on the play store.
League of legends
> The author should start writing a heavy matrix calculations in java.
https://devblogs.nvidia.com/parallelforall/porting-gpu-accel...
> The author should start implementing a small command-line tool ine java (grep?)
Later I noticed that Java teams did not get things done quick.
My android phone stutters while playing music. (No it's not packed with apps, there is at least 200mb RAM free)
Really, Java is just a tool. Language is familiar to anyone, performs good and libraries exist for just about everything.
The only reason we don't use C is because we'd require end-users to correctly pick different binaries and because the IDE for developing C is quite a pain (don't want to start a fight here, it is just pain when compared to Java).
So, let the cool kids play with Ruby and Go. Some of us just need to get things done.
- the use of the Object type (surprisingly common)
- No first-class functions or function types. New Java has lambdas but I'm not sure if it has function types or the ability to pass a class or instance method as a first-class value
- No higher-order types (e.g. The type of a map function, let alone an fmap function, can't be written)
- Need for frequent casting is both inelegant and a big source of errors
- Classes are giant, heavyweight and deeply stateful, and tend to have deeply nested hierarchies
- Class-scoped variable names (E.g. That don't require explicit 'this') are confusing, and for example don't make it clear whether a variable being referenced is a class variable, instance variable or local variable. Creating inner classes complicates things further, and inherited variables and methods are also opaque
- creation of new types is a pain which promotes overuse of primitives (ints/strings/bools) over more expressive and safe types
- polymorphism via interfaces isn't particularly expressive, for example AFAIK you can't make a function which takes two arguments of the same type unless you specify that type precisely
- null pointers are rampant, and even considered idiomatic, for example during initialization
- imperative style is forced on the user in a very strong way; for example no literals for array lists, maps etc, standard library overwhelmingly provides mutable data structures.
I could go on, but suffice it to say that the author's claim that the main complaint against Java is its verbosity is a red herring.
It's also a bit disappointing to see him dismiss languages like Scala (and presumably languages like Ocaml and Haskell, which he doesn't even mention) due to being "complex", which suggests to me that he hasn't fully grasped his own lesson that putting the time and effort into a safer, more expressive and more strongly typed language is worth the initial trade off in productivity. Although the author claims that once their code compiles it usually runs without errors, this has definitely not been my experience. Indeed my biggest argument against Java is that due to its imperative nature and inexpressive type system, it's not that much safer than many dynamic languages, which makes it really hard for me to justify using it.
Heck, I've tried hard to understand Haskell. Simply don't understand why someone goes through the effort of using that exotic language. The old library was taking 2 minutes to process input, the re-written version in Java took 3 seconds.
Just keep it simple, use Java.
That being said, yeah, Haskell's learning curve is quite steep, and writing high-performance code in it is kind of a black art.
Hey, it's possible to dismiss Scala due to being “complex” (which is certainly is), and still like (or at least not dismiss) OCaml and/or Haskell. :-p
> - the use of the Object type (surprisingly common)
Doesn't appear common to me at all - the code base I work on has no declaration of anything as 'Object' anywhere in well over 300k lines. None of the 3rd-party libraries we use have the Object type in any of their public APIs. So from my experience this is a non issue, and I'm quite surprised it was mentioned. Then again, I do work on a relatively new (<4 yrs old) code base, recently moved to Java v1.8.
In fact, probably the biggest offender of Object use is the Java built-in libraries, especially the Collections framework, parts of which are frustratingly not type-safe as a compatibility hangover from before generics were introduced. For a fun example, the map interface has put(K, V), but get(Object). Grrr!
> - Need for frequent casting is both inelegant and a big source of error
Again, the code base I work on has very little casting. I feel like this is more a symptom of how code has been designed rather than an inherent issue with the language. Once more possibly a hang-over from the pre-generics days.
> - Classes are giant, heavyweight and deeply stateful, and tend to have deeply nested hierarchies
This seems a bit subjective, so I'd say you might be writing/using classes badly. How does Java differ from any other OO language in this respect? And remember the words of The Great Joshua Bloch: always favour composition over inheritance!
> - Class-scoped variable names (E.g. That don't require explicit 'this') are confusing, and for example don't make it clear whether a variable being referenced is a class variable, instance variable or local variable. Creating inner classes complicates things further, and inherited variables and methods are also opaque
A moot point when using a modern IDE as far as I see it. But certainly a concern if syntax highlighting isn't available.
> - creation of new types is a pain which promotes overuse of primitives (ints/strings/bools) over more expressive and safe types
How/why exactly is this a pain? Related to the verboseness, perhaps? And certainly in the code I work on I wouldn't consider primitives over-used at all. Don't forget the Java enum, one of the best features of the language, can quickly be put together and contain as much extra information/functionality as you'd like. We certainly use them frequently.
> - null pointers are rampant, and even considered idiomatic, for example during initialization
If null pointers are this rampant, then again the code must be badly designed or doing something wrong. Null pointers are probably the least common issue we get in our code base. Of course I can only speak for myself. The Optional in Scala does sound like a brilliant feature, but doesn't demonstrate why Java is any worse than other non-Scala OO languages (here's looking at you C#).
> - imperative style is forced on the user in a very strong way; for example no literals for array lists, maps etc, standard library overwhelmingly provides mutable data structures
I can't argue with this. Mutibility in the standard libraries isn't great and parts of it certainly could do with a re-write (which worked out totally fine for Python, amiright?) and generally there are few few 'correct' ways to write anything (I'm ignoring the monstrosity that is Java EE here).
But this is an aspect of the language I actually really like. I like the verboseness, I like the lack of ambiguity, and I like that all well-written Java code looks remarkably similar. If dev teams enforce strict (and at least partially arbitrary) style rules, what's wrong with the language doing it for you? If you think that's a bad thing then I'd be very interested to hear your reasoning.
There are lot more, but this is one which irritates me the most.
It is good practice for methods to return an Optional instead of null if you can't guarantee a non null value.
Different tasks require different languages. It's not possible to pick just one. Most people gave this moron the right answer, and yet he failed to comprehend it.
And this pathetic cretin clearly never ever seen a truly expressive language. Likely, he never seen anything besides his pathetic Java and stupid Python.