Week 01 · Research Update

The History and Purpose of Programming Languages

1. Why did we move from punch cards to programming languages? What does that tell you about the purpose of programming languages?

Early machines had no concept of English, math notation, or anything resembling human language. At the hardware level, a computer only understands strings of binary electrical states, so the first programmers had to give instructions directly through punched cards; a hole in a specific position on the card corresponded to a specific binary digit. A single IBM card packed 80 columns and 12 rows and a character was encoded by a particular pattern of holes in one column; a card reader worked by shining light through the card and recording where the light passed through. This was workable, but slow and sometimes unaccurate; one misplaced hole could break a whole program.

The move away from cards happened gradually. Assembly language was the first real step: it let programmers substitute symbolic mnemonics for raw binary, functioning as a thin translation layer between what a person meant and what the machine actually executed. The bigger leap came with Grace Hopper's A-0 compiler in 1952 and then Fortran in 1957.

Taken together, this history makes the purpose of programming languages pretty clear. They exist to shrink the distance between what a person is trying to say and what the machine ends up doing, cutting down on the error rate along the way.

2. There are hundreds of different programming languages out there. Why do you think we need so many?

Roughly 9,000 programming languages have been created over time, though only 50–100 are in wide active use today, and the reason so many exist is that no single language can be optimal across every type of project: problem domain, execution speed and programming paradigm all pull in different directions.

Some of this is pure domain specificity. General-purpose languages like C/C++, Rust, Python, and Java can express almost any computation, but plenty of languages are deliberately narrow (SQL exists purely to query databases, for example) because a well-designed domain-specific language lets a problem be stated in terms that are natural to that domain, sometimes even for people who aren't professional programmers.

The rest comes down to trade-offs that genuinely can't be maximized all at once. Comparative studies of languages like C++, Java, C and Fortran 77 consistently surface the same tension: execution speed versus ease of use, simplicity versus raw expressive power.

New languages keep appearing because real organizational needs keep appearing too: Google built Go specifically for fast, networked cloud infrastructure, and Apple built Swift specifically to be the primary language for iPhone and Mac development. Both are recent languages designed to fit a niche that older general-purpose languages didn't serve as well.

3. What are some drawbacks of a programming language you use? How would you like it to be different? Think of specific examples.

I use Python. The drawback I run into most is that types are checked at runtime instead of at compile time. That flexibility is convenient while writing code, but it means type mistakes don't get caught until the program actually runs, which makes bugs harder to track down.

A concrete example:

def calculate_total(price, quantity):
    return price * quantity

Nothing here prevents calculate_total("10", 3) from silently returning "101010" (string repetition) instead of raising an error. The bug doesn't surface at the point of the mistake, wherever that bad value eventually gets used, which makes it much harder to trace back.

4. If you were going to create a new programming language, how would you start? What do you need to define?

First, decide who the language is for and why it exists. This is the most important choice, because everything else depends on it. A language for teaching beginners looks very different from a language for building fast games or managing databases.

Next, you need to define the grammar (the exact rules for how code can be written). This is about making the language easy to read and easy to maintain later. Part of this step means removing any confusion about how code should be read. For example, in the expression 4 + 4 * 3, should you calculate 4 + 4 first, then multiply by 3? Or multiply 4 * 3 first, then add 4? The expression alone doesn't tell you, the grammar rules have to spell it out clearly.

Then you decide two more things: how the language handles data types and memory, and how the code actually runs. Does it get translated into bytecode for a virtual machine, compiled directly into machine code, or interpreted line-by-line?

Finally, you write down the exact meaning of every part of the language, so there's no ambiguity.

So the order looks like this:

  1. Define the purpose and audience
  2. Write the formal grammar rules
  3. Decide the type system and memory model
  4. Choose compiled vs. interpreted, and pick a target platform
  5. Document exact semantics

References

  1. IEEE Spectrum: "From Punch Cards to Python"
  2. QuantumZeitgeist: "Punch Cards to Python" history overview
  3. ScienceABC: overview of programming language proliferation and domain-specific design
  4. arXiv: RuLa paper on domain-specific language design
  5. Medium: "Creating Your Own Programming Language"
  6. Towards Data Science: grammar ambiguity in language design
  7. Andrew Odendaal: semantics, semantic analysis, and target platform decisions in language creation

Further reading

  1. Real Python, "What Is the Python Global Interpreter Lock (GIL)?"
  2. freeCodeCamp, "Why Are There So Many Programming Languages?"
  3. Computerphile, "Creating Your Own Programming Language"
  4. "The Problem with Python's GIL Explained" — shorter, beginner-friendly explainer