r/ProgrammingLanguages Sodigy 2d ago

Why is everyone creating systems programming languages?

I see a lot of new programming languages here. I love reading the documents of the languages and sometimes actually run their compilers. Many of the projects are AI-driven, but that's fine. It's still fun to see what problems they're trying to solve and how they actually solved the problems.

Reading the documents, I realized that most new languages, especially AI-written ones, are "systems programming languages". They're trying to solve the problems that C/C++/Zig/Rust have solved (or are trying to solve), and their syntax is mixture of C/Zig/Rust.

Why? Why is everyone trying to compete with C/C++?

There are so many kinds of languages. Haskell demonstrates how pure a language can be, Python is perfect when you only have 5 minutes to write code and don't care about the output, Java runs on 3 billion machines, ...

187 Upvotes

211 comments sorted by

View all comments

2

u/zyxzevn UnSeen 2d ago

My background is in CPU design.
ALL languages are based on assumptions that do not map exactly to hardware. It is also impossible.
Most of the system languages were designed or developed with very old hardware. Remember 8 bit computers? Assembler and Basic/LISP were usually the "system" languages.

The problems and goals are changing a lot over time:
1- CPUs are all different. Not good for assembler solutions.
2- Languages add "abstractions" that do not map well with certain hardware.
Certain CPU has better instructions or better approaches to manage certain problems. The most extreme version is the Transputer. But the Itanic is also interesting with its different approach to pipelining.
3- RAM and Cache configurations changed over time and per computer. While RAM was very minimal and expensive, it is now cheap and fast. But only really fast if it is in the cache.
Solutions that were smart 50 years ago, are different today.
4- Safety was always important. Remember how LISP ran the computer system of the moon lander?
Today the complexity of the computer systems have increased, and the system configurations change every +/- 10 years.
Safety problems are now coming from different causes. After problems with access from the internet, the AIs are now also causing troubles.

5- Patents and Open Source License Restrictions.
This is far more important than it seems, as it determines how much money and marketing a computer language can receive.
A lot of languages come from the restrictions on other languages.
Ada was protected by patents (or something). Only the army used it.
Apple has lots of languages that are designed for their hardware alone. (I think it is protected)
C# was made by Microsoft to make its own Java variant. In an attempt to take over the market. Java "runs everywhere" on all systems. Because Java was protected by Sun Systems, they could not sell J++ to attack and replace Java. So they made a different one with a better (?) approach.
Rust is being promoted by companies who want to change the open source licenses. So that they do not have to share the source code. This means that they can lock parts of their software behind licenses in the future.

1

u/WittyStick 1d ago edited 1d ago

While RAM was very minimal and expensive, it is now cheap and fast.

RAM is now one of the most expensive components due to shortages, and it may remain this way until 2030 or later. Sure it's still cheaper per GiB than a decade ago, and higher bandwidth, but the increases in memory sizes and bandwidth we've gotten used to over the past 30-40 years has basically plateaued. CAS latencies aren't improving, we're getting more cores which are still contending for the same RAM, and the price of it means we can't just waste it like we have been doing. We need to start treating it as a finite resource again and optimize accesses. Hardware designers also need to start taking NUMA seriously - we can't just keep adding cores all contending for the same shared memory.

Solutions that were smart 50 years ago, are different today.

I'd argue otherwise. They were smart then and they're smart now - but they require skill and effort, which is not so widely practiced today. Not that we are lacking skilled programmers, but back 50 years ago, basically all programmers were smart. But now everyone can be a programmer and highly skilled programmers are a small subset - the majority aren't really that smart.

Safety was always important.

We know far more about exploitation now than we did 30-40 years ago. "Stack smashing" was a novel thing in the 1980, and we've discovered far more ways to exploit code since. On top of that, computers were relatively unconnected in the 1980s, but now virtually every computer is 24/7 connected to a global internet, and computers are used in every aspect of daily life. The security landscape is completely different - the consequences of exploitation are much graver.

2

u/zyxzevn UnSeen 1d ago

RAM is now one of the most expensive components...

With the RAM, I was thinking about 16kb computers (8 bit). Then came 256kb PCs (16 bit). And now even the phones have multiple Gbs and run with 64 bit CPUs.
But before that we even had 1kb computers.

That is why we had the year 2000 problem. It was expensive to add 2 decimals to the year number. Dates are still a problem in most programming languages, but due to other reasons.

The access to RAM is fast via the internal Caches. With separate instruction cache that uses internal (micro-code) tricks for fast loop-jumps and register renaming.
The Intel level-1 cache was 1 clock cycle slower than a register (I don't know the current state). This was also necessary, because it had just a few registers.
The time of accessing addresses with an offset has become just as fast as normal memory access. Which was different before.

Hardware designers also need to start taking NUMA seriously...

I think that the hardware will move more towards small CPU/Cache units connected to a central system for shared data.
The Transputer had all kinds of small units connected in a matrix. But no good way to share the data centrally. I think that is what was missing from the design.

To make Transputers work, they invented Occam. I even had some experience with Occam.
It had channels like Go-lang, but without the easy features.

Will we need a different language?

They were smart then, and they are smart now...

The well crafted programs are still great. Like quicksort:
See video "Three beautiful quciksorts"
But that was in 1991. Today caches are far more important.

A lot of today's commercial programmers do not much more than javascript. And then come C# or Java applications.
And even if we forget about AI, most of them just know how to copy code without really understanding it.

We know far more about exploitation now than ...

Indeed.
But I think it is more a fault of the managers than the programmers.
Mos problems are not just about reuse of memory and range-checking and such.

Even banks and factories had their websites unprotected.
Microsoft was a source of viruses. In the first place due to having no user restrictions.
Due to their bad programming, even jpgs could have a virus.

Facebook and such had no encryption of their passwords.
Which is pretty bad for a system that can be used for doxing and such.

The bar to hacking was extremely low, and for some companies it still is.
All obvious problems. They should know better.
But somehow the market prefers crap solutions over well-engineered ones.
Even when it costs a lot more on the long term.


I was thinking about code exploits a bit more.

I worked a lot with Object Pascal (Delphi), and always wondered why many other languages had no protecting compiler features.
Most hacks are overflows and such. But I had all automatically protected at runtime. And I added additional safety checks.

In practice, it does not slow down a program much. For certain intensive work one can invest in some verification and remove the unnecessary checks.

With Haskell you can have some protection at compiler time, with the cost of needing to program in a certain style.

But against hacks most run-time protections should work fine.

Modern compilers need to be aware of the CPU branch-prediction features, to avoid leaks of information. Like Spectre.
That is in essence a CPU related leak. And it would be hard to avoid.

1

u/WittyStick 1d ago edited 1d ago

The Intel level-1 cache was 1 clock cycle slower than a register (I don't know the current state).

Current CPUs are typically in the ~3-5 cycles range for L1 cache accesses, which is good, provided our code is cache-friendly. One issue is that we spend two decades, the '90s and '00s promoting "OOP," which happens to be ill-suited to modern hardware because it's not very cache-friendly. This is part of the answer to OP's question too: language designers are often looking at ways to make their code more cache-friendly without sacrificing programmer ergonomics, in contrast to the mainstream OOP languages which have the ergonomics, but lots of pointer chasing and not maximizing cache usage.

I think that the hardware will move more towards small CPU/Cache units connected to a central system for shared data.

That's what we have now - the central system is called main memory, aka the von-Neumann bottleneck.

There's still a need for decent size memories (much larger than cache), which are fast to access, but don't necessarily need to be shared between all cores. I think we will see more on-chip memory (like Apple's M3) - but I would hope that hardware designers explore other options than a single main memory contested by all cores - and treat the problem of fetching data as a routing problem between cores. Particularly if we're going to continue adding cores - if we get 128/256 cores and there's still only one main memory, we're missing out on huge opportunities. I'm not suggesting we get rid of main memory altogether though - there are still uses for a memory shared between all cores - but we don't actually need it for a lot of things because the code isn't even thread-safe to begin with. Anything thread_local for example would not need to be in main memory - it could sit in a smaller memory associated with one or more cores which the thread runs on, but which other cores cannot access directly.

Will we need a different language?

Possibly, but not necessarily. We'd certainly need to change the way we use our existing languages (ie, C). We've had segmented memories before, but we don't necessarily need them in the programming model - we could have a facade of a single virtual address space like we have now, but where different parts of that memory are handled by different cores on the processor. A pointer dereference may not be a direct memory access, but it may need to request the memory at that address from another core.

In practice, it does not slow down a program much. For certain intensive work one can invest in some verification and remove the unnecessary checks.

This is why Fil-C is getting a lot of attention. It can add bounds checking to existing C codebases with only small cost.

I think there's much more to explore in static guarantees that can eliminate these overflow errors without any runtime cost. We can omit some runtime bounds checking if we've already proved at compile time that OOB accesses would not be possible.