5 ms·
And this is what low-level programming is by definition: technical details stand on your way to abstraction building. Memory, error handling, underlying machine
by vkazanov 4y ago
And this is what low-level programming is by definition: technical details stand on your way to abstraction building. Memory, error handling, underlying machine details leaking, etc.
Zig tries very hard to stay (relatively) simple, make things possible, but not hide all the important details.
- auggierose 4y agoI don't mind technical details. But the best way to tackle technical details is to build the right abstractions. And the best way to build the right abstractions is to be aware of the technical details.
- vkazanov 4y agoNote then that there's an inherent conflict in programming language design space between introducing too many abstraction building tools and low-level details. It is very hard to make things truly orthogonal. E.g. memory and resource management tends to spill all over the code, with the other example being error handling. And once a language designer adds ways (and a programmer culture) to hide things - it becomes very hard to follow the code. Zig attacks this design space from a low abstraction and explicit flow point of view.
- DeathArrow 4y ago> Note then that there's an inherent conflict in programming language design space between introducing too many abstraction building tools and low-level details. Best C++ code that deals with low level details is as least abstracted as possible. One of the reasons C is used for writing operating systems kernels is that it doesn't hide details. Imagine Linux kernel written in OOP way with design patterns and SOLID principles. :)
- staunton 4y ago> Imagine Linux kernel written in OOP way with design patterns and SOLID principles. Doesn't sound that terrible to me. Just out of interest, do you think `*(int*)(0x12345678) = 0;` is the best way to do memory-mapped IO? That's least abstracted.
- maldev 4y agoHave you ever written low level code? There's constant hardcoded addresses you have to deal with which are in the spec. You can't really do BIOS, UEFI, Bootloder, Systems programming, ... without it. You wouldn't do a "magic number" and would make it a macro. But *SCREENBUFFER = 0;
- staunton 4y agoYes, my point being that the macro in this case is an "abstraction", and we were discussing GP's claim "all abstractions bad" (i.e., to quote them, low level code should be "as least abstracted as possible"). Was it really not clear what I meant? I've actually encountered seasoned embedded devs advocating using the magic number in this very case. Never really understood why. It was some combination of "abstractions bad" and "I want to be able to check all adresses against my printed dead-tree documents while debugging "... Of course noone really believes "all abstractions bad", but I wonder why some people still claim that.
- pjmlp 4y agoC is used because of UNIX, it hides plenty of details.
- auggierose 4y agoYes, I agree that there is this tension that no single "programming language" can resolve. That is why we don't need programming languages, but systems for building abstractions. But as long as we don't have those systems, I prefer programming languages that let me build proper abstractions.
- still_grokking 4y agoProgramming languages are systems for building abstractions. At least the proper ones.
- DeathArrow 4y ago> But the best way to tackle technical details is to build the right abstractions. Wrong way (according to you): Compute factorial using AVX intrinsics Best way (according to you): Make a factory class AbstractMathFormulaCalculatorBuilderFactory to instantiate a builder class AbstractMathFormulaCalculatorBuilder which can build an AbstractMathFormulaCalculator, from which you derive a FactorialCalculator in which you use an AbstractMathFormulaExecutor, built with an AbstractMathFormulaExecutorBuilder, generated by AbstractMathFormulaExecutorBuilderFactory.
- pif 4y agoRight way, according to him: Compute factorial using a function ComputeFactorial that uses AVX intrinsics.
- auggierose 4y agoSorry, but the above is all according to you, not to me.
- DeathArrow 4y agoI don't demand abstractions everywhere.
- auggierose 4y agoFrom what I gather so far I don't think you know what an abstraction is, so it is prudent of you not to demand them everywhere.
- rootlocus 4y agoThere are no "right abstractions". There are tradeoffs with advantages and disadvantages. Your preferred abstractions are by no means the "right" ones, especially since you don't even define what they are.
- auggierose 4y agoOf course there are right abstractions. And of course what the right abstraction is depends on the context, and takes into account the trade offs you are making. Any programming language is an abstraction, for example, and no programming language I am aware of is the right one out of the box except for very narrow and well-defined domains. That's why it is important that the language lets you build your own context-dependent abstractions.
- rootlocus 4y agoAnd part of that context is your personal preference. Zig purposely chooses to prevent hidden control flow [1]. If operator overloading is a preference of yours, the language will get in your way. And that's fine. But it doesn't mean you can't build the "right abstraction" with it. These tradeoffs force you, for instance, to add an allocator to every type that needs dynamic allocation. For me that's great because it's evident which components need memory and I can make a conscious decision on what strategy to use with each one (or to avoid them entirely). For someone else, that might be a PITA. There is no "right" abstraction here. 1. https://ziglang.org/learn/overview/#small-simple-language https://ziglang.org/learn/overview/#small-simple-language
- auggierose 4y agoNo, your personal preference is not part of the context. Unfortunately, too many programmers think that way. If you don't like using abstractions, but if you like instead to make everything explicit, that is of course your prerogative. But denying that there is a right abstraction will just keep you from finding it. It doesn't change the fact that there often is one. Going after the right abstraction takes time, and it might be just too expensive in your context, or your context may actually make abstraction infeasible. So in my opinion, it is all about trying to get into a position where experimenting with abstractions becomes cheap and economical. In principle, we should be in a much better position today in that respect than, say, 30 years ago.
- pjmlp 4y agoAda, Modula-2, Mesa and Object Pascal already showed how to do it properly, with nice abstractions, in what concerns systems languages with manual memory management.