Earlier quoted context omitted.
Golang or Rust. If it’s a web service or microservice: Golang hands down. If it’s a desktop software or game engine, rust. If you just want to typescript your way to success, deno and vite. If you’re too introverted for Rust, Zig. Java, whether it be spring, micronauts, jee, whatever, is wasting CPU and Memory in the cloud costing you and/or your enterprise money.
> Golang golang is probably a good contender for business logic code where Java is widely used, but I feel ecosystem (libs, integrations) is not comparable to Java, so you take some risks while choosing golang.
Java 21 makes me like Java again
461–470 of 777 posts
Re: Java 21 makes me like Java again
#462Earlier quoted context omitted.
I worked with C# professionally. The async/await syntax works with the language's other statements, but for a long time it had gotchas. It doesn't qualify as "structured concurrency", and it has the aforementioned issues — it's (accidentally) error-prone, it splits the ecosystem in two, and has no interruption model. I am not familiar with Swift, but I think you can hardly beat Kotlin's implementation. This is a good…
What do you mean by "it splits the ecosystem in two"? I never observed such split, certain methods intentionally offer sync and async variants. Interruption is achieved through cancellation tokens and has to be handled by consuming methods. There is no way around it because interrupting execution at an arbitrary point would lead to all kinds of issues regardless of the language (unless it implements some form of tran…
That’s a choice, but it is unfortunate for the programmer. The truly right way to do it all is like Erlang does - where all processes are cancellable and nothing bad happens.
Re: Java 21 makes me like Java again
#463Earlier quoted context omitted.
You can’t decide language superiority by the number of features. While C# indeed has many cool features, I do think it has already went into C++ territory where all the different, independently cool features have very non-trivial interactions that make it very hard to reason about. Also, async-await is not a good thing — virtual threads are superior in every way in case of a managed language.
Why async/await is not a good thing? What makes green threads better? Do you know the difference, the issues async/await addresses that green threads simply do not?
Re: Java 21 makes me like Java again
#464Earlier quoted context omitted.
> delivering actual software while you figure out how React 32 broke your transcompiler. Say that to enterprise software systems still running on Java 7 or 8 without any clear path to upgrade because their whole systems will break.
It’s almost like there is even a CS law for this exact scenario.. but Java 8 will be around and will still work 10 years from now, plus it is not an insurmountable task to bump it up to the latest version at all. Tell me literally any platform that has a better backwards compatibility story, because honest to God there is simply absolutely none.
Re: Java 21 makes me like Java again
#465Earlier quoted context omitted.
Unless dynamic linking is used, or OS APIs change between version, or specific OS files change location.
Go binaries are traditionally statically compiled.
Also DNS uses dynamic linking unless configured otherwise, while being OS specific, then that are the libraries that rely on cgo.
Re: Java 21 makes me like Java again
#466Earlier quoted context omitted.
Afaik, no language as great of exceptional handling as Java. I prefer Go but I have to admit, Java's checked exception handling is amazing.
That is an extremely debatable topic. Which is why kotlin completely ignores checked exceptions. Frankly, Id rather have a result and optional/nullable type like in rust/kotlin than deal with exceptions in any capacity.
The correct way to deal with Java’s checked exceptions would have been introducing a Result type, or, preferably, type algebra, like in TypeScript, so something like:
fun openFile(fileName: String): File | FileNotFoundException {…}
Then you could handle it similarly to null: val content: String | FileNotFoundException = openFile(“myfile.txt”).?read()
…then you have to do a check before you use content as a String…
or val content: String = openFile(“myfile.txt”)?.read() ?: “File not found”
(There could also be other possible ways of handling the exception, like return on exception, jump to a handling block, and so on.)In fact, null should be treated as an exceptional value the same way all exceptions should be.
Re: Java 21 makes me like Java again
#467Earlier quoted context omitted.
I worked with C# professionally. The async/await syntax works with the language's other statements, but for a long time it had gotchas. It doesn't qualify as "structured concurrency", and it has the aforementioned issues — it's (accidentally) error-prone, it splits the ecosystem in two, and has no interruption model. I am not familiar with Swift, but I think you can hardly beat Kotlin's implementation. This is a good…
What do you mean by "it splits the ecosystem in two"? I never observed such split, certain methods intentionally offer sync and async variants. Interruption is achieved through cancellation tokens and has to be handled by consuming methods. There is no way around it because interrupting execution at an arbitrary point would lead to all kinds of issues regardless of the language (unless it implements some form of tran…
In Java, you don't need to initialize those "tokens" manually, because the interruption signal is baked into Threads. Moreover, a lot of the standard library cooperates with Java's interruption, which is why you see plenty of methods throwing `InterruptedException`; and it's also reflected in types such as `CancellableFuture` or the `Flow.Subscription` (reactive streams). Of course, user-level code that isn't well-behaved, can end up catching InterruptedException, or resetting the interruption signal, without actually interrupting. This makes Java's interruption model somewhat error-prone, but it's workable, and at least it's baked in.
Note that interruptions could also be preemptive, as you don't necessarily need cooperation. If you think of the call-stack, or flatMap/SelectMany in reactive APIs, the compiled code could check the interruption flag automatically and interrupt the call chain.
And resource leaks aren't necessarily a problem, if the interruption protocol is well-thought-out. In Java, try/finally still works in the presence of interruption, since at worst you get an `InterruptedException`. It's not ideal because you can interrupt the interruption process, and in truth the ideal would be for interruption to be its own communication channel, complementing that of exceptions. But it's totally doable, and here I am familiar with several libraries from Scala's ecosystem, namely Cats-Effect, Monix, and ZIO that show it (with limitations imposed by the runtime).
Either way, what C# provides is basically next to nothing. In fairness, some C# libraries tried fixing it, such as Rx.NET, but it's not enough. And the aggregate result in the .NET ecosystem is that interruption is not something people design for. Like what to interrupt a network socket? This ends up being a setting, presented as a timeout in case of inactivity, as a configuration of the connection, instead of a higher-level generic function that can be applied on the consumer side. And the probability for resource leaks goes up actually, because in the presence of concurrent races, you really need interruption.
Re: Java 21 makes me like Java again
#468Earlier quoted context omitted.
Checked exceptions are gross, they get in the way when you're prototyping, and you end up just ignoring them anyway (since you're prototyping)
The ergonomics of checked exceptions may be debatable but compared to golangs explicit error handling at essentially each function call is definitely worse.
Re: Java 21 makes me like Java again
#469Earlier quoted context omitted.
Go binaries are traditionally statically compiled.
Hence my 2nd and 3rd points. Also DNS uses dynamic linking unless configured otherwise, while being OS specific, then that are the libraries that rely on cgo.
Let me tell you the most common scenario. I have a fairly popular FOSS CLI tool written in Python. I cannot use the features from the latest version of Python or else I will alienate ~50% of the userbase. This problem does not exist with Rust or Go.
This problem would have existed for Java on Android except Google took the burden of "desugaring" the Java 17 code -> Java 8 compatible bytecode for the old devices.
Re: Java 21 makes me like Java again
#470Earlier quoted context omitted.
I don't think any existing Go developer is going back to Java. I worked with Java for 10 years and switched to Go and I will never go back. This is mostly because applications and libraries are so hard to reason about and understand due to inheritance, packaging, OOP, build tools ect compared to Go. Go is simple. It's easy to understand, read, and maintain. The packaging is like how you would package files on your co…
Go has made many decisions that i'm not happy about. If they did one thing exactly right on the language level, it's the [lack of] OOP: interfaces in their implementations, and no inheritance, overridden methods, covariance / contravariance games, etc. You can of course write in Java in that style: only extend interfaces, never inherit classes. But many libraries, including the standard library, actively refuse to co…