Comparing to dynamically typed languages (and even to statically typed languages using a lot of type inference) is a little tricky, because in some cases "verbose" means you have information available locally that you would otherwise have to look up elsewhere.
This is absolutely true, especially with Java 8.
Learning where things are in the stdlib for Java is different, but not harder than Ruby IMO. Where is MD5 in Ruby? Or DateTime?
I can and do code Scala in ST2 on occasion. Mostly for gists. IntelliJ just makes working on bigger codebases nicer.
Anyways, just an opportunity to say: You don't necessarily have to trade in performance and verbosity. You can get a relatively succinct language, with much better performance, and still enjoy the ecosystem.
For instance, Scala and Kotlin.
I assume it stems from Coldfusion and it being popular around the time of the rise of Java, but to continue that tradition nearly 20 years later of XML templating/configuring everywhere just deters professional developers of nearly any other language.
There are some non J2EE Java frameworks that try to remedy the faults of J2EE, but it's kind of given Java on the web a bad rap.
JSF2/Facelets replaced JSP in the most recent JEE standards and is much nicer to work with.
I mean JEE 1.6 was released 4 years ago (around the time of Rails 2.0). For a standard that is not bad.
We actually use a lot of apache wicket which is a very nice framework for website/applications.
Agree 100% about Java's verboseness. I really want type inference, lightweight objects, properties (vs JavaBean accessor convention), switch for 'instanceof', etc.
However. Java's verbosity is nothing compared to the verbosity of the common APIs and frameworks. All that DI, IoC, configuration via markup, etc. are terrible efforts to make Java more like a dynamic programming language. Even the built in APIs have design pattern-itis, with types, hooks, hierarchies aplenty.
Yep, Intellij IDEA does it pretty well, or one can get their language of choice individually as WebStorm (JavaScript/NodeJS), PHPStorm (Webstorm + PHP), PyCharm (Python + Webstorm) or RubyMine (Ruby + Webstorm).
The refactoring and type inferring abilities for dynamic languages in each are pretty amazing. Types can also be inferred by docblocks and return types as well in each IDE for code analysis to avoid silly mistakes. That, along with refactoring has saved me tons of time and a reason to use a full IDE over a more lightweight editor. They also have an open source version of the Python IDE if you want to try it out.
I believe you're asking for Scala. For example, switching on types:
trait Foo
class Bar extends Foo
class Baz extends Foo
val thing = // could be either bar or baz, don't know
thing match {
case f: Foo => println("Got foo")
case b: Bar => println("Got bar")
}Our study group has done two Scala tracks (and currently studying Akka and reactive programming).
Ruby and Scala make my head hurt. I don't have a mental model for what's happening under the hood. Unlike LISP, Forth, Java, etc.
I really do want a refined, simplified Java. My wishlist of features are gleened from Boo (minus the duck typing), Nice, and Kava (lightweight objects).
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.3...
Honorable mention for Frink (preserves units).
I think that what you're really looking for is Kotlin: http://kotlin.jetbrains.org/
On the other hand, it suffers from not having a big ecosystem.
I don't have to change my workflow at all between working in Python, C, Go and JS. I can use vim for all of the above and none of them force me to have years of experience with an IDE in order to be productive.
It does have one advantage over the JVM, which is a much shorter startup time. But Java has better performance and far better monitoring tools (as well as dynamic linking and hot code swapping).
Objects vs structs and functions, exceptions vs multiple return values, required static vs required dynamic linking, implicit vs explicit subtyping/interfaces, etc.
Go is C with added convenience.
Exceptions vs. multiple return values are two different local decisions made by Go's designers: multiple return values and lack of exceptions. Multiple return values are handy (might find their way to Java one day), but I would call that a feature, not a different approach. As for exceptions, it is my understanding that Go's designers haven't made a final ruling on the subject.
Static vs. dynamic linking are properties of the runtime (native vs. VM) rather than the language. In principle, both Go and Java could support either without any language changes.
Go is most certainly not like C, because C's philosophy is letting the programmer work at the same level as the CPU. Go, if anything, is further removed from the hardware than Java (no explicit control over threads or scheduling, no access to memory fences).
Go's designers have said that they wanted to experiment with a more direct approach to memory in exchange for a less advanced GC.
So, you are right that in terms of memory placement issues, Go is more low-level than Java, but it's higher level when it concerns scheduling. All in all, it places them pretty much at the same level. It certainly doesn't make Go closer to C.
Go tends to be written like a low-level language with very good high-level libraries. You don't have huge class hierarchies; instead you have functions. You don't have a million custom exception types; you just return error codes. Go is obviously closer to Java with respect to some of the things you can do with those concepts (things like switch statements being very general are features of much higher level languages than C, etc.), but as a programmer, you're still writing a switch statement, not a series of polymorphic methods dispatched at runtime. That's what I mean -- Go is very, very unlike Java if you're writing idiomatic code in each.
First of all you have this on about every second line:
if err != nil {
return err
}
Method signatures are convoluted because you have to repeat the receiver type for every single method and add (actualReturnType, error) at the end.Go:
func (MyType* mt) myMethod(s string, i int) (string, error)
Java: String myMethod(String s, int i)
For functions you want to use in expressions you need a second one that calls the first one and panics instead of returning err.You can't specify default values for structs, so you often need an extra function that constructs a default instance of the struct and initializes its fields.
And the lack of generics means you have to write a lot of things several times for different types.
Lambdas are very verbose as well. You get no type inference even in contexts where it would be simple to do:
Go:
filter(func(s string, n int) { return len(s) < n })
Java 8 (Scala is similar): filter((s, n) -> s.length < n)
Function names often have to be longer because there is no function overloading.Go's simplicity is a double edged sword. Lack of verbosity is definitely not its strength.
Obviously there are many counter examples where Java is more verbose than Go. But they are very well known by now so I'm not going to repeat them here.
I admit that if I just need to review a single file or knock an R script together I will launch Sublime. This is almost exclusively as a result of launch time ... nothing more. Good IDEs tend to get out of your way - whilst offering you advanced visualisation, debugging and reporting for when you, ... you know ... have to work with other people.