Yes indeed. Porting code is also a great way to learn a language. And you learn a lot about idioms and patterns on both sides. Go innovated quite a bit in terms of simplicity. However, they also did a few things that they are now trying to fix like having generics and exceptions. Lack of overloading is something that I miss in other languages as well. E.g. in Javascript you often end up with these type checks to sort of fake things. These often get added defensively because the lack of typing just causes people to call things with the wrong types and it is common for that kind of code to not be noticed (fixed a few such issues when introducing typescript recently).
A lot of stuff in Java is just because (by now) it has a lot of history and baggage. JavaBeans were kind of cool back in the late nineties but mostly it's a really annoying convention by now. The notion of accessors is not obsolete but unfortunately was not part of the language design when they created Java. Since Java has reflection, they came up with naming conventions that allow code to inspect object instances and do things with properties based on naming conventions. This has been key to a lot of the Java enterprise stuff that happened after this. And it also facilitated creating UI builders that came with IDEs like jbuilder, netbeans, visual cafe, etc. when having a UI builder was still a base requirement for an IDE. Eclipse sort of broke that tradition by not including one (initially).
These days UI builders are basically very uncommon; which makes javascript frontend work particularly tedious and repetitive. Because there are no conventions, no typing, and quite often no meaningful test coverage in JS, it is basically impossible to deal with that in a UI tool. So, accessors matter and are not obsolete at all.
Most modern languages have more elegant ways to do essentially the same type of accessor mechanisms in the language. And also languages like Smalltalk had this (as well as UI building tools, refactoring, and a lot of other stuff that is still science fiction in the javascript world).
If you look at Kotlin, they fixed this while retaining the ability to expose code back to Java.
For example kotlin has properties with accessors that you can optionally override. Normally you just type val foo="bar" and you have a string property with an inferred type of String. The setters/getters generated under the hood and used automatically when you assign or use the variable. If you want you can customise the accessors or use something called delegated properties that e.g. turn a property getter into a function or use lazy intialization. Once compiled, a java class that uses that code would see the normal setters and getters as if it was a normal Java class. Likewise when accessing Java code from Kotlin you use java properties as if they were normal kotlin properties (i.e. without using setFoo(foo)/getFoo()). This makes Kotlin a really nice way of using legacy Java code.
I’ve been diving deep into Kotlin lately and I am now convinced that Kotlin is the next evolution for Java codebases and the JVM. It fixes a lot of the quirks in Java with great interop support so we can still use all the jvm/Java knowledge,libraries,performance in a more modern, more ergonomic and safer language.
I agree. I wonder how well the transpiler in IntelliJ works. I'm using Kotlin in my spare time a bit in a maven sub-module of a project, but used it from scratch (because of the great interoperability with Existing Java Code). I'd love to switch to it in other modules as well (still Java code), but wonder if it generates idiomatic Kotlin code out of the box, but maybe not. That said I'm a Kotlin beginner, but it seems everything from Effective Java is so much easier with Kotlin and the defaults are simply better.
Yes, the converter gets you eighty percent of the way there. Usually it is a bit too conservative and e.g. biased towards making all types nullable because it is hard to reason about nullability in Java. In the same way it attempts to turn any method starting with the prefix get into a property, which does not always make sense when it is clearly a bit of business logic instead of a property. Finally, it seems to slab a lot of redundant generic type hints on things, which don't always work. As soon as you remove them, Kotlin's type inference usually gets it. So I typically spent a minute cleaning up after converting a file.
After that you get to the idiomatic stuff like e.g. making properties read only getting rid of multiple constructors by introducing default parameters. Getting rid of the builder pattern (mostly redundant in kotlin), introducing data classes where that makes sense, using lateinit vars to make nullable vals nonnullable, etc. Technically you are at that point improving things.
A lot of stuff in Java is just because (by now) it has a lot of history and baggage. JavaBeans were kind of cool back in the late nineties but mostly it's a really annoying convention by now. The notion of accessors is not obsolete but unfortunately was not part of the language design when they created Java. Since Java has reflection, they came up with naming conventions that allow code to inspect object instances and do things with properties based on naming conventions. This has been key to a lot of the Java enterprise stuff that happened after this. And it also facilitated creating UI builders that came with IDEs like jbuilder, netbeans, visual cafe, etc. when having a UI builder was still a base requirement for an IDE. Eclipse sort of broke that tradition by not including one (initially).
These days UI builders are basically very uncommon; which makes javascript frontend work particularly tedious and repetitive. Because there are no conventions, no typing, and quite often no meaningful test coverage in JS, it is basically impossible to deal with that in a UI tool. So, accessors matter and are not obsolete at all.
Most modern languages have more elegant ways to do essentially the same type of accessor mechanisms in the language. And also languages like Smalltalk had this (as well as UI building tools, refactoring, and a lot of other stuff that is still science fiction in the javascript world).
If you look at Kotlin, they fixed this while retaining the ability to expose code back to Java.
For example kotlin has properties with accessors that you can optionally override. Normally you just type val foo="bar" and you have a string property with an inferred type of String. The setters/getters generated under the hood and used automatically when you assign or use the variable. If you want you can customise the accessors or use something called delegated properties that e.g. turn a property getter into a function or use lazy intialization. Once compiled, a java class that uses that code would see the normal setters and getters as if it was a normal Java class. Likewise when accessing Java code from Kotlin you use java properties as if they were normal kotlin properties (i.e. without using setFoo(foo)/getFoo()). This makes Kotlin a really nice way of using legacy Java code.