Recently, i had to understand the design of a small program written in a language i had no idea about (ABAP, if you must know). I could figure it out without too much difficulty.

I realize that mastering a new language is a completely different ball game, but purely understanding the intent of code (specifically production standard code, which is not necessarily complex) in any language is straight forward, if you already know a couple of languages (preferably one procedural/OO and one functional).

Is this generally true? Are all programming languages made up of similar constructs like loops, conditional statements and message passing between functions? Are there non-esoteric languages that a typical Java/Ruby/Haskell programmer would not be able to make sense of? Do all languages have a common origin?

  • 5
    I'll direct you to Beating the Averages by Paul Graham. You may or may not want to read the whole thing, but for the relevant part search for the heading "The Blub Paradox". Mr. Graham can't be bothered to put anchors in his wall of text, so I can't directly link to it.
    – kenm
    Commented Jul 28, 2009 at 2:59
  • 5
    Languages don't have common origin. But all languages try to solve some problem. I think it is somewhat analogous to spoken language. The purpose is to express oneself. I can't say it is straight forward to understand languages based on the knowledge of 1 procedure/OO/functional. I haven't done this but if I were to ask this question, I would look at perl or lisp with lots of brackets & I wouldn't be able to say that knowing 1 language of all type is sufficient. Commented Jul 28, 2009 at 3:07
  • 1
    In that case: Lambda calculus. Perhaps not a 'real' language, but it is the mother of all programming languages in a sense. I once had to implement a functional language such that it compiled into lambda expressions (which were then directly interpreted). The results were (to me, at least) unreadable despite preserving all the relevant identifiers. Especially recursive functions using the Y-combinator. The only practical way to figure out what some of the sample expressions did was to hand-evaluate them. Simple things like fibonnaci and merge sort were unreadable.
    – kenm
    Commented Jul 28, 2009 at 3:25
  • 2
    If you know functional languages, you should know that loops aren't possible in every language.
    – jalf
    Commented Jul 28, 2009 at 4:49
  • Piet is pretty different. :)
    – Jack Leow
    Commented Aug 13, 2009 at 3:43

7 Answers 7


The basics of most procedural languages are pretty much the same.

They offer:

  • Scalar data types: usually boolean, integers, floats and characters
  • Compound data types: arrays (strings are special case) and structures
  • Basic code constructs: arithmetic over scalars, array/structure access, assignments
  • Simple control structures: if-then, if-then-else, while, for loops
  • Packages of code blocks: functions, procedures with parameters
  • Scopes: areas in which identifiers have specific meanings

If you understand this, you have a good grasp of 90% of the languages on the planet. What makes these languages slightly more difficult to understand is the incredible variety of odd syntax that people use to say the same basic things. Some use terse notation involving odd punctuation (APL being an extreme). Some use lots of keywords (COBOL being an excellent representative). That doesn't matter much. What does matter is if the language is complete enough by itself to do complex tasks without causing you tear your hair out. (Try coding some serious string hacking in Window DOS shell script: it is Turing capable but really bad at everything).

More interesting procedural languages offer

  • Nested or lexical scopes, namespaces
  • Pointers allowing one entity to refer to another, with dynamic storage allocation
  • Packaging of related code: packages, objects with methods, traits
  • More sophisticated control: recursion, continuations, closures
  • Specialized operators: string and array operations, math functions

While not technically a property of the langauge, but a property of the ecosystem in which such languages live, are the libraries that are easily accessible or provided with the language as part of the development tool. Having a wide range of library facilities simplifies/speeds writing applications simply because one doesn't have to reinvent what the libraries do. While Java and C# are widely thought to be good languages in and of themselves, what makes them truly useful are the huge libraries that come with them, and easily obtainable extension libraries.

The languages which are harder to understand are the non-procedural ones:

  • Purely functional languages, with no assignments or side effects
  • Logic languages, such as Prolog, in which symbolic computation and unification occur
  • Pattern matching languages, in which you specify shapes that are matched to the problem, and often actions are triggered by a match
  • Constraint languages, which let you specify relations and automatically solve equations
  • Hardware description languages, in which everything executes in parallel
  • Domain-specific languages, such as SQL, Colored Petri Nets, etc.

There are two major representational styles for languages:

  • Text based, in which identifiers name entities and information flows are encoded implicitly in formulas that uses the identifiers to name the entities (Java, APL, ...)
  • Graphical, in which entities are drawn as nodes, and relations between entities are drawn as explicit arcs between those nodes (UML, Simulink, LabView)

The graphical languages often allow textual sublanguages as annotations in nodes and on arcs. Odder graphical languages recursively allow graphs (with text :) in nodes and on arcs. Really odd graphical languages allow annotation graphs to point to graphs being annotated.

Most of these languages are based on a very small number of models of computation:

  • The lambda calculus (basis for Lisp and all functional languages)
  • Post systems (or string/tree/graph rewriting techniques)
  • Turing machines (state modification and selection of new memory cells)

Given the focus by most of industry on procedural languages and complex control structures, you are well served if you learn one of the more interesting languages in this category well, especially if it includes some type of object-orientation.

I highly recommend learning Scheme, in particular from a really wonderful book: Structure and Interpretation of Computer Programs. This describes all these basic concepts. If you know this stuff, other languages will seem pretty straightforward except for goofy syntax.

  • 3
    Great Answer! As a follow-up (is there a way to ask a follow-up question in SO?), is there one language i could master and claim to understand all concepts in programming software? Would it be Lisp (or a dialect such as Scheme)?
    – Anirudh
    Commented Jul 28, 2009 at 4:16
  • @Anirudh: There's no formal follow-up mechanism, but you could open a new question. If it contains a rationale and a link to this question, it might not even be closed. ;) To answer your follow-up, I wholeheartedly believe there isn't just one language, since the paradigms are too different.
    – John Y
    Commented Jul 28, 2009 at 4:23
  • @Anirudh: Agreed with John Y, there isn't just one. But if you are relatively new to the field, you should spend considerable energy to master the procedural paradigm (I consider OO just a specialization). It wouldn't hurt to look other paradigms (logic, constraint, dataflow) to get a sense of how they work, but for most day to day industrial work, procedural languages are pretty much king.
    – Ira Baxter
    Commented Jul 28, 2009 at 4:42
  • 1
    Just like with natural languages, "harder to understand" is subjective and dependent on the first language you learn. Commented Sep 10, 2011 at 16:31
  • 1
    @NullUserException: This suggests you should pick your first language carefully, to maximize ease of understanding others. That's the point of Scheme, and in particular the SICP book.
    – Ira Baxter
    Commented Oct 8, 2011 at 16:45

Hardware description languages are programming languages, but they are conceptually very different. Try VHDL or Verilog on for size. They are common for programming FPGAs. (Ok, so they're not processors, but they are general purpose computing devices. And such should be considered valid hardware for computer science topics.) You have to explicitely make things occur serially. It's a completely different model. You have think of things occuring in parallel as the rule not the exception. For loops in verilog expand into parallel hardware. So the "expected" behavior might not be what you expect.

  • That's a good point. I will look look up Verilog/VHDL.
    – Anirudh
    Commented Jul 28, 2009 at 3:14
  • I've always thought that conventional programming languages were just really crummy ways to code programs that were naturally parallel, such as VHDL. When you start out as a hardware designer, this bit about everything occurring in a serial fashion seems incredibly clumsy. (We're teaching the wrong programming langauges to people as their first langauge: it should be Verilog!).
    – Ira Baxter
    Commented Oct 6, 2011 at 15:58
  • Pure Functional languages also seem to default to parallel computation, and Erlang/Elixir/Smalltalk(?) seemed to be based on active objects.
    – aoeu256
    Commented Apr 25, 2021 at 0:50

Depends on what you mean by "basically." All languages of any flexibility are Turing-complete. In that sense: yes, they are all basically the same.

On a low level, they all perform similar sequences of operations and all Windows, Linux, and (recent) OS X stuff all runs on Intel-compatible processors using the same instruction sets. In that way they are also basically the same.

I realize that you sorta defined "basically" in your question, but to really answer it, that definition will have to be much more refined. In many ways they are all alike. In many ways they are distinct. It's all too easy to say "it depends." If you take either extreme, the question will likely not answer what you intend it to so where that line is drawn is crucial to answering your question as you intend it.


I would say that a language encodes meaning. If the meaning has any sense in some context then all languages that could express the meaning could be said to be equivalent limited by the meaning and the context.

If you limit that context to a standard Von Neumann machine then the computational meanings of changing memory and computing in a cpu could be said to be the origin - and possibly the only meaning that all the languages have in common. All other things are abstraction built on these.

  • 2
    John von Neumann. And it's NOT pronounced like "newman", more like "noyman".
    – John Y
    Commented Jul 28, 2009 at 4:10
  • Thanks for the correction - I do pronounce is like you said though. Commented Jul 28, 2009 at 7:54
  • When someone suggests a correction, you can just edit your post to reflect it. Commented Aug 13, 2009 at 3:54

Programming languages are also tools for thinking. With another thinking perspective, some problems disappear or are transformed to different, more manageable kind (for example, many C++ style design patterns just disappear when you are thinking in Lisp (see for example this Peter Norvik's presentation), and Erlang frees you from thinking of some low level concurrency or distributed computing constructs and lets you just concentrate on the application logic).

Note, however, that sometimes the "new" paradigms can be partially be applied to "older" programming languages which explains why we for example have books teaching functional programming for Java programmers. But natively supporting and integrating a more powerful paradigm in the language level enables more natural application of the paradigm (and consequentially makes it impossible to understand programs in a language supporting unfamiliar paradigm, as hinted by other answers - @Ira Baxter listing non-procedural languages and @kwatford referring to Paul Graham).


At the lowest level, every programming language is the "same," but that doesn't meant that they're the same at the level where you actually interact. They abstract problems for you; that doesn't mean that they abstract the same problems or that they abstract each problem the same way.


Mature languages generally have a few goals, and they make tradeoffs where they sacrifice one thing for another. A general-purpose language can be used for anything, but no language can ever excel in every area. A few examples:

C attempts to be an ideal systems programming language. To this end it sacrifices readability and safety for low-level control and speed.

Python aims to be an ideal scripting language. To this end it sacrifices speed and verifiability for productivity and portability.

Haskell attempts to be a safe, mathematically pure language. To this end it sacrifices learnability and convention for verifiability and reliability.

These sacrifices and benefits make a huge difference in the language. Yes, most programming languages can be used for anything that can be done by a computer, but none of those same languages should be used for everything. All of the languages above are ones I would choose for certain tasks but not for others. If I were programming an operating system I would choose C. If I were writing a backend for a website, I would use Python. And if I were writing a financial system I would use Haskell.

In the end, your choice as a programmer is what the right tool for the job is.