I am relieved to learn that I wasn't sleeping too deeply.
> A bit of simplification to the standard never hurts.
Absolutely right, but I'm afraid it might be too little too late. I doubt any one person can keep all of C++ inside their head.
I am relieved to learn that I wasn't sleeping too deeply.
> A bit of simplification to the standard never hurts.
Absolutely right, but I'm afraid it might be too little too late. I doubt any one person can keep all of C++ inside their head.
So that's one way to not be bored and to challenge yourself at work every day. :)
I think the better answer is to just remember the bits that are frequently useful to you, and pull up a tab on the rest if and when you need it.
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.
I just looked up >>>, it's something I'd definitely know had I delivered any Java projects.
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.
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.
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).
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.
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.
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.
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
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.
* 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.
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.
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++.
Since there are no type annotations to help your understanding of the code, you need to keep a lot in your head, as opposed to statically typed languages.
Also, we do have type annotations now. They’re not universally used, and definitely not required, but mypy and friends can go a long way toward finding type issues even without them.
OK, so I don't have every corner of the stdlib memorized, especially the odd deprecated batteries-included stuff like playing sounds on a Sun workstation. Nor do I have the extension API docs committed to memory, as you can use the language a lot without having to write those things yourself.
But the core of Python, like the language itself and the most common parts of the stdlib that are actually used in 95% of Python code, I have a strong grip on. In particular, the actual language is pretty simple.
This is why Go is my (and seemingly a lot of other people's) go-to "get shit done" language, I can write and edit code for hours without having to think about (too many) footguns or hunt for docs and esoterica.
Just like Google pushing Kotlin over Java, then having to accept keeping up to date with Java ecosystem was relevant to keep Android ecosystem going.
I disagree. I'd say productivity has very little to do with language familiarity and way more to do with ecosystem familiarity. C++ is hard because the ecosystem has no real entry point and several "script language to write a script language to write a compilation definition to write a script language to compile a project" build systems. (Who's familiar with M4?)
Mind you, I’m not thinking of some obscure thing that is only possible in Lisps, as in my experience these are seldom required, and code generation is always an option.
Go is hilariously ill-designed from this perspective, it gives you the common 80%, but has no answers for the remaining 20%. Generics does improve it a bit, but there are so many edge cases that it is simply sad to see it in a supposedly modern language.
The only time I've gotten friction is when in another project someone was really eager about making everything as abstract and modern as possible, to the point the code was (in my eyes) nearly unreadable. But that's not a C++ problem, that's a dev problem.
And a bit ironic. I lived through the static compile type/dynamic late type wars. There was this argument that with C++ (and similar) you knew and had some compiler ratified certitude you could count on. But if you’re telling me that a junior/intermediate dev can write code, perhaps making head scratching design concessions to get the thing to compile, he might make code that appears to run in the common case, but has unexpected behavior in other as of yet demonstrated areas, because they can never hope to have enough knowledge of the language to build a semi accurate model to know what to expect, then we’re really no better off than those late bound interpreted hippies with their weird metaprogramming VMs.
My point is that C++ offers users a lot of tools. You don't need to use most of them to solve most problems. Just start with simple tools: functions, classes, standard templates, etc.
That 10% effort will solve 90% of problems.
If you find a problem that can't be solved with the simple tools, then start looking into more advanced features C++ offers and use them if appropriate.
That is why no-one needs (or should try) to keep all of C++ in their head. It's not necessary for most problem solving.
It's of course fine to be enthusiastic about it and learn some new things just for the sake of learning. But it's not a requirement to know all of C++ to write C++.
You just need to know as much as everyone else on your team and all of the libraries that you are using.
"Within C++, there is a much smaller and cleaner language struggling to get out". Yes, that quote can be found on page 207 of The Design and Evolution of C++. And no, that smaller and cleaner language is not Java or C#. The quote occurs in a section entitled "Beyond Files and Syntax". I was pointing out that the C++ semantics is much cleaner than its syntax. I was thinking of programming styles, libraries and programming environments that emphasized the cleaner and more effective practices over archaic uses focused on the low-level aspects of C." Source: https://www.stroustrup.com/quotes.html#:~:text=%22Within%20C....
The question is then, "which 'cleaner and more effective practices' are being used in the code you write and maintain?"
The most obvious is if someone included a library that was dumb enough to be compiled with -ffastmath but the days of that are mostly long-gone.
If everyone is using a different niche of the same language then you have the same problem.