44

Without being presumptuous, I would like you to consider the possibility of this. Most OS today are based on pretty low level languages (mainly C/C++) Even the new ones such as Android uses JNI & underlying implementation is in C

In fact, (this is a personal observation) many programs written in C run a lot faster than their high level counterparts (eg: Transmission (a bittorrent client on Ubuntu) is a whole lot faster than Vuze(Java) or Deluge(Python)). Even python compilers are written in C, although PyPy is an exception.

So is there a particular reason for this? Why is it that all our so called "High Level Languages" with the great "OOP" concepts can't be used in making a solid OS?

So I have 2 questions basically.

  1. Why are applications written in low level languages more efficient than their HLL counterparts? Do low level languages perform better for the simple reason that they are low level and are translated to machine code easier?
  2. Why do we not have a full fledged OS based entirely on a High Level Language?
rtindru
  • 559
  • 1
  • 4
  • 6
  • 36
    You imply that only "High Level Languages" are object oriented, which is not true. – Uooo Jun 28 '13 at 07:59
  • 1
    I can't bother writing a full answer, but someone should cover at least the simple and exact nature of C(and C++ to some extent) and it's execution model compared to languages like Java or C#, let alone Python or JavaScript. I think this is the exact #1 reason why most OS stuff is in C. – zxcdw Jun 28 '13 at 08:28
  • 3
    @rtindru "Pretty low-level language" (mainly C/C++)? What is your definition of High-Level Language then? You need to be clear about your definition/interpretation of High-Level Language. Python is actually a scripting language as it gets executed directly on its engine (IDLE or command line terminal), if you did not realise that by now. There is a very good reason (philosophical and practical) why C/C++ are used as implementation languages for lots of OS, but I am sure the power users here will probably not be jumping into that for this question. – ha9u63a7 Jun 28 '13 at 08:38
  • 10
    Android is not a brand new OS. It's just another Linux flavour. – Den Jun 28 '13 at 08:45
  • 3
    @hagubear _There is a very good reason (philosophical and practical) why C/C++ are used as implementation languages for lots of OS_. What is this very good reason? – rtindru Jun 28 '13 at 09:30
  • At least in the case of Java and any of the .NET languages a virtual machine is required to translate non-assembly code into assembly code. While it would be possible to boot into a virtual machine that executes the code, this would add an additional overhead, its simply is worth the performance loss. Furthermore a good Java/.NET Programmer can make a certain types of program perform faster then a "low level language" programmer so your personal experience is flawed. – Ramhound Jun 28 '13 at 10:40
  • @Ramhound My personal experience is working with 10-12 different software systems that uses wither C/C++ as the code base, Windows/Linux/QNX as the OS, and further integration with external software in the form of executables/object files (which are also done in C, FORTRAN, ADA, COBOL, etc.). The timeline goes as far back as 10 years. Even now, lots of engineers I know prefer C/C++ than Java/C# for their target system. You got to be careful when saying "Worth the performance loss"; this may not be valid for safety/mission critical system. I respectfully disagree that C/C++ isn't HLLs. – ha9u63a7 Jun 28 '13 at 11:11
  • @hagubear - My comment was suppose to indicate that the virtual machine used to translate the language those languages use into machine code is not worth the performance loss. indicating that because of the performance loss its simply isn't worth while to create a operating system with those languages. – Ramhound Jun 28 '13 at 11:17
  • 2
    If I understand correctly, the OS for LISP machines were written in LISP. Though perhaps it could be argued that the dialect used was a low-level language? – Robert Fisher Jun 28 '13 at 13:39
  • To avoid confusion this question should be changed to why are most OS's written C/C++ or "close to the metal" languages. I think most people would consider them high level languages. – pllee Jun 28 '13 at 16:45
  • 1
    @pllee Depends on what "level" you usually work at. I'm in Python and Javascript all day, so C looks pretty low-level to me. – Izkata Jun 28 '13 at 16:48
  • 1
    http://stackoverflow.com/questions/6638080/is-there-os-written-in-haskell – Thomas Eding Jun 28 '13 at 18:40
  • @Izkata C/C++ are much lower level than what I am working with now but I still consider them high level languages. But I guess it is all up for debate. – pllee Jun 28 '13 at 18:51
  • 1
    For the most part, you DON'T need a low-level language for an operating system. However, there are places where you DO need low-level language facilities. By low-level I mean control over your data structure layout down to the bit level and freedom from any language runtime interference such as a garbage collector or thread system. Where possible, you don't want to sink as far as assembly language, so most work at this level is done in C. – Rafe Jun 30 '13 at 11:23
  • The Burroughs B5xxx - B6xxx computers had an ALGOL dialect as its operating system language. It also had stack hardware to facilitate the language. – donleslie Jul 01 '13 at 19:26
  • Eiffel is a high-level OO language. However it can be compiled to very fast C. – ctrl-alt-delor Sep 14 '17 at 13:50

10 Answers10

41

A lot depends on where you put the division between low-level and high-level languages. For example, different people tend to put a language like C++ on different sides of that divide.

Regarding your questions:

  1. I don't believe there is such a difference between low-level and high-level languages, but more a difference between interpreted languages and languages that compile to native instructions.

    But there might also be a difference in culture between programmers, where the once that use a low level language focus more on the performance aspects of the (design) choices they make.

  2. If you consider C++ to be high-level, then there is at least one OS written entirely in a high-level language (Symbian OS is written in C++). What stops you from writing an OS in most high-level languages are two things:

    • An OS needs low-level access to memory and hardware and perform dirty tricks on them. This kind of access is generally considered unsafe for application-level programs, so many high-level languages don't allow it.
    • An OS needs to execute without support software being present, such as interpreters. This makes it extremely hard to write an OS in a language that can't easily be compiled into native instructions.
Bart van Ingen Schenau
  • 71,712
  • 20
  • 110
  • 179
  • 36
    There is no such thing as an interpreted language or a language that compiles to native instructions. A language is a set of mathematical rules, it is neither interpreted nor compiled, it just *is*. Interp. and Comp. are traits of, well, the interpreter or the compiler, not the language. Every language can be implemented using a compiler or an interpreter. Most languages today have both interpreted and compiled implementations. There are interpreters for C and all major JavaScript implementations compile to native code. And what is native code anyway? If I compile Java to JVM bytecode and run – Jörg W Mittag Jun 28 '13 at 10:53
  • 11
    that on a Java CPU, and I compile C to ARM machine code and run that on an ARM interpreter because my PC doesn't have an ARM CPU, then what makes ARM native and JVML not? – Jörg W Mittag Jun 28 '13 at 10:53
  • 6
    @JörgWMittag: If you have a CPU that can directly execute Java bytecode (without using an additional JVM), then Java bytecode is native code for that CPU. Also, I don't rule out the possibility of writing an OS in a language that is typically interpreted or executed in a VM, but it does make them less obvious choices. – Bart van Ingen Schenau Jun 28 '13 at 11:58
  • 15
    @JörgWMittag - I agree that any language can be compiled or interpreted (compile a bash script; use interpreted C++ (CINT/Cling)), but many decisions in language design are based on will this be interpreted, compiled, or both. A language that makes you manually declare/initialize statically-typed variables, manually allocate/free memory, do pointer arithmetic, remember to check array bounds will be less convenient in an interpreter (versus a language that garbage-collects memory, infers dynamic type, checks array bounds). Is this line 100% clear? No, but the difference exists in practice. – dr jimbob Jun 28 '13 at 20:30
38

Microsoft has done some very interesting research in this direction, if you look into Singularity:

http://research.microsoft.com/en-us/projects/singularity/

Also, Mothy Roscoe et al have been working on Barrelfish which uses the Eclipse constraint programming language as an OS service to sort out all kinds of OS management and resource allocation problems:

http://www.barrelfish.org/

Rafe
  • 631
  • 5
  • 3
  • Wow, I can't vote up, need 15 reps... just joined today! Thanks a lot. – rtindru Jun 28 '13 at 07:55
  • 9
    @rtindru: even with 1 rep point you can accept an answer [What does it mean when an answer is "accepted"?](http://programmers.stackexchange.com/help/accepted-answer) – Marjan Venema Jun 28 '13 at 11:01
  • 6
    Accepting an answer tends to cut down on new answers/discussion. Personally, I would recommend against accepting (to this specific question) for at least another day. – Brian Jun 28 '13 at 16:02
  • 1
    I would add Cosmos to the bunch: open source, third party, not as interesting as singularity but have some nice ideas! http://cosmos.codeplex.com/ – Lorenzo Dematté Jul 05 '13 at 07:17
17

There are a number of good reasons for this.

Today's low-level language was yesterday's high-level language

Yes, believe it or not, once upon a time even C was viewed as a high-level language. Even ~20 years ago it was common enough to see it described as a "mid-level" language. This was a time before OO was as popular as it is today, Java didn't exist, C# didn't exist, even C++ wasn't properly standardized yet.

Historical Inertia

Operating systems that you use today have deep deep roots in history. Windows goes back to the early/mid 80s, Unix goes back to the early/mid 70s. There is a LOT of old, working code in operating systems, and you generally don't want to rewrite old, working code.

At some point you have to go down to the hardware

This happens in the kernel, it happens in drivers, it happens in memory management subsystems, it happens in the filesystem. Sure you can layer a high-level language on top of it, but you still need the ability to more directly access the hardware that a lower-level language offers.

Portability

I don't mean portability to different hardware or a different OS as it's more commonly understood today; this is more subtle. There is one major advantage of providing a C-based interface for something, and that is the fact that virtually every other language that exists can link to C. Even the Windows API is still a C-based API these days for that reason.

Personal Preference

Some people just prefer to program this way, and that can be a major factor. For example, Linus Torvalds has a famous rant against C++ which makes it pretty clear that as far as he's concerned, C will always be his tool of choice for this kind of work (the content of the rant and whether or not you agree with it is irrelevant to this discussion; the fact that the rant exists is enough).

Taken together, these should clearly establish why an operating system was originally written in something like C back in the old days, and why very significant chunks of it - even today - remain so.

Maximus Minimus
  • 1,498
  • 10
  • 11
13

First, there are some bootstrap issues. Most of the features that make high level languages easier are based on abstractions that a kernel must provide itself. How do you write a memory manager in a language that requires a memory manager? How do you write I/O drivers without using the nice I/O standard libraries of your language? How do you create threading and synchronization primitives without using the language's libraries?

Second, it's extremely useful and much more readable when writing operating systems to be able to assign a variable to a specific memory location. This is easy in C, and every single C programmer knows how to do it. If it's even possible in higher level languages, it's so rare that only gurus know how to do it.

In other words, when you account for all the limitations and modifications you would have to accept, C and C++ start looking a lot easier.

Karl Bielefeldt
  • 146,727
  • 38
  • 279
  • 479
  • 2
    Your first paragraph makes no sense. An I/O driver in C doesn't use `stdio.h` either. A custom mutex implementation doesn't use pthreads. That's precisely what it means to implement it yourself! And that is independent of the language you're using. That is not to say high level languages are a good choice for low level tasks (they usually aren't in my experience). –  Jun 28 '13 at 16:12
  • I'm aware of that. I'm just pointing out that a lot of what differentiates a high level from a low level language is in those parts of the language that are unavailable in kernel development. When you compare languages core to core, C doesn't look so spartan any more. – Karl Bielefeldt Jun 28 '13 at 16:21
  • 1
    Not quite true. While you'll need *some* code that doesn't use X to implement X, all remaining code can depend on that code and use X. –  Jun 28 '13 at 16:28
  • That's a good point. – Karl Bielefeldt Jun 28 '13 at 16:33
12

A main reason for the dominance of C for operating systems lies in history - current mainstream operating systems like Windows and all forms of Unix (BSD, Solaris, HP-UX, MacOS X, ... as well as clones like Linux) go back a long time, before OO and other "high level" constructs became mainstream.

For the core of the operating system besides performance there are needs to e very specific about the hardware instructions and one needs full control over memory which languages like C do very well.

For embedded systems there sometimes are operating systems using higher level languages for greater parts of the system. One notable example is JavaOS by Sun.

For widespread operating systems an notable example not using C also is the classic MacOS before MacOS X - that was in large parts written in a dialect of Pascal which allowed some form of object orientation.

johannes
  • 3,601
  • 2
  • 26
  • 32
6

First of all, bootstrapping requires at least a small part to be written in Assembly or equivalent.

Second, there was a OS written in an indisputably HLL - Lisp Machine. (The fact that it failed commercially had more to do with other hardware becoming cheaper faster and the triumph of Worse is Better than with deficiencies of its philosophy or design).

Third, C++ is quite object-oriented and high level, so, as others pointed out, Symbian OS is another example.

Fourth, there is little need for new OSes at this time. We already have quite a few linux and bsd flavors which run on just about any hardware, and creating a brand new OS from scratch is quite expensive.

sds
  • 729
  • 5
  • 12
  • You missed the Burroughs B5000 mainframes. Their operating system was written in Burroughs Extended ALGOL. – John R. Strohm Jul 02 '13 at 15:21
  • 2
    `there is little need for new OSes at this time` I have still not decided myself if this is true or not.. Yes, modern OSes (modern windows (NT) / modern Unix) are all we need, functionality and performance wise. But barely: they are born in another area where "the net" was corporate/university and the users trusted, and multiproc was 2/4 processors. They are "plagued", to some degrees, by the excess of trust (rootkits, malware, viruses..). I am starting to think that there IS space for a modern, safe, isolated OS ... with better support for parallelism too (better then threads) – Lorenzo Dematté Jul 05 '13 at 07:14
  • 1
    Lisp *is* low level, `CAR` and `CDR` are [IBM 704 assembler macros](https://en.wikipedia.org/wiki/CAR_and_CDR#Etymology)! Even [C segregates inline assembly](http://www.codeproject.com/Articles/15971/Using-Inline-Assembly-in-C-C), rather than treating it as any other function. Considering Lisp's `CAR` and `CDR` work on x86, ARM, and a host of over ISAs, that's some impressively portable assembly. (Side note to anyone I may have confused: Yes, Lisp is a high level language. `CAR` and `CDR` being assembler macros was just an implementation detail, not a key feature. ;) ) – 8bittree Oct 28 '16 at 17:50
5

To better phase what I wrote previously.

The Burroughs 5xxx - 6xxx machines did not have an assembly language. The lowest language available was an extension to Algol. The Algol was implemented in hardware. The OS and all languages were written in Algol. It outperformed all the competitor machines of the time. It also required significantly less code which made it much easier to maintain. It had stack hardware which supported a recursive language such a Algol.

The Burroughs operating system evolved into a version called MCP. MCP currently runs on Unisys systems.

donleslie
  • 81
  • 3
  • I seriously doubt they implemented an Algol *compiler* or *interpreter* in hardware. Hardware much prefers `1 2 3 * +` over `1 + 2 * 3` and it's completely inconceivable they would've designed hardware to process `1 + 2 * 3` in any way whatsoever – user253751 Jul 26 '21 at 16:52
3

Most of the higher-level languages that you mention have a feature that doesn't fit well with operating systems: Automatic memory management. You can't rely on a garbage collector when writing a real-time system -- either soft (which is what an operating system is) or even worst hard. To quote Tanenbaum [i]:

Some things that C does not have include built-in strings, threads, packages, classes, objects, type safety, and garbage collection. The last one is a show stopper for operating systems. All storage in C is either static or explicitly allocated and released by the programmer, usually with the library function malloc and free. It is the latter property -- total programmer control over memory -- along with explicit pointers that makes C attractive for writing operating systems. Operating systems are basically real-time systems to some extent, even general purpose ones. When an interrupt occurs, the operating system may have only a few microseconds to perform some action or lose critical information. Having the garbage collection kick in at an arbitrary moment is intolerable.

Now, you might argue that C++ is also a good candidate since it offers manual memory management. C++ has already been used in some operating systems such as Symbian (mentioned by Bart) and BeOS. But IMHO C is still the fastest language that can be ported in many architectures without a huge effort (in contrast to assembly of a specific architecture).

[i]: Modern Operating Systems 3rd edition, page 73

sakisk
  • 3,377
  • 2
  • 24
  • 24
  • 4
    Symbolics machines had automatic memory management. Smalltalk did on an Alto. That was in the 80s. A linear type system removes the necessity for GC completely. These are solved problems, if only we could remember that! – Frank Shearar Jul 03 '13 at 19:52
  • 1
    It would be possible for a language to include automatic memory management, but include a special kind of "deeply-pinned" reference and allow methods to explicitly declare that they will not access any non-pinned reference nor invoke any methods that might do so. There would be no need for a stop-the-world garbage collector to interfere with code running in a method which was not going to access any objects that might be modified by the GC. – supercat Jun 12 '14 at 16:17
2

As others have pointed out, several operating systems have been written in high level languages. Perhaps what you mean is that all the successful, mass market, general purpose OS have been written in some combination of assembly, C, and C++?

Most high level languages have tons of helpful features that carry an associated performance cost. Automated memory management is an obvious example, bounds checking of arrays is another. If you are writing a general purpose OS you are likely to run into situations where the performance penalty of these helpful features is more than you are willing to pay. At that point you'd like to be able to turn them off. Languages like Python, C#, and Java vary in which features you can turn off, but none of them are as versatile as C or C++ in this regard.

In this aspect C and C++ are almost as versatile as pure assembly. If you decide that you need ten different memory managers covering ten different memory allocation scenarios you can implement them all in C and C++, and load and unload them as you see fit. Heck, you don't even have to link to the standard C runtime libraries or startup code if you don't want to.

Charles E. Grant
  • 16,612
  • 1
  • 46
  • 73
0

The real answer is Money. There's not enough perceived benefit of a high level language OS to justify spending the resources to build one and then push it into the mainstream. There's massive cost involved in building a new driver for each piece of hardware it needs to support, for example.

There are various OSes written in high level languages, with the primary purpose of research, such as Oberon and Singularity.

Peter
  • 3,718
  • 1
  • 12
  • 20