5 ms·
> no attempt to justify why current levels of abstraction — which are charitably hundreds of times more complicated than the difference between, say, go and rub
by Veedrac 9y ago
> no attempt to justify why current levels of abstraction — which are charitably hundreds of times more complicated than the difference between, say, go and ruby — are good, right, and just
It seems to me that Go is part of a reaction from people who are not happy with current levels of abstraction.
- stouset 9y agoEvery person who's bet against additional layers of abstraction has been on the wrong side of history so far. I see no reason why that trend ought not continue. Some of those layers will be rethought, of course. Some will be merged. But it's inevitable that new layers will be added on. Abstraction is fundamentally the process that allows us to solve progressively harder problems, by sharing knowledge of our solutions to similar problems. It's central to our understanding of math, physics, biology, psychology, and every other scientific field you can name. Software engineering is no exception.
- Veedrac 9y agoThe losing minority, sure, but the wrong side? AAA games? Linux? Rust? Vulkan? WebASM? Yes, some abstraction is beneficial. But too much abstraction leaves you with, you know, the decrepit state of modern software. Abstraction as you actually see it isn't letting us solve "progressively harder problems", it's letting GMail take up more RAM than my OS does from boot. Meanwhile most of the really interesting problems are still done in fairly primitive languages.
- stouset 9y ago> AAA games? You mean the ones built on a handful of abstracted 3D engines like Unreal, Source, id Tech, CryEngine, Unity, etc? > Linux You mean the operating system that abstracts away from us things like filesystems, hardware access, shared memory, time sharing, networking protocols, access control, multicore processors, etc.? > Rust You mean the programming language that adds a new abstraction of "borrowing and ownership" to help simplify the confusing existing abstractions of memory management and data race detection? > Vulkan You mean the API that abstracts away parallel computation on graphics hardware, upon which they intend for dedicate graphics abstractions like OpenGL and WebASM to be abstracted? > WebASM? You mean the API that abstracts away running low-level machine code — not on your own machine, but sandboxed on remote machines via web browsers. > Meanwhile most of the really interesting problems are still done in fairly primitive languages. Do you want to take a guess why I'll argue that you consider the obscenely complicated task of "delivering secure, multiuser, interactive applications with offline persistent data storage to hundreds of thousands of remote clients" a non-interesting problem? It's only because of the incredibly successful and complex network of abstractions that are Ethernet, IPv4, TCP, DNS, TLS, HTTP, HTML, JavaScript, SQL, graphical image formats, web browsers, database servers, caches, switched networks, load balancers, and so on that these kinds of achievements that would have been considered monumental even thirty years ago are not "really interesting problems" today. Abstraction has allowed us to break apart the component parts of this incredibly complicated problem into small, independent, coordinating layers. The fact that you think that something like delivering web applications is a non-interesting problem practically makes my argument for abstraction all by itself.
- jstimpfle 9y agoYour points are good, but parent's comment has mostly been about OO which is not necessarily a successful abstraction in these areas. AAA or kernels games are traditionally written on a low level, i.e. C with maybe some convenience C++. Especially for memory management there just isn't a good one-size-fits-all abstraction. Look for AAA games or kernels in Java. Another problem of OO for high-performance or complex architecture is the mindset it inflicts upon developers. It motivates decomposition in "independent" objects, while this is just not possible. You have to think about processes in the large, about dataflows, about how to structure information and how to handle cross-cutting concerns, etc. Getting at these problems with an OO mindset leads right into desaster. Look up data-oriented programming. Look how a game engine is architected. There are lots of memory and resource managers, for example. But nobody would think of a Vertex as an individual "object". Or break his head how to design a character object, when related data really has to sit all over the project (character world position and state, associated 3d resources, sound resources, ....). >> Rust > You mean the programming language that adds a new abstraction of "borrowing and ownership" to help simplify the confusing existing abstractions of memory management and data race detection? So far, it's just an attempt to enable mindless OO-style programming without inflicting a runtime, but I guess with very limiting mechanics. And it inflicts a huge syntactic overhead. I predict the applications of Rust are very limited. Game programmers are usually (as far as I know) not very busy with memory management problems.
- Veedrac 9y agoI'm certainly not arguing for no abstraction! Use as much as you need; nobody argues with that. These are just places where the bar for "need" isn't an afterthought, and effort is taken to keep abstractions minimal to avoid their cost. > Ethernet, IPv4, TCP, DNS, TLS, graphical image formats, switched networks, load balancers These abstractions exists because they are necessary. They are a bit of a mess, admittedly, but invested people have worked hard to make what they were given as small a mess as they can manage, and what is left exists because it has to historically. When your packets get pulled through hardware specifically designed to do exactly that, the abstraction almost ceases to be. (Disclaimer: not a network person) > HTTP, HTML, JavaScript These abstractions are why 12 billion instructions per second per core counts as slow now.
- dbaupp 9y agoI think the grandparent means that Go is already very abstracted from what's actually happening (e.g. programmers don't have to think about quantum mechanics, voltages, machine code (i.e. the actual numbers), microcode, CPU caches, virtual memory, finite memory/memory management (GC), implementing runtime type-checks or virtual dispatch) like many other languages. On one of those "spectrum" diagrams everything is bunched really far to the right: asm Go Ruby SQL reality <---------------------------------------------------> abstract Their point is something along the lines of: there's not as much justification for why all that stuff to the left is "good" abstraction, versus the justification for why the tiny extra bit to the right is "bad". The line between good/bad abstraction seems to be fairly arbitrary.
- stouset 9y agoYes! You have restated my position better than I could have.
- Veedrac 9y agoThis feels like a false comparison to me. When you write ASM you pretty much know what it's going to do. When you ADD two registers, you really are making two reads in the register file, which really is a piece of physical hardware, and those reads really do go to a physical adder and get written back to the real, physical register file. And languages like Go translate reasonably (but not exceptionally) straightforwardly to assembly. Even if you don't know all of the details that go into making it fast, your first guess of what it's doing is pretty much right. In contrast, adding some lazy FP callback into your latest node.js framework on DOM objects might be doing something, somewhere, but who on earth really knows?
- stouset 9y ago> This feels like a false comparison to me. When you write ASM you pretty much know what it's going to do. This is because it's an excellent layer of abstraction on top of the machine code which is interpreted by the abstraction of microcode which sends it to the abstraction of a physical processor that's itself just an abstraction on top of transistors that themselves are an abstraction around manipulating voltages on a complex network of circuits. Nobody bats an eye at these levels of abstraction. And they're not perfect! Modern CPUs have hundreds of errata. Skylake's alone is almost 40 pages long, at 3-4 per page. But you take them for granted because they're several layers lower than what you have to deal with on a regular basis. Even your example of adding two registers required compiling through an assembler, scheduling execution by a time-sharing operating system that fakes the concept of running hundreds of parallel processes by rapidly looping through running processes, and on and on and on. We are awash in a sea of abstractions more deep and complex than even a dozen of the world's best engineers put together could hope to fully understand. And yet people earnestly defend language design decisions that prevent a single function from comparing two values of any arbitrary numeric type as being too complex, when issues like that are less than a hundredth of a hundredth of a hundredth of a percent of the complexity that are modern computers.