What Is Systems Programming, Really? (2018)
willcrichton.net
willcrichton.net
The primary distinguishing characteristic of systems programming when compared to application programming is that application programming aims to produce software which provides services to the user directly (e.g. word processor), whereas systems programming aims to produce software and software platforms which provide services to other software, are performance constrained, or both (e.g. operating systems, computational science applications, game engines, industrial automation, and software as a service applications).
That is to say, the distinction I consider to be somewhat meaningful is between "Systems Programming" and "Application Programming", and I think this expresses the most salient aspect of the difference:
application programming aims to produce software which provides services to the user directly (e.g. word processor), whereas systems programming aims to produce software and software platforms which provide services to other software
But is all of this terribly important? Meh. I am not convinced that it is a terribly important distinction in most day to day contexts. And that's at least partly because the lines do seem to be a bit hand-wavy, subjective, and fuzzy.
A systems program is a background service or a tool that provides the underlying abstractions for applications to run. An application programmer operates with well-defined APIs and, in general, should not be concerned with storage mechanisms, concurrency issues and resource management.
But even here, there is also a spectrum: should the browser engine developer know about the actual pixels of the display, and the "electrocoagulation of Ag nanoparticles between silicon nanostructures that support Mie resonances" [1], and so forth: the layers never stop, hence maybe it's more important actually caring about the product as a whole, in all its effects and side effects, a sort of omoiyari [2], as the Japanese would say.
[1] https://www.degruyter.com/document/doi/10.1515/nanoph-2022-0...
[2] omoiyari: 'give your thoughts and take an action on it', English: https://youtu.be/KJ5kcEQi934?t=71 Japanese: https://www.youtube.com/watch?v=16P_t4ApyhI
Just brainstorming here xD.
[1] https://rustwasm.github.io/wasm-bindgen/examples/dom.html
[2] https://thewagner.net/blog/2019/01/30/load-balancer (off-topic: Rob Pike's Concurrency is not Parallelism https://www.youtube.com/watch?v=oV9rvDllKEg)
Of course it's fuzzy and unimportant, they're just words for categories we've made up, and didn't even make a very good job of it.
Even if we did make it clear which is which, what's the gain from being able to make a clear distinction? Is it any more productive than fighting over who got the best text editor?
Exactly. I mean, what will you do differently at work tomorrow if your job title is changed from "Systems Programmer" to "Application Programmer"? Approximately nothing.
Is it any more productive than fighting over who got the best text editor?
The text editor discussion is probably more productive!
System programming is about a program being used by another program unlike an application which is being used by a person. A programmer too will not use that program but use an application to develop a program which will then use that program. This makes system programming distinct from application programming in purpose, philosophy and reality.
Contrast this to a GUI program a user interacts with. Its purpose is dependant on its relationship to the user. The philosophy is that the user could click on anything on the screen at any time, so the program had better be ready! The reality is that users live in their own world, free from all concerns of the silicon world, except one - power. They may perceive memory pressure in the form of slowness, but they don't feel it the way the operating system does.
Systems:
- Lacks a GUI.
- There are technical details.
- Doesn't compete with applications.
- Memory pressure is an issue.
Applications:
- Has a GUI.
- Need to be responsive.
- Power usage is important.
- Memory pressure results in slowness.
I don't think we got any closer to a useful answer.
Web browsers are another interesting item that don't fit neatly into this classification either. I mean clearly a browser is something that provides services directly to the user. You use it to navigate the web, view and download documents, store bookmarks, and all sorts of stuff. It's 100% "application level." Except... the browser also provides a runtime, including memory and process management, networking services, graphical rendering, etc. to other software. In fact, a browser is basically a poor man's Operating System. So it's 100% "systems level." Wait, what?!??
The middleware-programming is also systems-programming was also reinforced by Rob Pike when he originally presented Go as a "systems language". However, he now admits[1] it confused people and Go might be better categorized as a "server" apps language -- i.e. writing Google's backend infrastructure code that doesn't need to be written in C++.
In the 1980s, "systems programming" was usually a synonym for "bare metal programming" because "systems programming" was just a shorter way of saying "_operating_ systems programming". (One writes an operating system to boot up on bare metal.) And systems programming was typically assembly/C/C++ instead of business programming like COBOL or dBASE. In that mode, writing kernel drivers or a UEFI boot loader is also "systems programming". In contrast, "applications programming" was something else.
That said, if today you surveyed 100 random programmers in various domains, I'd have no idea if there's a dominant view of what systems programming is.
[1] from the article: Rob Pike: When we first announced Go, we called it a systems programming language, and I slightly regret that because a lot of people assumed it was an operating systems writing language. What we should have called it is a server writing language, which is what we really thought of it as. Now I understand that what we have is a cloud infrastructure language. Another definition of systems programming is the stuff that runs in the cloud.
I don't think RabbitMQ being written in a "non systems language" is relevant. Its a systems program even if it was written in shell (if it was it might be a bad systems program, but a systems program nonetheless because of it's intended customers and use case).
Which brings us to browsers, which are not systems programs (and I think we tend to not think of them as such) almost entirely due to their primary customers not being programmers. This is despite the fact that they fit the "complexity/size and close to the metal" definitions a lot better than many other programs that are commonly considered to be systems level.
Take an OS, for instance. You can build on the other parts of the OS (if they exist yet, and/or if your layered architecture permits you to), and the bare metal. That's it. That's all you have.
Contrast that with writing an app on top of, say, a POSIX-compliant OS, and there's a huge difference in how you program. Sure, as other comments point out, there's a continuum of points between the two, but there also is a pretty stark difference between the ends of the spectrum.
Guessing a bit here, but the difference may more generally be that in application programming, you are more constrained by the logic and purpose of the application, and in systems programming, you are more constrained by the system. The app is more stand-alone, and the system is defined by the interaction of the components. From this perspective, it may be fair to think of a microservices architecture as "systems programming".
Database engines are an excellent example of this spectrum. Some simple databases contain no systems programming at all whereas advanced databases are essentially complete operating systems that run in user space. If you walk the code bases along this spectrum, you will see a shift in the construction, character, and design of the code base as more of it transitions from "application" to "systems" code.
The distinction is important because systems programming is a different skillset than applications programming. For example, there is often a requirement to do a lot of sophisticated scheduler design that is integral to the correctness of the software in systems programming. Application programming rarely concerns itself with this, it relies on threads, locks, etc and has the OS sort out the scheduling.
Outside of actual operating systems where systems programming is unavoidable, the primary motivation to do systems programming in a user space application is it can greatly improve performance, scalability, and robustness.
We have the word "middleware" to describe that.
If you look how the word is used, "systems programming" does clearly not mean that (personally, I don't remember ever seeing it used that way). It's more used as an architecture paradigm, where you don't expect a lot of things to be abstracted, for whatever reason. The word choice is obviously because the underlining system that provides those abstractions is architected this way.
The distinction is actually relevant in a lot of contexts. As we get better languages and compilers that provide lower cost or more expressive abstractions, it is getting less and less relevant, but it still has a lot of relevance. And yes, it's a fuzzy concept like any other software architecture one.
> Dynamic programming languages are arguably still far from systems languages,
> since dynamic types and idioms like “ask forgiveness, not permission” are not
> conducive for good code quality.
I find it amusing that, when asked to give a defining characteristic of systems programming, key figures behind C++, Rust, D, and Go gave radically different and unrelated answers: "client applications," "resource-constrained applications," "cloud infrastructure," and "unsafe pointer casts."If anything, a more practical definition is "only C and C++ are systems programming languages, by fiat, because it's an artificial category whose historical roots have long since lost pertinence."
shudders
Systems programming is about adjudicating contention for system-constraints and system constrained resources. It's about creating relatively clean interfaces to relatively thorny problems. It's only lost apparent pertinance because of the explosion in numbers of people "coding" web front ends or other things at the top of the stack, and because the code that solves some of these problems is well understood and complete. But underneath all what we do in the various userspaces is the same and even greater complexity of problems which require maintenance and development/porting to new architectures as they get developed
It seems a lost art. When I learned Pascal, C and C++ during high school most of my peers were learning and using these.
Until early 2000s most of the software facing end users was quite low level because there was no way around it, people needed software that was fast enough.
Even if today I use mostly a garbage collected language and I am abstracted away from the language, I find my days and years of using C and C++ quite rewarding because I understand how the hardware works, what are the trade-offs when taking one decision and what is the path forward if I want to have decent performance.
This is why a "systems" programming language makes no sense. You need many languages to address all the different kinds of hardware in your system.
But ultimately words only mean what ever you define them as in the moment, so system can mean anything you want it to, so long as that meaning is conveyed to others needing to understand how you are using the word.
A system is something that is put together from smaller, distinct components in such a way that it has emergent properties not inherent in its components.
Is systems programming to provide such components so they can be put together by application programmers?
If yes, then “lower level” is entirely relative. A component might be a hardware driver, a service in the cloud or a set of primitives in your game engine.
This would also mean that the term is recursive. Anyone who is programming components or larger parts of a system that can be put together is now systems programming.
So the web developer who handles content negotiation for both end user consumption (html) and further processing (json) is now systems programming?
It’s all a bit confusing with this term.
"Applications programming" is building user facing applications, mostly out of systems others have built.
e.g. I work for a company that makes a database. Even though I work in a higher level language (Julia), it's still systems development because it's concerned with systems-level concerns: building a system that is normally off the shelf, and being concerned with memory bandwidth, fragmentation, cache misses, etc.
And it's not that application level engineers don't have to be worried about these things. It's just a matter of degrees or emphasis.
When employed doing "application programming", I consider it bad practice to build systems from scratch. e.g. rolling your own queueing system or database when the real job is integration and solving the customer's business requirements.
Xerox PARC systems programming was done in Smalltalk, Interlisp-D, Mesa/Cedar, where garbage collection was part of the picture. Likewise at ETHZ with the various kind of Oberon based systems they produced.
I was lucky to have done systems level stuff in BASIC, and Pascal before getting to learn C and C++, as I wasn't subject to the misunderstanding C and C++ are the only way to do systems work.
What matters is understanding how the hardware works, and actually how that high level stuff maps into Assembly.
* Lots of pretty low level programming. OS level stuff and raw network programming.
* Low level database and data storage skills in all levels. Programming, database internals like optimizers and storage engines.
* All aspects of networking; TCP/IP, other protocols, physical level, routing protocols and lots of socket level programming in Unix.
* Operating system internals.
Higher level languages are something like an e-commerce website. You're talking about views, orders, auth, accounting, etc. Of course they connect at some level but you're generally thinking about some business level that isn't in terms of computer words.
In AI, we think of mathematical algorithms, but computers do not understand math. Math is a purely human invention, computers have no idea of math. Nor computers understand Python or C. The only things CPUs are designed to understand are 0s and 1s, quite literally. It's a very long road, and lots of layers of abstractions, from 0s and 1s to Python (or C for that matter). This long road is Systems Programming to me and I find it quite fascinating.
To do Systems Programming, I would think you want direct access to hardware, to the metal itself. C and C++ (some other languages? C#?) provide such an access. Python (or Java) does not provide such unfettered access to the hardware. Having said that, I find author's assertion, that "Dynamic programming languages ... are not conducive for good code quality", both inaccurate and irrelevant to the System Programming assessment.
The important implication of this is that various potentially important requirements are unknown.
Performance, load, memory, scaleability, regulatory, security, platform, CPU, etc.
If you're successful, your users (developers of apps or higher-level systems) will be using your software in ways and for purposes you can only partially know.
You have to deal with that somehow.
Maybe you can design your software to be agnostic to a concern (e.g. if your protocol uses a TCP stream, your users can adopt SSL as needed).
Maybe you optimize for the concern as much as is feasible (this is why performance is such a concern for "systems programming languages... there is no acceptable level of performance, you want the performance overhead to be as small as feasible.
Maybe you miss a concern that is important to your potential users and fail.
The ABCs of IBM® z/OS® System Programming is a 13-volume collection that provides an introduction to the z/OS operating system and the hardware architecture. Whether you are a beginner or an experienced system programmer, the ABCs collection provides the information that you need to start your research into z/OS and related subjects.
...
2.1 The role of the system programmer
The role of a system programmer is broad, but essentially it is to maintain a stable operating environment for users and business applications. A system programmer’s responsibility can be at the operating system level, at the subsystem or middleware level, or at the hardware level. A system programmer installs, customizes, and maintains that environment by rolling out regular maintenance or even upgrading the entire environment to keep current and use new functions.
Another part of the system programmer’s responsibility is to provide technical support to the users of the environment. This support can be answering questions about a product or analyzing a potential defect in the product (IBM or third party).
Systems programming is what happens when you apply the OSI model to the interconnections required for you to have a happy user, using your application.
Oh, that's too simple, I hear you say! Not at all. The model just gives you the harness you need to grasp the complexity.
If you're not "OSI ALL THE THINGS!" you didn't quite get the memo that the network is the computer, and thus "ALL THINGS ARE OSI'able!"
The model was developed during the network era, but has been discovered broadly through wide application that it is applicable to all systems interconnection.
https://en.wikipedia.org/wiki/OSI_model
When you traverse the OSI layers successfully, identifying and creating the components relevant to the layer interconnects, you are a systems programmer.
Of course this is a generalization, but holds surprisingly true.
Same debate happens with system(s) administration/administrators. It’s subjective and subject to pedantry
You're programming something to be used in systems.
Without any philosophy, clear and concise.
Everything programmed are systems but not all systems are programmable
I don't understand the use of but here. This doesn't contrast with what I said.
>Everything programmed are systems
Then 'systems programming' is a redundant turn of phrase. You don't say you're 'food cooking', while there are foods you don't cook.
I meant that I don't agree with your sense of the word 'system', as clearly and obviously referring to software development. Of ourse, if paired up with the words 'development' or 'programming', the association is there.
Still, the following titles reads to me as very different occupations:
- Systems Programmer (low-level, bare metal)
- Systems Engineer, (e.g. aeronautics, robotics, banking, requirements)
- Systems Developer (business domains, processes & people, services)
biases all mine
Basically, don't put that on your CV unless you know the company doesn't filter resumes through HR and has somewhat technical management.
And OCaml is more system oriented than C? He does not even know why so many people are using C for system programming.
System programming: bug bricks box.
:-)