Ryan Klein Dev

How Does a Computer Work and What Is a Programming Language?

November 05, 2021

Developers deliver instructions to a computer using programming languages. The list of programming languages are endless. Some are popular and commonly used like Python and JavaScript. Others are highly specialized and tailored to a single job. There’s even a programming language called Chef that’s meant to make code look like a recipe. These languages are part of a category called Esoteric Programming Languages. The rest of this post will dive deeper into what programming languages are along with a list of common programming languages and their purpose.

How Do Computers Work?

If you understand the basics of how a computer works, you’ll gain an appreciation for what programming languages are and why they are so important.

The Central Processing Unit(CPU) of a computer is made up of transistors. Transistors are tiny switches that can either allow electrical current through them or block electrical current. When current flows through, a transistor is on. When current is blocked, a transistor is off. This is where the 1s and 0s come from. 1 means the transistor is on and allowing current. 0 means the transistor is off and blocking current.

When you have an 8-bit CPU, that means you have 8 bits available for defining commands or storing data. 8 1s and 0s. For an 8-bit CPU, a command to add two numbers might look like 01000110. Here’s how it breaks down.

Operation Source Register 1 Source Register 2 Destination Register
01 00 01 10

The operation tells the computer what to do. 01 tells the computer this is an add operation. 00 could mean subtract, 10 multiply, and 11 divide.

The remaining bits point to registers. A register is where the CPU holds values. This command is telling the CPU to add together the values in Source Register 1 and Source Register 2 then put the result in the Destination Register. These registers are just more transistors represented by 1s and 0s. Each one can hold 8 bits. Here’s a further break down.

Register Address Binary Value Decimal Value
Source Register 1 00 00000001 1
Source Register 2 01 00000010 2

So, by taking the value in Register 1 and adding it to Register 2 you get 3. 3 is put into the Destination Register with the binary value 00000011.

This was a very basic example to demonstrate computers conceptually. Today’s CPUs have 64-bit architectures with commands that are much more complex.

Programming a Computer in Binary

Programming in binary would be a nightmare! You’d need a way to control the current through each transistor. You could do this with light switches. To execute the command above, first you’d have to toggle the light switches to set up the values in each register. Then, toggle all the light switches to set up the command. When all your switches are set, you’d press a button to tell the computer to run the program.

Before programming languages, scientist would use punch cards to program computers. Punch cards are laid out in a grid with each space representing a transistor or bit. Turning a bit on would be represented by a punched hole.

Flipping switches and punching cards is extremely tedious and error prone. Just incorrectly flipping one switch can break an entire program. You could easily add when you meant to subtract.

Assembler

Assembler is considered to be one of the first programming languages. It’s been in use since the 1950s. It’s sometimes referred to as machine language. Assembler languages communicate directly with the CPU. The add command in assembler might look something like the following.

PUT 00000001 $r1
PUT 00000010 $r2
ADD 00000010 $r1 $r2 $r3

The first two commands put values into registers. Register 1 could have the value of 1 in binary and register 2 would have the value of 2 in binary. The third command adds the two values together and puts them into register 3.

A little better but still a lot of binary. Yuck.

The Operating System and Low Level Languages

Parts of an operating system, like Windows or macOS, are often written in Assembler. The operating system will manage the hardware and work directly with the CPU. This means a developer can give commands to the operating system rather than directly to the CPU. This is called an abstraction. Operating systems abstract the CPU away from the developer. Operating systems will often work out of the box with a language like C++ which was introduced in 1985. Here’s how to add together two numbers in C++.

int x = 5;
int y = 6;
int sum = x + y;

That looks much better. No more binary. No more registers. Under the hood, the operating system will convert the C++ code into Assembler in a process known as compiling. The operating system will then run the compiled Assembler code.

That’s all a programming language is. Commands that are easy for humans to write, compiled down into 1s and 0s by an operating system or some other software on the computer.

Since languages like C++ work directly with the operating system, they are extremely fast and powerful. But, with great power comes great responsibility. While less error prone than Assembler, C++ programs are still easy to break.

For example, in C++, you have to manage memory. If you wanted to store an array of numbers, you have to tell C++ you want enough memory to hold those numbers. When you’re done with the array, you need to tell C++ you’re done with the associated memory.

Higher Level Languages

As developers noticed some of the pitfalls of C++, other languages started to pop up.

Java

Java is one of the most commonly used programming languages in the world. It was introduced in 1995. Many programs are written in Java and it’s heavily used in the enterprise world. It’s often used to build server side applications.

Java can be easier to write than C++ and takes care of memory management for you. However, most operating systems don’t know how to turn Java code into Assembler. To run Java code, you need to have something called a Java Virtual Machine(JVM). The JVM takes your Java code and translates it into a language the operating system can understand. Then, the operating system can run the program.

This is a further abstraction. Java is a programming language. The JVM is just a program that runs on your computer that can interpret Java for the operating system.

Python

Python and its supporting libraries are very good at data management. It was released in 1991. Given the rise in Big Data and Machine Learning, Python has become very popular. It’s very easy to get up and running. You simply install Python on your computer and start writing programs. Just like Java, Python interprets your commands and converts them into a language the operating system can understand.

Python has many uses including server side web applications, data processing, and simple scripting.

JavaScript

Most modern browsers run JavaScript, which was first available in 1995. With the rise of the internet and the demands of users on the internet, browsers and JavaScript have become very popular. Browsers and JavaScript both continue to add features and benefits increasing the capabilities of developers using these technologies. Again we have another abstraction. The browser interprets JavaScript then turns it into something the computer can understand. A browser is just like the JVM or the Python interpreter.

Developers wanted a way to run JavaScript without the browser. This is what Node.js enables. Instead of running in a browser, JavaScript programs can be run by Node.

Modern Programming Languages

The higher level programming languages mentioned are a bit dated and have their own issues. For example, in Java, it’s easy to access a variable that doesn’t have an underlying value. That’s a bug that is often discovered by users of an application. In newer languages, if you try to access a potentially null value, you’ll be prevented from running the program until you address the issue.

Older programming languages are getting better and better, but it can be difficult to add features to an existing programming languages. Sometimes it’s easier to just start fresh. Here are some modern programming languages that are gaining popularity and address some of the issues of languages that came before them.

Swift

Swift is a programming language created by Apple most commonly used to build iOS and macOS applications. It was released in 2014. Apple has open sourced Swift so it doesn’t have to be used for building iOS or macOS applications. You can run it on any machine just like you’d run Python or Java.

Kotlin

Kotlin was created by a company called JetBrains in 2011. In the Java section, it was mentioned that Java runs on software called the JVM. To run on a JVM, Java is compiled down in to Bytecode. If a language can be compiled down to Bytecode then it can run on a JVM. Recently, Google made it possible to develop applications in Kotlin for Android. This is possible since Android devices run their apps using a JVM. With all the Android developers in the world, Kotlin has gained a ton of popularity.

Kotlin’s objective is to address some of the main problems developers have with Java.

Go

The motivation for the Go programming language was similar to that of Kotlin. It was released in 2009 by Google. It’s meant to be similar to writing low level languages like C++ but with some of the safety measures in place like other modern languages. Between heavy usage at Google and a wave of utilization in open source projects, Go is climbing in popularity.

Rust

Rust was announced in 2010 and has many similarities to the languages mentioned above. It is rapidly growing in popularity. Computers have a lot of work to do and are expected to be fast. To get all that work done in a timely manner, they leverage concurrency. Rust is well suited for programs with concurrency while maintaining the familiar feel of older programming languages.

Building on the Shoulders of Giants

As you may be able to tell from this post, each technology and language has benefited from the one before it. Without transistors, we don’t have computers or Assembler. Without Assembler, we don’t have the operating system and C++. Without C++ we don’t have Java and we wouldn’t be where we are today. These languages and technologies will continue to grow. One of the amazing things about programming is the community participation. These languages aren’t always built in isolation by large corporations. They’re often kept afloat and advanced by volunteers. With these continued efforts, it’s exciting to think about where computers and programming will be in the next 10 years!


Hi, I'm Ryan. This is my development website. I've been coding for over 15 years. I love sharing what I've learned with those interested in development and technology. Follow me on twitter!