I am taking an introductory course on python and the instructor says that python is a high level language and C and C++ are low level languages. It’s just confusing. I thought that C, C++, Python, Java, etc were all high level languages.
I was reading questions at stackoverflow on C, C++, etc and they all seem to refer to those languages as high level. It seems to me that some programmers use those terms interchangeably.
2
High level and low level are relative terms so the usage has changed over time. In the 70s UNIX made waves because it showed that an operating system could be written primarily in a high level language: C. At the time C was considered high level as in contrast to assembler.
Nowadays C is considered a low level language because neither the language nor the standard libraries provide any of the bread and butter data structures like vectors, dictionaries, iterators, and so on. You can have all those structures in a C program, but you’ll end up writing them yourself. Python, Java, etc. are high level relative to C because many of those standard data structures are built in to the language or are part of the standard libraries. Having those right out of the box makes it easier to program at a more abstract level.
C is low level in a 2nd sense: it enables direct manipulation of the computer hardware (at least as direct as the OS will allow). The most common implementations of Python, Java, etc. are at least one step further removed from the hardware because they run in a VM. If you want to manipulate the hardware from Python you’ll have write an extension to the Python VM, usually in C or C++.
C++ is an odd case. It provides tons of nice data structures as part of the standard library, but it also allows low-level manipulation of the hardware.
11
Think of this in terms of a sliding scale, from LOW-level languages all the way through to HIGH-level languages. As a language moves up the scale, from LOW to HIGH, the language provides more and more abstraction from the specific interface with the computer.
LOW-level languages are written to explicitly direct the computer – think machine code and assembly code.
HIGH-level languages attempt to abstract away the nitty-gritty details (particularly memory allocation and release of memory). The idea is to provide a more “natural” interface to programming and hopefully allow the programmer to focus on design and production.
These days, C is regarded as a LOW-level language. It still has some significant abstractions from machine code and assembly code, so is technically ‘higher’ than these. However, it does still provide direct memory addressing and not provide garbage collection. So these are details a programmer must design for.
Compare this to other languages such as Python, Ruby or Haskell and you have a much more obscure interface. These languages have large libraries of code that abstract away most of the computer command. Ever wondered what happens to a variable in Python when you leave the local scope of a function, or delete it? Probably haven’t right? And that is because in a HIGH-level language you don’t have to! They look after the memory allocation / release for you.
HIGH-level languages have the advantage of function. They allow us to design and develop freely (and safely!).
LOW-level languages have the advantage of speed in most cases. There is a cost to interpreting HIGH-level code. Plus, it is kinda cool to write something in ‘computer speek’.
Hope this helps
High-level vs. low-level is not a black-and-white thing, but a continuous scale. The terms are used to describe how close a programming language is to the hardware; the higher the level, the more it abstracts the hardware away.
The lowest level, obviously, is binary machine code – it is the exact representation the OS loads and feeds to the CPU. Assembly is the first level of abstraction built on top of it: instead of binary code, one writes mnemoics, human-readable symbolic codes that represent binary machine instructions. This is what people used for systems programming before UNIX.
C is the next step up in the abstraction chain, bundling common patterns into flow control constructs and abstracting machine-specific instructions into platform-agnostic syntax, and this last abstractions was one of the major factors that made UNIX both revolutionary and highly successful, because it meant that the same code could be compiled for any platform without any major changes.
C++ adds another layer of abstractions: it adds classes (abstracting vtables and context passing into an OOP syntax), new
and delete
(bundling memory allocation and variable initialization into a single construct), compile-time type checking, templates (type-safe compile-time metaprogramming), and a bunch of compile-time syntax conveniences like namespaces, function and operator overloading, etc.
Python takes another big step away from the hardware. C++ still gives the programmer full control over memory allocation, and allows for direct manipulation of RAM; Python takes care of memory management for you. Additionally, instead of compiling your code to all-native machine instructions, it runs it against a virtual machine; this carries a performance penalty (which can sometimes be hefty, but usually isn’t something to worry about), but it also allows for neat things that would be tricky in C++ and excruciatingly hard in C, such as manipulating functions and classes at run time, getting the names of arbitrary objects at run time, instantiating classes by name at run time, monkey-patching, etc. etc.
So when people divide languages into “high level” and “low level” ones, they draw an arbitrary line somewhere, and that line isn’t always the same. In 1970, the line was between assembly and C (abstracting away platform-specific machine instructions being the decisive factor); in 1987, it may have been somewhere between C and C++; today, it may be between C++ and Java (with automatic memory management as the decisive factor).
Long story short: high-level-ness is a sliding scale, and for the three languages you mention it’s C < C++ < Python.
1
The line between the “low-level” and the “high-level” languages shifts from time to time.
For example:
Back in the days of UNIX, C was a high level language.
Today C doesn’t have the structures like the mapping types(dictionaries), iterators etc. which today’s high-level languages like Python have. So the line has shifted, and C has now fallen into the low-level group.
Low-Level Languages:
These languages are “close” to what the machine can execute (the lowest level being : Assembly Code!).
When working with these languages, the programmer has to think about the lowest level stuff like memory management.. You are close in that sense to the hardware, that you have to directly work with it.
High-level Languages:
These languages take you away from the hardware, as they manage things like memory themselves. When you work with these languages, memory is a factor(obviously), but you don’t work with the hardware directly. Instead the language manages that, keeping you away (maybe higher) from the lower, hardware interface.