UP | HOME

Low Level

Lets settle once and for all some annoying bullshit.

Lots of people are parroting some delusional lunatics about a supposed superiority, if not sacredness, of pure C. Ok, lets try to understand what the C programming language was at the time of it “triumph”.

Back then people have programmed systems in an assembly language of a particular machine, which was more or less OK, given that all the codebases were small.

An assembly langauge, however, offers you not much support for developing proper, non-leaking abstraction.

Basically, all you have is a procedural abstraction in an purely imperative, untyped language.

The most used instruction in all assembly languages is MOV. It literally moves a value between a register and a memory location (and vise versa).

Everything is an address or an offset. An address itself is an offset from some base “segment”, so implicitly everything is a mutable reference.

The basic building block is a Procedure, which is supported by hardware’s “stack discipline“

No support for modules until very resent (masm or tasm), no other higher level constructs whatsoever.

C

The main insight and “the genius” behind C (at the time) was this notion of being a “thin, almost transparent” layer of proper higer-level abstractions on top of an assembly (the machine code, to which it compiles).

Of course, it used the machine calling conversions (which we now call an ABIs) and almost directly translated “functions” to procedures. The separation of the interface specifications (of “functions) into header files was a major innovation.

No surprise that the notion of a pointer type is the central, and of a typed /array, as a continuous chunk of memory, so the offsets can be calculated easily.

So, C cleverly generalized the common abstractions of an assembly language (and of machine architecture), and created sort of a meta-language, based on proper concepts, which a better support for modularity.

It is important to note that at almost the same time a way better language - CLU at MIT - has been developed, but was destined to remain only an academic language.

Now the main question is - do we really want to program at this level.

The answer is “NO” for anyone who ever tried to study or do mathematics.

C++

This still the only video you need: https://www.youtube.com/watch?v=kdlIlIIHCz0

It shows you exactly the promises of what C++ supposed to be – a set of zero-cost (the biggest meme) higher-level abstractions on top of C, which compiles to the same “direct translations to machine code” as plain C would.

In reality, however, the nice parts literally ends here (end of this video) and the whole fucking mess of LHS and RHS semantics, lifetimes, aliasing problems, dangling references, “moves semantics”, has not been discussed.

This is, perhaps, the biggest lesson in programming – how nice, oversimplified theories (and naive world views) are different from actual realities.

Another lesson is that smart people, like the guys at Id Software, are using exactly this, the smallest possible, idealized, subset of C++.

Want to see the actual code? Well, look at all the Google’s open-source (Chrome, Tensorflow), all the Intel’s open-source libraries, Pytorch, etc.

Higher level and abstract types (classes) is what makes it possible to create and maintain such kind of projects – of such complexity and size.

MTL

Have you ever tried to develop a “stable” and “trusted” math or scientific library? Use it to trade your own money? Run your medical devices? (and yet they run their medical devices on C++98)

Do you want to re-implement from scratch, say, some parts of Intel’s MTL? How about graphics? Mesa? No?

To understand “why no” one has to understand some fundamental mathematical structures and how exactly they have been defined (generalized).

It has been well-understood since the time of FORTRAN II that we have to program with high-level abstractions using high-level languages. C, no mater how clever it was, is not a suitable language.

Almost all the decent PL research of LISPs, the ML family, and of non-strict Functional languages will show you why.

It even has been shown that “laziness” facilitate its own abstraction techniques based on thunks which leads to smaller code and better modularity.

Rust

It tries to bring better, restricted semantics to imperative “reference-based” languages.

The main innovations is bringing (lifting) the references to the type-system, and It solves a lot of problem by making sure that certain situations and states will not happen.

Author: <schiptsov@gmail.com>

Email: lngnmn2@yahoo.com

Created: 2023-08-08 Tue 18:37

Emacs 29.1.50 (Org mode 9.7-pre)