To the extent that there is a real distinction between "Systems Programming" and "Whatever is not Systems Programming" and to the extent that this distinction matters, I tend to align with the take espoused in the Systems Programming[1] Wikipedia page:
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.
In practice, the demarcation line for "systems programming" is when the software directly controls and manages the hardware resources it uses. Software like this takes on some of the characteristics of an operating system because it is required to provide similar functionality, even if not an operating system per se. In application code, some other piece of software, usually the operating system, takes care of this for you.
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.
I think embedded is a distinct subset of systems programming. It definitely deals with hardware resource management, but is a bit different because it tends not to build the high-level resource management abstractions on top of the hardware for other application code to use e.g. what a database kernel is to a database.
Rabbitmq is a good counterexample. It is overwhelmingly used to provide services to other programs, deal with resource/performance constraints every second, but is an application-level program. Written in non-system programming language and not part of operating system and never will be.
It's interesting in that the RabbitMQ example helps illustrate how fuzzy and subjective this all is. Some people would definitely take the approach of "it's not part of an operating system so therefore it's not 'systems' code". Personally I would disagree. I've always considered "middleware"'ish type stuff to be "systems level" by virtue of the "it mainly provides services to other software" aspect of the definition seen above.
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?!??
>I've always considered "middleware"'ish type stuff to be "systems level" by virtue of the "it mainly provides services to other software" aspect of the definition seen above.
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 think based on the parent posts choice to go with the "who is your customer" definition and the fact that we intuitively think of RabbitMQ as some sort of systems program, it probably fits the modern definition of systems program that we all kind of agree with but do not necessarily put into words.
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.
> whereas systems programming aims to produce software and software platforms which provide services to other software
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.
A somewhat better dichotomy, faulty as all dichotomies, I suppose would be: No Magic Programming and Plenty of Magic Programming (or even All the Magic Programming). Where by magic one understands the expectation of the developer for the system to "just work": from the CSS developer writing a line such as `color: red;` and having no second thoughts to the browser engine developer knowing/caring about all the layers, from parsing to composition, to actually display a red colored text.
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.
I think this is a different dichotomy - declarative vs imperative. Generally, the declarative languages have all the magic implemented in an imperative engine.
It is a meaningful distinction. A mobile, desktop or a web app solves a problem for the end user and should be under their control via commonly-understood UI metaphores and IO mechanisms.
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.
It's still a continuum, not distinct categories. People can't deal with that, and given the fact that there is really zero point talking about this continuum (it's not even in job titles) I would say we should just ditch the term "systems programming" entirely.
Kubernetes is clearly a different sort of program compared to Microsoft Word. Even if we don't have a rigorous ontology that sorts them into two distinct boxes neatly, they're just so different at the extremes that it's useful. We make a distinction between pulmonologists and cardiologists even though they both know anatomy and deal with the human body, and as we mature as a discipline, specialization is only natural. Denoting the area someone works in as belonging to one group or another is useful for determining peers that share your concerns, vs people that work in totally different areas from you. That doesn't make them better or worse than you, just different.
To me, one difference often is how much you have available to build on. At least for some "systems programming", the answer is: Not much.
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".
Every software has a user. Other programmers are users too. In addition, all software is performance constrained, as no user has an infinitely fast computer or infinite time.
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?
Even if we did make it clear which is which, what's the gain from being able to make a clear distinction?
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.
if we simplify it to being an OS (systems) vs a gui (applications) programs, we can see their purpose, philosophy, and reality. The OS' purpose is to run other programs, and thus that interface, Elf, is full of technical implementation details fitting the philosophy of a OS that allows multiple processes to run, and reality - Linux (OS) does not compete with Airbnb (application).
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.
The distinction goes to use case, and helps the hammer and nail programmers not get into arguments with the screwdriver and screws programmers over which is better - a hammer or a screwdriver? Of course, we as an industry love to argue, but I do think there is some use in having a distinction. Systems programmers have other programmers as users, application programmers have people as users. B2B vs B2C.
Got it. Businesses heavily employing a B2C marketing strategy should employ Python, Java and JavaScript programmers, while the B2B equivalents should use C and C++. Very useful to be able to make these decisions on a higher level, so that programmers don't need to argue about which tools would be well suited for a particular product. Allowing sales to make these decisions for us will improve our time to market.
My personal distinction is that application programming is more selfish, not interested in most other parallel applications whereas systems programming needs to take a more global view to ensure the system serves sufficient resources to all applications
Well, arguably any library provides services to other software and not directly to the user. The definition needs to be more specific than that. Is implementing left-pad systems programming?
Will makes a dubious claim to support a dubious distinction. Plenty of large, complex infrastructure is written in Python.
> 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."
I liked much of your critique, but you completely lost me with your last para.
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
For me "systems programming" is just low level programming. You do it when you need to access the hardware, when you need performance.
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.
Systems programming is when you break-out from your shiny MVC API and libraries, and start reading section 2 of the Linux/BSD manual. When you start caring about process and thread affinity, memory allocation patterns, CPU cache performance, etc.
Yet an operating system is at a higher level, above the kernel. Traditionally, systems have been the middle ground between the low level and the high level.
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.
There's a slight variation on this, although I never saw it said out loud: Low level or not, system programming is about interacting parts. Long ago, low level meant sending messages/signals to various chips to have the desired effect. It was cryptic and full of time and space constraints, and people equate system with these complex topics but to me the "interacting parts of a system" is still an important aspect of the definition. That's why I accepted go being a system language, it just wasn't operating at the electronic layer, but the computer/node level.. but it was meant to orchestrate messages concurrently between all these nodes, just like chips and signals long ago.
The problem with that distinction is that the word “system” doesn’t get to have a say in any of it.
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?
I see it as "systems programming" is building the "systems" that one later assembles into applications.
"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.
Which can even be done in BASIC, like on the 8 bit home computers, or the BASIC compilers available for MS-DOS, VAX/VMS, HP-UX and so forth.
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.
In IBM mainframes, "systems programmer" (sysprog) traditionally means "system administrator". Part of the reason for that, is a systems programmer was expected to be accomplished at assembler, which was used to write user exits (to customise the behaviour of the operating system to meet the needs of each site) and even patches to the OS code (SYSMODs). Operators were responsible for day-to-day running of the system (startup, shutdown, mounting and unmounting tapes and removable disk packs, changing forms in printers, starting jobs, resolving minor technical problems). Sysprogs were responsible for installation, configuration, customisation, upgrades, troubleshooting more complex problems, etc. Over time, the need to customise the code of the OS declined, and IBM made the OS much harder to modify by taking away customer access to source code (IBM's 1983 "Object Code Only" announcement) – so contemporary IBM mainframe system administration involves much less programming than it used to, but the name has stuck. Also, you no longer have to write user exits in assembler – C is supported (e.g. using IBM Metal C), as is PL/X (if you work for IBM, or one of the small handful of ISVs who ordered IBM's PL/X compiler during the brief period they were offering it to them)
I think when someone says systems, they mean computer systems. So the kind of things you're interested in are ultimately computer words like drivers, memory, threads, interrupts, queues. If that's your general level of abstraction you're system programming.
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.
Ultimately, the author comes to a dubious conclusion by ignoring the context. By studying what people were writing about in the 70s, he also ignores the context - it was a given that any program of significant size or of a fundamental nature would compile (efficiently) to machine code. The hardware was too weak to support anything else. A language that didn’t satisfy certain performance criteria wouldn’t even be a contender.
His odd conclusion being that ML languages like Haskell are "systems programming." I thought the rest of the article was mostly interesting, but how that could possibly be your conclusion is a bizzare mystery. My guess is he wrote the conclusion before the research and got the cart before the horse.
Perhaps from my limited AI-centric point of view, I have a simple definition of Systems Programming: when I hit enter and run Python/C/C++/Java program, what actually happens?
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.
Rust - absolutely, for sure! In terms of Assembly, it's incredibly difficult to write an efficient Assembly code these days, especially in a multithreaded, multicore environment. In such environment, as humans we just can't compete with compilers any more. Reading and analyzing assembly code from C/C++, - sure that's absolutely necessary. Writing an assembly code from scratch, better than compiler? I am sure people do that but that's ... quite hard.
Yes, but there are parts of the CPU instruction set which a compiler won't ever emit. If you are using those features, as certain low-level systems must, then you use assembly (typically shortish snippets called from a compiled program).
If you think the term "Systems Programming" is problematic, try "Computer Science". I have seen the term "Computer Science" applied in multiple college catalogs to MS office!
To me, it's "system software" when it's intended to be a building block for other software.
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).
I'm surprised to see a complete lack of application of the OSI model to answering this question.
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.
When you traverse the OSI layers successfully, identifying and creating the components relevant to the layer interconnects, you are a systems programmer.
The difference is that Systems programmers believe they are better (i.e., more skilled) than Applications programmers. Just like infrastructure engineers think they are better than backend engineers think they are better than fronted engineers think they are better than designers.
Of course this is a generalization, but holds surprisingly true.
As someone who speaks English poorly but has a little bit of experience with the subject, I surprised the proper name is systems programming, not system programming. Why it is so?
The expression is redundant isn't it? Only systems can be programmed. You can't program a cinder block or a cardboard box. I think this is just an early way to say 'software development' and people got caught up on their own mental images of what 'systems' are to them.
I kinda see what you mean, but systems is an exceptionally vague term. Popular use and even the formal field of Systems Science is hardly more related to computing than any other area of society.
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.
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)
Low-level programming is definitely more meaningful, the problem is it fails the HR speak test - they tend to think it means just not very strong programming.
Basically, don't put that on your CV unless you know the company doesn't filter resumes through HR and has somewhat technical management.
I think that the big iron definition was "using BAL [basic assembly language?] on IBM hardware." Anyway, I knew a guy in the 1980s who described himself as a systems programmer, and as far as I know that was what he did.
By definition, a system is something comprised of multiple parts that build a whole. Thus systems programming would be combining and architecturing systems out of other parts, making them connect, designing interfaces etc?!
I always thought Systems Programming == using syscalls, even if done in an interpreted language. Not sure where I picked up that definition or if anyone actually shares it.
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.
[1]: https://en.wikipedia.org/wiki/Systems_programming