Gradle could be used as an AI benchenmark on its own! The syntax of plugin DSLs changes all the time. Special credits could be achieved for handling old (Groovy) and new versions (Kotlin) of Gradle itself.
However, the cause it not really Java as such, but massive frameworks and tooling (e.g. Maven). Maybe AI will bring some fresh air to Java, because old truths might no longer be valid. But it will be hard to get rid of old habits because it manifested in AI training data.
My takeaway is that Go almost always prefers simplicity and not so much good software engineering. `nil` without compiler checks is another example, or designing a new language without generics. However the overall simplicity has its own value.
I agree, its strength (beyond goroutines) is that anyone who knows one of the popular languages (Python, Java, etc) can easily translate their idioms and data structures to Go, and the code would remain easy to read even without much Go experience. That's probably one reason why the TypeScript compiler team chose Go.
But this makes the language feel like Python, in some ways. Besides nil, the lack of expressivity in its expressions makes it more idiomatic to write things imperatively with for loops and appending to slices instead of mapping over the slice. Its structurally typed interfaces feel more like an explicit form of duck typing.
From what I remember of a presentation they had on how and why the made Go, this is no coincidence. They had a lot of Python glue code at Google, but had issues running it in production due to mismatched library dependencies, typing bugs, etc. So they made Go to be easy to adopt their Python code to (and especially get the people writing that code to switch), while addressing the specific production issues they faced.
> he popular languages (Python, Java, etc) can easily translate their idioms and data structures to Go, and the code would remain easy to read even without much Go experience
disagree, they made many decisions which are different from mainstream: OOP, syntax as examples.
Sure, the syntax is unique, but it's fairly easy to get over that. I guess I'm comparing to Rust, where not only is syntax different, but data structures like a tree with parent references aren't as straightforward (nor idiomatic), and there's a lot more explicit methods that requires knowing which are important and which are just noise (e.g. unwrap, as_ref).
I would argue that after a short tutorial on basic syntax, it's easier for a Python/JavaScript programmer to understand Go code than Rust.
to me Rust syntax is less alienating, they adapted ML syntax which is probably second most popular(scala, typescript, kotlin) after C style syntax, while Go from whatever reasons got something totally new.
Which aspects of Rust syntax are adapted from ML? Semantics sure, but to me the syntax seems a lot more similar to C++ (e.g. semicolons, type parameters using <>, etc.)
For some uses, that's all you need, and having more features often detract from your experience. But I'm doubtful on how often exactly, I have been able to carve out a simple sub-language that is easier to use than go from every stack that I've tried.
I think of it as a bit like Python with stronger types.
I'm not convinced that you couldn't have good software engineering support and simplicity in the same language. But for a variety of mostly non-technical reasons, no mainstream language provides that combination, forcing developers to make the tradeoff that they perceive as suiting them best.
I don't like Bitwarden UI/UX. It looks not really polished. Especially the "folders" are akward. How the implemented it, calling them labels and designing them like labels would make way more sense. But the whole UI looks like software developers - and not designers - built it.
I think I tried using it maybe 4 years ago or so, and I had the same feeling. It just felt.. awkward to use, lots of friction. I was hoping it had changed by now, but I guess that hasn't happened.
yes, but that's just one part of the equation. machine code from compiler and/or language A is not necessarily the same as the machine code from compiler and/or language B. the reasons are, among others, contextual information, handling of undefined behavior and memory access issues.
you can compile many weakly typed high level languages to machine code and their performance will still suck.
java's language design simply prohibits some optimizations that are possible in other languages (and also enables some that aren't in others).
> java's language design simply prohibits some optimizations that are possible in other languages (and also enables some that aren't in others).
This isn't really true - at least not beyond some marginal things that are of little consequence - and in fact, Java's compiler has access to more context than pretty much any AOT compiler because it's a JIT and is allowed to speculate optimisations rather than having to prove them.
It can speculate whether an optimization is performant. Not whether it is sound. I don't know enough about java to say that it doesn't provide all the same soundness guarantees as other languages, just that it is possible for a jit language to be hampered by this. Also c# aot is faster than a warmed up c# jit in my experience, unless the warmup takes days, which wouldn't be useful for applications like games anyway.
Precisely right, but the entire point is that it doesn't need to. The optimisation is applied in such a way that when it is wrong, a signal triggers, at which point the method is "deoptimised".
That is why Java can and does aggressively optimise things that are hard for compilers to prove. If it turns out to be wrong, the method is then deoptimised.
There's no aliasing in the messy C sense in Java (and no pointers into the middle of objects at all). As for other optimisations, there are traps inserted to detect violation if speculation is used at all, but the main thrust of optimisation is quite simple:
The main optimisation is inlining, which, by default, is done to the depth of 15 (non-trivial) calls, even when they are virtual, i.e. dispatched dynamically, and that's the main speculation - that a specific callsite calls a specific target. Then you get a large inlined context within which you can perform optimisations that aren't speculative (but proven).
If you've seen Andrew Kelley's talk about "the vtable boundary"[1] and how it makes efficient abstraction difficult, that boundary does not exist in Java because compilation is at runtime and so the compiler can see through vtables.
But it's also important to remember that low-level languages and Java aim for different things when they say "performance". Low-level languages aim for the worst-case. I.e., some things may be slower than others (e.g. dynamic vs. static dispatch) but when you can use the faster construct, you are guaranteed a certain optimisation. Java aims to optimise something that's more like the "average case" performance, i.e. when you write a program with all the most natural and general construct, it will, be the fastest for that level of effort. You're not guaranteed certain optimisations, but you're not penalised for a more natural, easier-to-evolve, code either.
The worst-case model can get you good performance when you first write the program. But over time, as the program evolves and features are added, things usually get more general, and low level languages do have an "abstraction penalty", so performance degrades, which is costly, until at some point you may need to rearchitect everything, which is also costly.
I mostly do dsp and control software, so number heavy. I am excited at the prospect of anything that might get me a performance boost. I tried porting a few smaller tests to java and got it to c2 some stuff, but I couldn't get it to autovectorize anything without making massive (and unintuitive) changes to the data structures. So it was still roughly 3x slower than the original in rust. I'll be trying it again though when Valhalla hits, so thanks for the heads up.
Although there's no doubt that the lack of flattened object is the last remaining real performance issue for Java vs. a lower-level language, and it specifically impacts programs of the kind you're writing. Valhalla will take care of that.
As others already pointed out, UUIDv7 is a solid choice and if you don't like the default representation, you can encode the underlying byte array with base62 for example, to get short, URL-friendly IDs.
reply