Hacker News new | past | comments | ask | show | jobs | submit login

In all other languages I worked in, I basically can keep the entire language (not stdlib) in my head, and it's extremely valuable to understand what's going on. In C++ I just can't.



Without looking it up do you know what are the Java memory model guarantees? Or what's the difference between >> and >>> ?

Even "simple" languages have things that most people simply don't remember without looking it up because it's just not useful to know in day to day work.


> Without looking it up do you know what are the Java memory model guarantees?

* Java is a happens-before language--you need a sequence of X happens-before Y from a write to a read that crosses threads for the language to be well-defined. I'm not going to list the "obvious" cases of happens-before relations.

* volatile variables in Java are sequentially consistent atomic variables.

* 64-bit loads are atomic in the sense that word tearing cannot be observed.

* Writes to a final variable in an object's constructor happen-before the end of constructing an object. (Probably the easiest thing for people to forget)

* There's a bunch of complex rules to try to explain what happens if you violate happens-before and you have a data race. These aren't really right anyways, so you can safely ignore these and pretend it's UB if you do create a data race, which is what happens in other happens-before language models.

> Or what's the difference between >> and >>> ?

The first is arithmetic shift right and the second is logical sign right; alternatively, the first will copy the sign bit into the lower vacated bits while the latter does not.


> you can safely ignore these and pretend it's UB if you do create a data race

I mean, that's safe but it's thoroughly unnecessary. In a language where races are UB all bets are off and that's a pretty wild consequence for what may be a relatively minor mistake.

Because data races aren't UB in Java, our program even though its behaviour now likely defies ordinary understanding by its creators, does still have some coherent behaviour. For example maybe we raced code that's putting CustomerOrders in a List, and so the List is smashed. In a language like C++ it's entirely possible that the smashed List is so toxic that even asking how big it is potentially has completely insane answers, crashes, runs arbitrary code, anything might happen - let alone if trying to take all the CustomerOrders out one at a time for processing. In Java, maybe the List is empty, which is not what we wanted, or it has all the orders which shouldn't be there, it won't have for example a negative number of CustomerOrders or anything else completely nonsensical.

In terms of defensible business logic, Java's memory model isn't better. But in terms of "Do attackers who exploited my race also get to run arbitrary machine code with database access?" the answer is definitely going to be "No" in Java for a data race, unlike in C++ or even Go.

Also, while it's true that Undefined Behaviour is common for data races (because of SC/DRF and laziness), it's not what happens in OCaml, they've come up with an even cleverer scheme than Java so that they hope their programs remain not only strictly well defined, but maybe something you can reason about despite a data race.


> 64-bit loads are atomic in the sense that word tearing cannot be observed.

This is true in practice in case of most JVM implementations, but is not in fact mandated by the spec — only 32bit values are loaded atomically according to that (so on a 32bit JVM you might observe ‘tearing’).

Nonetheless, I also think that you can pretty much hold all of Java in your head, as opposed to C++.


Yes... but I think the real question that will stump people is "What is <? super Foo> and how is it different from <? extends Foo>". :D

Java generic semantics are wild and often surprising.

But too your point, I think typescript is FAR more complex than C++ yet I almost never see similar complaints of its complexity. The richer the type system, the more complex the language.


That's not the real confusing one in generics. The real confusing one is "What is the difference between Class<List> and Class<List<?>>" (i.e., mixed generics and raw types)... I only know about this because it bit me in the ass once!


Ha! I thought about doing a tricky thing with wildcards vs missing generics.

What gets even more wild is, for reasons I really don't understand, when a missing generic makes its way into a generic pipeline it seems to have the tendency to erase other generics. (IE, `list.stream().map((f)->new Map())` does weird things with the stream as it gets more complex.). You can throw in "What's the difference between List<Object>, List<?>, List, and List<? extends Object>" for good measure :D


These are both pretty intuitive - you can provide any class which is extended by or extends T respectively. Some of the consequences are less intuitive, but I don't think it's any hard to remember. As someone who last professionally programmed Java during Java 7 days, it was still clear to me what these mean.


>I think the real question that will stump people is "What is <? super Foo> and how is it different from <? extends Foo>"

No, I don't think so. These are both common to see especially since Java 8 added Consumer as the former used to be pretty rare to see.


Thankfully I've never worked seriously in Java. Ask similar questions about Python, C, x86 assembly, old versions of C#...

I just looked up >>>, it's something I'd definitely know had I delivered any Java projects.


I mean, listing x86 assembly is a joke, right?

Everyone knows the simple add/mov/etc commands, but the list of total commands is in the multiple thousands, many with very unintuitive effects.

I don't think there's a person on earth who knows all the X86 language.


No, I only listed it because of how simple it is which makes me confident I understand exactly what's going on.

The full list of opcodes is like an stdlib - you don't need to know it by heart, just know what's available and how to search the docs. The things you can and hopefully do keep in your head are what addressing modes exist, how flags affect things, how interrupts work etc'.

Better low level developers than me also understand all the concurrency stuff - what is kept in which cache when, what operations constitute which kinds of memory barriers and what guarantees do you get about the thing you just read or wrote.


It's actually not that bad. There are a bunch of obscure things, but most of the mnemonics are just variations with slightly different names.


List all features supported in C# 12 and on which runtime version were made available, without looking into the language reference.

Bonus points for the ones that have different behaviour between .NET Framework and Core.

Extra bonus points when taking Mono, .NET Native, IL2CPP into consideration.


Wow, they have a C# 12 now? I wrote "old versions of C#" because I last delivered a project in C# 3.5, and honestly that was maybe 12 years ago and it was a bit arrogant of me to add it, I don't think I understand C# _that_ well.


.NET Native is dead for a long time, it’s the least important runtime flavour compared to others today because of this. IL2CPP and Mono are orthogonal and only ever relevant if you develop for Unity going forward (okay, there’s Blazor too which uses it for WASM).


No it isn't, given the extent UWP is still used on Windows given the failure of WinUI 3.0/WinAppSDK to deliver something that has feature parity with it.

Windows widgets and the new badly implemented File Explorer are probably the only WinUI 3.0 applications, the remaining stuff is still pretty much UWP, while many third parties that still care about WinRT at all, are stuck in UWP due to missing features and tooling in WinUI 3.0/WinAppSDK.

As for the rest of your remark, it doesn't change the fact that those runtimes exist and have relevant differences.


I am catching a whiff of judgement in your reply. You are the person on the team who knows the ins and outs of the language and is proud of it. You are a valuable member of the team, but I don’t want a whole team of you. There are other skills that are just as important in getting something “delivered” as knowing all the syntax.


Judgment? Like assuming that if someone understands the language they’re using they must not have other skills? :)


I said there are other skills that are just as valuable that I look for when building a team. Exhaustive knowledge of a language is a perfect skill for writing docs, training, performing interviews & doing code reviews. My main point was, it is not a required skill to be a “good” developer, like you seemed to imply.


I said it's possible to keep a full model of how some languages work in my head and I find it helpful to, not that it's mandatory. I even said that I can't do it in C++ and that I've delivered C++ projects, so I don't think my phrasing implied that it's required :-)

A good developer ships high quality software. If the situation calls for it, she ships it in C++ or ECMAScript 3 or Microsoft InfoPath. Nothing else is required. Many other skills are very useful, like good communication skills or some understanding of business or math or how computer infrastructure works.

These days I seldom write code - maybe one out of 4 or 5 work days I'll spend more than half an hour typing code in a text editor - and yet having a good model in my head of how my language works, how my database works, how my caches work, how my network works, is something that's very useful to me everyday. Other talented developers I know don't have that, and I recommend most of them to spend a bit of time acquiring it because it's worth it. More talented developers than me that I know and work full time in C++ don't have it, and sadly I don't recommend they get it because I think it's beyond their abilities. I think that's a negative attribute of a language that has some other very positive attributes (like its culture of just writing code that solves problems instead of obsessing about tools and DX all day).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: