7 ms·
There's a couple of things that make Go feel lower level than Java. The first is having access to pointers and the manipulation that brings. Even though there i
by dwohnitmok 5y ago
There's a couple of things that make Go feel lower level than Java. The first is having access to pointers and the manipulation that brings. Even though there isn't pointer arithmetic, needing to think about referencing and dereferencing structs is lower level than Java, which doesn't provide this in the language at all and forces all objects to be pointer-heavy references of references (apart from primitives).
The other thing is that by not having a VM, a lot of usual Go performance optimizations end up being "closer to the metal." E.g. optimizing struct alignment is a fairly pedestrian Go performance optimization. On the other hand, if you rely on guarantees of how the Hotspot JVM (as opposed to other JVMs) lays things out in memory, that's considered pretty deep hacking in Java.
- feffe 5y agoYou do have more precise control over the memory layout of your data in Go. Because of the value types and support for using interior pointers to arrays. In that respect it's like C which is lowish level.
- azth 5y agoYou can know your class alignments in Java using tools like http://openjdk.java.net/projects/code-tools/jol/ http://openjdk.java.net/projects/code-tools/jol/ Having access to pointers is a superficiality. Java is getting value types, and C# already has them.
- dwohnitmok 5y agoRight but those tools are VM-specific (e.g. the one you've posted is Hotspot-specific) and VM-specific optimizations are usually considered advanced optimizations in Java. Valhalla's value types aren't the same thing as pointer access (or lack thererof). The first thing is that this is baked into the definition site rather than being something that can be decided at a call site. The second thing is that value types entail way more than just pointer access (as befits a higher-level approach). In particular it gets rid of the built-in ability of Java objects to act as locks, gets rid of mutation, etc. It's a much larger change than just referencing and dereferencing. More to the point, the notion of pointers referencing and dereferencing is a lower level concept than reference vs value types. The former is usually used to implement the latter.
- azth 5y ago> More to the point, the notion of pointers referencing and dereferencing is a lower level concept than reference vs value types. The former is usually used to implement the latter. If the end result is the same, then the claim is really meaningless. I'm just pointing out the parroting that goes on in the golang community.
- dwohnitmok 5y ago> If the end result is the same, then the claim is really meaningless. One being used to implement the other doesn't mean the end result is the same (you cannot use value types and reference types to implement pointers because of the call-site vs definition-site distinction). As I mentioned, value types are far more than pointer dereferencing.
- azth 5y agoThe point is, pointer dereferencing in golang is limited to mimicing value types/reference types, something that C# already offers. It is not like C and C++ where you have pointer arithmetic. So it's just an illusion that it is "closer to the metal".
- dwohnitmok 5y agoNo it's not. Value types and reference types are definition-site concepts whereas pointer referencing and dereferencing are call-site things. This allows both for different ways of programming as well as different language semantics.
- thegeekpirate 5y ago> It is not like C and C++ where you have pointer arithmetic. You absolutely _can_ do pointer arithmetic—it just requires using the "unsafe" package for obvious reasons (https://go.dev/play/p/Batmgb1KJcg https://go.dev/play/p/Batmgb1KJcg). Hell, there's even a helper function (https://pkg.go.dev/unsafe#Add https://pkg.go.dev/unsafe#Add) for addition!
- throwaway894345 5y agoIt's also worth distinguishing between "has value types" and "uses value types". C# has them, but they aren't particularly idiomatic--they're regarded as an optimization.
- azth 5y agoHow is that relevant to the point whether a language is "closer to the metal" or not?
- throwaway894345 5y agoBecause calling a language "close to the metal" is potentially ambiguous--it can imply that a language merely has "close to the metal" features or it can imply that they not only exist but are used in the course of idiomatic code. Specifically, only one of these interpreters conveys the idea: "I can read code in this language and have a pretty good idea about what the generated machine code is like".
- azth 5y ago> I can read code in this language and have a pretty good idea about what the generated machine code is like This is not true even for C. Secondly, it seems that its common in the golang community to parrot things that not only are incorrect, but provably wrong.
- throwaway894345 5y agoFirst of all, you can look at C code and have a pretty good idea about the generated machine code, or at least a much better idea than with C# and Java. Secondly, it's even easier to predict Go code because Go compilers don't optimize as aggressively as C compilers and because Go has very little UB. > Secondly, it seems that its common in the golang community to parrot things that not only are incorrect, but provably wrong. Whatever your intentions may have been, this is just language war flame bait, and it's against the rules.
- 5y ago
- geodel 5y ago> Java is getting value types, And it is good thing to have. But if one desperately comment same thing multiple times, I feel reasonable to ask why the hell they weren't added in all these years?
- azth 5y agoThe philosophy behind Java is that a feature needs to be demonstrated in production very well before it is added to the language, in order no to go overboard with features and end up with C++ :) Value types have proven their worth, especially with the gap between CPUs and memory bandwidth, so they're being added.
- int_19h 5y agoIf these are really the two sticking points, then Go should be on roughly the same abstraction level as C#/.NET (which also has pointers - with arithmetic, even! - and user-defined value types with explicit layout control and unions). However, given that Go also brings its green threading into the picture, I'd argue that it's actually higher level than either Java or .NET in that one respect.
- dwohnitmok 5y agoC# is an interesting case. You can only use pointers in unsafe C# code, so you could argue that unsafe C# code is as low-level as Go or even lower (which I actually think you'll find many supporters for), but unsafe C# is different from normal C# and is outside the purview of everyday C# code (whereas again pointers in Go are absolutely pedestrian). RE threading, green threads though are coming (back!) to Java as well with Loom, but I consider that more of a library/runtime thing than a language thing (as is the case with Loom). A hypothetical Go library could expose system threads and have an API for manipulating them, it just wouldn't be first-class in the same way goroutines are. But this is similar to how having async-await in C# doesn't negate the fact that you can use direct system threads from the standard library.
- int_19h 5y agoWith C# and .NET, you also need to consider the different kinds of pointers involved. The thing that's closest to Go's pointers would be managed references (which don't have pointer arithmetic but are GC-aware). In C#, this corresponds to in/ref/out parameters, locals, and return types. Now, the difference is that those can point directly to the stack, and thus cannot escape the function in which they were created for memory safety reasons. But conversely, they are allowed in safe code. And then there's stuff like Span, which these days lets you do something similar to Go slices: Span<byte> p = stackalloc byte[n]; (note that this is also safe code!) As for green threads, I think in case of Go they can't really be considered a library thing due to language integration of goroutines and channels. It's also not quite the same as C# async/await, because the latter isn't really a threading system so much so as syntactic sugar for CPS; it's entirely possible to have a single thread running the event loop.