Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Traditionally, C was called a high-level language, but these days it is often referred to as a low-level language (it is high-level compared to Assembly, but it is very low-level compared to, for instance, Python, these days). Generally, everyone calls languages of the sort of Python and Java high-level languages nowadays.

How would you judge whether a programming language really is a high-level language (or a low-level one)? Must you give direct instructions to the CPU while programming in a language to call it low-level (e.g. Assembly), or is C, which provides some abstraction from the hardware, a low-level language too? Has the meaning of "high-level" and "low-level" changed over the years?

share|improve this question
10  
I think it would be better to call C a mid-level language (really, why limit it to just high -level and low -level; there are in-betweeners too): it's much higher-level than assembly, but not as high-level as Java, Python, C#... And I guess C++ would be a mid-to-high-level language. It has the low-level stuff of C but lots of "high-level" stuff too. –  FrustratedWithFormsDesigner Feb 2 '11 at 15:15
    
@FrustratedWithFormsDesigner +1 Good point –  Anto Feb 2 '11 at 15:16
2  
You can say COBOL is a HIGH-level language since it gets you HIGH pay these days. –  user8685 Feb 2 '11 at 15:21
3  
@Developer Art, highest-level language I've found is called Cannabis. –  Neil Feb 2 '11 at 15:24
add comment

10 Answers 10

up vote 9 down vote accepted

There is no such a thing as high-level language considered without context. Instead, when taking two languages, one may be more high-level than another.

It means that to consider a language to be high-level or not, you must either talk about another language to compare to, or to compare to most known languages at the moment of time.

The fact that your own question starts by "Traditionally, C was called a high-level language" illustrates that. Yes, C was a high-level language, because there was C, and there was Assembler. In this way, C was a higher-level language than Assembler. Today, C is not a high-level language, because there is C#, Java, and others, providing higher abstraction than C.

Note that by "providing higher abstraction", I mean allowing to think more about what your code is doing and less about how it is done.

A higher-level language allows you to do it, but it doesn't mean that it force you to do it. That's why (nearly?) everything that you can do in Assembler can be done in C, if needed, even if C is a high-level language compared to Assembler. Languages as C# also provide an ability to write low-level code if needed, but in most cases, you stuck with much more abstract code, compared to C.

share|improve this answer
1  
The implicit context is 'all programming languages'. That's why, even though you say 'There is no such a thing as high-level language...', you are able to later contradict yourself by saying 'Today, C is not a high-level language'. This is obviously and implicitly understood as 'Today, in the context of all programming languages', C is not a high-level language'. Having said that, this is a silly point to make because it's just as fair to argue 'There is no such thing as a fast car without context', or 'There is no such thing as a hot day without context'. –  Kirk Broadhurst Feb 8 '11 at 6:05
    
There is no such comment as the above comment without context. –  Tiberiu-Ionuț Stan Jul 28 '12 at 12:13
add comment

Wikipedia:

strong abstraction from the details of the computer

and more specifically

includes concepts from the problem domain instead of those of the machine used

What are "details of the computer"?

There are too many to list. The are generally either details of the computer architecture (generally solved by the core language) or interface and protocol details that are outside the problem domain (solved mostly by libraries).

Computer architecture examples:

  • Registers, the stack, the instruction pointer and jumps - almost all languages other than assembly abstract these, generally into function or method invocation.
  • Linear execution and program flow - Abstracted by logic languages, lazy functional languages and langauges with continuations; not so much by anything else.
  • Memory locations and memory management - The reason why C, C++ and Objective-C are not completely "high-level". Very HLLs provide garbage collection.
  • How big is a machine register, or a word/byte of storage? How many bits are in an "Integer?" What's a "floating-point number"? What's the biggest or smallest one I can have? Java and C# (and many others) expose this to the programmer; this one bothers me.
  • How many processors does the computer have? How do I divide large tasks between them? Again, most supposed high-level languages leave you on your own here.
  • What physical inputs and outputs does this computer have? To mice and keyboards, screens, printers, a network?

Interface/protocol examples:

  • File formats, file locations and filesystem layout. Varying support.
  • Operating System calls - Mostly wrapped in built-in libraries. Occasionally (C family) available directly but avoided.
  • Network protocols - What details aren't handled by the OS are either handled by libraries or not at all (HTTP, SMTP, etc.).
  • GUI APIs, CLI APIs, service APIs... Both consuming and providing.
  • Too many more to mention

What are "concepts from the problem domain"?

Depends on who you ask, and how they choose to view the problem.

Most major programming languages take a singe general view of all problems and how to produce solutions; these tend to align with one or more of the major paradigms (procedural, functional, OO, logic, array, etc.). General programming languages thus view the problem domain as "almost everything".

Some languages work especially hard at allowing the user to create domain-specific languages, either by allowing direct extension of the syntax (Common Lisp, Scheme, OCaml) or through other means like metaclassing (Python, Ruby) or combinators (Scala, Haskell).

There are true specialized languages that approach a smaller problem, but you mostly see them inside a host language. There's XSLT for formatting, Regular expressions for string mangling, SQL for (somewhat) relational data, and XML-based languages for just about everything.

Whoops, that wasn't the question.

Here's my rough division of 3 subdivided "heights" of language level, from highest to lowest. This is based on the above ideas, sort of. Oddly, the languages at the very top are the least powerful and general; some may not even be turing complete!

In my opinion, the most high-level languages are those that almost entirely throw out how the surrounding computer works. There are really about three categories of these:

  1. Business domain specific, e.g. languages specific to phone systems or dolphin research or DSP. These are more rare than they used to be (say, per programmer alive). These "include specific details of the problem domain", as above.
  2. Task-specific Little Languages like XPath, XSLT, smaller SQLs, Regex, Make, dc or m4 macros. See link for many more (mostly Unix-related). These mitigate specific "details of the computer", as above.
  3. Very high-level general languages that are divorced from the underlying computer to a specific end. The languages I consider in this category take one or more language paradigms to a useful extreme: J, Prolog, Haskell, Oz, IO, and perhaps some concurrency and dataflow languages. These attempt to completely eliminate "details of the computer" and also clearly have the ability to approach all problems that are not bound to hardware.

The remaining languages that I consider high-level languages are those that provide a straightforward way to build DSLs or other very clear, compact interfaces. (These interfaces, in function, qualify as "little languages" as above!) These I separate again into (ranked-ish) categories:

  1. Lisp dialects and other systems with syntactic macros (Dylan, Metalua)
  2. Languages that strongly encourage DSLs and compact APIs. This means simple syntax and "late binding in every aspect". Here I include Python, Ruby, Smalltalk, IO, and many others.
  3. Statically typed languages reasonably suitable for building compact interfaces and DSLs (Scala, OCaml) and dynamic languages with possibly too much baggage for DSLs and transparent interfaces (Javascript, Perl, Lua).
  4. Other languages, when equipped with text macros or code generation systems. Not ideal, but better than nothing.

Below this is everything else. They vary by level, but they are not high level anymore. This includes languages like C, C++, Java, C#, Cobol, VB6, VBScript, PL/1, Ada, perhaps the Algol family... You name it.

Specifically Java and C# (and even C++) may impress others as "high-level", but for me they have too many strikes against them. I feel the class systems and type systems are still dictated by the hardware and speed concerns in much the same manner as C functions and structs. In particular, those languages force the programmer to be needlessly concerned with how many bits or bytes are in everything.

TL;DR: From highest to lowest, business domain-specific languages, then little languages, then very high-level functional/array/OO/concurrency languages, then Lisps, then expressive dynamic languages, then expressive static languages, then everything else.

share|improve this answer
    
if I remember correctly, even Haskell Int is finite, isn't it ? –  Matthieu M. Feb 2 '11 at 17:51
    
Yes, but Integer is arbitrary, and I believe that integer literals are Integer type by default. That said, I do pick on languages I don't like about this (C++, Java) and tend to leave others alone (Lua, Perl)... –  Jesse Millikan Feb 2 '11 at 19:15
add comment

To me higher-level means, more declarative. In lower-level languages you tell the computer exactly what to do, how and when. In declarative languages you can focus on your business logic/intentions.

In that sense it's shades of gray instead black/white. Forth for example can be both low-level and high-level.

See this overview: http://www.info.ucl.ac.be/~pvr/paradigmsDIAGRAMeng.pdf

share|improve this answer
1  
I like the diagram. –  FrustratedWithFormsDesigner Feb 2 '11 at 15:27
    
Me too, although I'm sure Scheme belongs over there with OCaml. It most certainly has "cell state". Maybe the creator only read The Little Schemer... –  Jesse Millikan Feb 8 '11 at 2:16
add comment

Is it closer to your native language or machine language?

The highest level language would be English (or any other language spoken and written by humans). The lowest level is machine language, getting down to the very 0s and 1s that it interprets in the end.

Those are the only two that are set in stone, so to speak. The computer languages we write in ultimately fall somewhere between these two points and will typically lean towards one end or another. As to whether they are high or low is really relative to which computer languages are available to us.

If you only have English, C, Assembler, and Machine Language, you might consider C to be a high-level computer language given the alternatives. However, if you were to add Java to the list, then you would probably start considering Java the high-level computer language, while C would be considered middle of the road.

At this point, we have so many computer languages available, it can be difficult to know where each stands. While it is always going to be a judgement call, you can get an idea by thinking about how close it falls to your natively spoken language, like English, vs. a machine language like binary.

share|improve this answer
1  
+1 for considering that it's all relative to other options available. –  Anna Lear Feb 2 '11 at 16:54
add comment

The "high" in "high level" is an indication of distance, distance from the machine, from the world of ideas.

High <=> Ideas : you express ideas without worrying about the machine

Low <=> Machine : you work directly with the machine to make sure it does what you really want in the end.

Most business ideasa are expressed in the ideas sphere while most very technician ideas are expressed in the machine's sphere.

So for me it's just a distance. Languages cover ranges in that distance : some are low level only (asm, maybe C but it's a bit higher), some are high level only (java, C#, Ruby, Python) and some tries to allow to acces everything (C++, D ...)

That's the same thing with tools, libraries, etc.

share|improve this answer
add comment

I see "high-levelness" of a programming language where it doesn't take you any knowledge about underlying hardware, its limitations and mapping of your code to the hardware to successfully write really large programs.

With C for instance you can't avoid getting right with pointers, memory management, algorithms to get productive. And while learning those you'll be getting machine-level knowledge automatically.

However with something like Java and C# you don't need any of those to be productive. Well it would do you good to know that stuff but if you don't you can get away for really long, project permitting of course. Perhaps for life.

share|improve this answer
3  
The "highness" of languages like Java and C# come from their libraries. If you looked at the code for database interfaces, they're either very technical or are heavily dependent upon other libraries which are very technical. –  Neil Feb 2 '11 at 15:28
    
@Neil: If a C programming environment were bundled/installed with a comprehensive set of libraries (also written in C) for strings, database connections, basic and advanced data structures, etc... (like Java/C#) would it then be a higher level language? –  FrustratedWithFormsDesigner Feb 2 '11 at 15:30
    
I think the term "high level" does refer to the fact that you don't have to know the details of the physical machine, but by that definition C is a high level language. The 'hardware' you're interacting with in C is really the C abstract machine. You don't need to know the details of how any of that is actually implemented on the hardware, just the details of the abstract machine, just like in java you only need to understand the JVM, or the CLR for C#. –  Cercerilla Feb 2 '11 at 15:33
    
If access to mysql required a single include to MySQL.h and a single call to mySQL.connect("dbserver"); and retrieval of records was simply a matter of creating a Criteria object and passing it to mySQL.select(criteriaObj); etc., then yes. However, all methods would be public. Though that doesn't make it low level, just extremely obnoxious. –  Neil Feb 2 '11 at 15:51
    
@CodeninjaTam: C has the register keyword which seems like a very "low-level" feature since you're telling the compiler you think something should be stored in a register. And GNU C has the asm keyword so you can have in-line assembly code. –  FrustratedWithFormsDesigner Feb 2 '11 at 15:57
add comment

It depends on context, the level you are programming on. For embedded systems programming C might be high level enough. On the other hand if you are programming user interfaces even Java might feel too low level.

"A programming language is low level when its programs require attention to the irrelevant." — Alan J. Perlis.

share|improve this answer
add comment

Technically, when assembly was made it was considered high-level. Before that, you had to program directly in machine code...1's and 0's. It's all relative as some have mentioned. Java and C# are examples of the highest level programming languages because they create code that targets a virtual machine. The code can then be run on any hardware to which the VM has been ported.

A lot of noise has been made about 4GLs (or fourth generation languages). The idea behind these languages are that they are designed for very specific purposes (e.g. querying data and creating reports). As such they have a much more limited syntax than the 3GLs but they abstract away the details of how things are done even more than 3GLs.

For reference assembly abstracts the concept of machine code. C and C++ abstract many of the concepts of assembly but compiles down to assembly (if you have the right compiler you can target any machine). C# and Java take it a step further. You only need one compiler because it targets the VM. The VM is implemented for a given OS and Architecture combo. (Despite this additional abstraction, they're still considered Third-Generation).

4GLs are declarative in nature. Rather than telling the machine how you want it to do something, you tell it what you want to do. An interpreter can be implemented in any language to read a 4GL package and execute the request. Technically by that definition, one could see HTML as a 4GL. The constructs of an HTML page (<Body>, <Table>, etc) are interpreted by the browser which is responsible for rendering the page. Of course HTML is often combined with javascript, providing a blend of 4GL and 3GL construct.

Other examples include XAML which can be interpreted in free standing form, or preprocessed as a resource in an application. These are a subset of 4GLs however. The big idea is to be able to express declaratively that (for instance) I want to display all the registered users in the system. Note that I don't say I want the records from the user table in the application. Just that I want to display the registered users.

In the past there have been major attempts to introduce 4GLs, but they have never been accepted by the industry. In many cases, they were ridiculed because they were being sold as "the last program you'll ever need" (implying that the need to hire developers would be a thing of the past).

In reality for a 4GL to be useful it needs to be highly specific in nature (E.G. SQL for querying a database) or it needs to be extensible by a developer. If you look at technologies such as Windows Workflow which allow me to dynamically compose a running application out of steps or activities using a designer (and have the details of those activities implemented in C#), it seems that we're getting closer to that idea.

share|improve this answer
add comment

High-level is used as a comparison but generally tends to define a subset of languages that abstract the programmer of some implementation details (like the parameter needed to execute a system_call to access a file, or the permission octet needed to read from an input, etc), greater the abstraction higher the level.

Imagine the guys programming using assembler and the ones programming in C, or a more recen example like Java vs C programmers. There is a tendence to go higher, but the real meaning is expressed in comparison with others.

share|improve this answer
add comment

I'm old, and a lumper: if it requires something more complicated than a one-to-one translation from source to machine code (or very nearly so), then it's a high-level language. In that respect, I consider languages like C to be every bit as high level as Python or Haskell.

There's definitely a hierarchy of HLLs, though, and C falls somewhere near the bottom in terms of expressive power and useful abstractions.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.