Hacker News new | ask | show | jobs
by deepaksurti 2228 days ago
> Not always, though. See every bug and exploit with C arrays ...

That can also be perceived as a a flaw of the language design in that it does not allow one to write dumb, safe and fast code. Which are such languages in existence today?

edit: fixed typos

4 comments

I would say Java, which I suspect is bound to be a bit of an unpopular opinion here (I expect more startup people than enterprise denizens in HN); but the more I think about it, the more sure I'm that it fits the bill:

- Dumb: you bet. The inclusion of lambdas has shaken things a little, but usually Java code is straightforward with little space for "cleverness". The counterpoint to this, of course, would be the memes about AbstractFactoryFactoryImplementationSubclassDispatcher class names and all that, which IMHO does not represent much actual Java code out there. There are good reasons why big corps prefer Java, and readability is one of them. As a programmer, I've found it easier to jump into a Java codebase I didn't know much about than in any other language. And this has happened even when I had little experience in Java.

- Safe: yes. You have to go out of your way to be unsafe in Java. Memory allocation is done for you and the try-with-resources idiom is almost as good as C++ RAII.

- Fast: also yes. Usually about 2x or 3x the run time of C/C++ code, some times even less.

> Fast: also yes. Usually about 2x or 3x the run time of C/C++ code, some times even less.

not commenting on the Java part as I believe it's usually faster than that (though not so sure when you see the years of hoops that Minecraft java had to go through to stop being so damn slow all the time...) , but it's kinda frustrating to be fighting for microseconds almost daily and then hear people saying that 2x slower is fast... 2x slower means going from 100fps to 50fps which ... well, gets you fired ?

I know this thread is about game development, but not everyone has hard deadlines to churn out frames. The comparison is useful because it separates Java from many other languages that are possibly 10x slower, which make them unsuitable for a huge number of domains where Java can still be useful.
While Java isn't perfect, it was more lack of skills of Minecraft developers than anything else.

Using classes for everything with a full OOP approach, instead of DOA and ECS, with tons of new in hot paths, no wonder it had performance isuses.

This was discussed in some Minecraft forums,

https://www.reddit.com/r/programming/comments/2jsrif/optifin...

It basically boils down to

> Why is 1.8 allocating so much memory? This is the best part - over 90% of the memory allocation is not needed at all. Most of the memory is probably allocated to make the life of the developers easier.

HFT is as high demanding as games and it makes use of Java, however I think that Java developers with such skills rather have a HFT salary than what game devs earn on average.

How would avoiding GC even work? As far as I know that Valhalla thing still isn't there - wonder if it ever comes. Last I used it, you could only have "structs" together with GC. Maybe there is just no practical way to do this? What prominent examples are there?

I remember a story of a HFT trading software written in Java. Supposedly it had big issues with GC. That's why they built a system where multiple threads would attempt the same operation, and the first thread wins. This approach reduces the likelyhood of a GC ruining the timings. Funny story.

My bachelor's thesis involved writing a software in Java that would manage dozens or hundreds of millions of small objects. These objects were all instances of the same class; the contained only three ints. It was very slow, and especially in an OOM situation the GC would work for more than a minute before finally giving up. I changed the software to use SOA instaed of AOS - moving from a huge array of these objects to three int[] arrays. Since ints aren't boxed, that left me with only 3 objects instead of many millions. The code was uglier for it, but the performance was another world. Unfortunately, such a change is not practical if you have many classes.

That was 5 years ago with Java 8. Disclaimer: I haven't followed Java since then. I know next to nothing about it.

But that is exactly what you do when going after performance in game development, even in C and C++, and it isn't less ugly by using those languages instead of Java.

There is an EA available for Valhalla and there is now the roadmap to incrementally bring such features into the platform. Java 14 has a new native memory support as experimental and it might reach stable already by 15.

https://jdk.java.net/valhalla/

https://cr.openjdk.java.net/~briangoetz/valhalla/sov/01-back...

https://openjdk.java.net/jeps/370

The problem why it is taking so long is engineering effort to keep ABI compatibility, namely how to keep 20 year old jars running in a post Valhala world, while at the same time migrate value like classes into real value types.

Java's biggest mistake, from my point of view, was to ignore the GC enabled systems languages that had value types, non traced references, and AOT compilation from the get go, then again I guess no one on the team imagined that 25 years later the language would be one of the choices in enterprise computing.

Back to Minecraft, the game isn't Crysis or Fortnight in hardware requirements, so a language like Java is quite alright for such game, what isn't alright is what the new development team apparently lacking experience eventually ended up doing to the game engine.

If one is to believe a couple of posts like the one I referred to.

In C and C++ you don't need to make int-arrays. You can group data that is accessed together in structs and keep arrays of these structs.

With regards to performance, there must be some fine art in splitting structs into smaller structs, and keep them as parallel arrays, but there is also a limit to it. At some point you will need too many pointers to point at the same position in all these arrays.

I've never cared to split a lot, since it makes code harder to read. My guideline has always been to optimize for modularization: In OOP there tend to be large objects containing links to "all" related information. That violates the rule of separation of concerns. With parallel arrays you get perfect separation of concerns. One parallel array doesn't even need to know that there are others.

> Back to Minecraft, the game isn't Crysis or Fortnight in hardware requirements, so a language like Java is quite alright for such game, what isn't alright is what the new development team apparently lacking experience eventually ended up doing to the game engine.

I'm not in a position to judge, and I've never even played it, but it seems to me that Minecraft has a lot of voxels to maintain. Also massive multiplayer requirements?

Indeed, despite all criticisms Java as a technology is one of the best things that has happened to the software industry, next to Linux.
Java won because of its humungous and stable standard library with the full backing of Sun (and Sun was huge presence at the time). It was quite a joy to have pretty much all the functions you could ever need (not really but it felt like it at least) at your fingertips without having to do manual dependency management.

As a technology it really didn't have much to give. Object Pascal was born in 1986, Ada in 1980 with language support for design by contract, JIT with Lisp in 1960 and Java came in 1995.

It wasn't just Sun, though they did the heavy lifting marketing-wise. The Apache Project also hopped on the Java train way early and produced a crapton of libraries which made developing internet applications way easier, especially for corporate schlubs who might have been previously exposed to Microsoft (or, ugh, IBM) systems but didn't have acceas to the internet foljlore Unix gurus had.
They did the legwork to figure out browser Applets as well.
Cleverness is more a function of a programmer's habits and attitude than of the language: one tries to be clever in any language.

C++ offers "efficient" ways to be clever, with varied and difficult challenges that can be addressed in relatively little difficult code; some are good or harmless (e.g. aligning struct fields to cache lines or concise towers of useful templates) and some are bad (e.g. flaky homemade not-too-smart pointers and almost-STL-compatible containers).

Java, on the contrary, facilitates the creation of large, boring and easy to read generic object-oriented tumors, that become satisfactorily clever only when they go very far (e.g. one more layer of indirection than everyone else) or reach theoretical limits (e.g. nothing left to invert control of).

- Dumb: you bet.

Java as a language is dumb, but as an overall platform is not. In a way it is a two-layer platform: you have the outer layer, a boring language that is used by a lot of people to write most of the code, then you have a hidden layer, that most people ignore, made of bytecode manipulation, runtime code generation and language agents that let you do cool things like adding compile-time nullness checks, generate mapping classes to avoid writing a lot of boilerplate code or good old ORMs that automatically generate your sql queries for you.

Such functionalities are not exactly easy and straightforward to use, but in my opinion it is a good thing: they are there and can be used, but for most programmers will be hidden behind a few "magic" annotations.

This is in contrast to other languages where the advanced functionalities are "all over the place" and every programmer must be aware of them (I'm thinking of C++ and Common Lisp for example).

If you have a teams of great programmers you may achieve better results with the latter approach, but for the average company the Java approach is better because you can have average programmers write boring code while taking advantage of a few clever tricks here and there by using libraries/frameworks written by better programmers.

Cleverness in this case means:

- Too many jumps in code logic instead of serial logic

- Premature optimization 1: messy code (using lots of unclear variables etc), this is common within calculations, and games have quite some of those.

- Premature optimization 2: failing to properly architect

- Single-character variables. Java IDEs default to fullvars

- Bad function/method names

- Not expressing what you mean (for i= vs foreach)

- Too many abstraction layers / IoC

- Too many sideeffects / complex code (interwoven code)

- Callback hell

Nr 1 is important.. You need to be able to "follow the code". If that requires you to create a DSL in order to code something async in a serial way, then by all means do so.

For example with: network (duh.), but also in games: character dialogs, animations etc. etc.

  The inclusion of lambdas has shaken things a little
I'm curious, do you consider lambdas as more or less "dumb"? Because I consider them the dumbest, simplest and maybe best way to do polymorphism. In a way, OOP's whole shtick was about not using them and instead extend stuff with classes.
It's less dumb than usual Java code in the sense that it's less obvious. Java Lambdas are anonymous, inline implementations of single method interfaces (or abstract classes with a single abstract method). In classic Java you would instantiate an explicit object, from an explicitly named interface (anonymous classes were still allowed, but at least the code would have the name of the implemented interface and the overridden method). This made the code more explicit, therefore more cumbersome but also more obvious. I like lambdas because they make the code considerably less cumbersome but only a little less obvious. But they do make the code a little less obvious, and as such, I would say that they make Java less "dumb".
Golang is a pretty good example.

> The key point here is our programmers are Googlers, they’re not researchers. They’re typically, fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They’re not capable of understanding a brilliant language but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt.

~ Rob Pike

> Which are such languages in existence today?

Zig will be there soon.

Zig first needs to have code samples in the documentation that compile.
It's not really the fault of programmers or the language but pernicious and stubborn failure on the part of the C Standards Committee.