Welcome to the World of Programming Languages!
Hello! Today, we are going to explore the different ways humans talk to computers. Computers are incredibly fast, but they aren't very smart—they only understand "on" and "off" (1s and 0s). Programming languages are the tools we use to bridge the gap between our complex human ideas and the computer's simple binary brain. By the end of these notes, you’ll understand why we have different types of languages and how we translate our thoughts into something a machine can execute.
1. Classification: Low-Level vs. High-Level
In Computer Science, we classify languages based on how close they are to the computer's hardware versus how close they are to human language.
Low-Level Languages
These are "low" because they are very close to the hardware (the actual circuitry of the CPU). There are two main types:
1. Machine Code: This is the "pure" language of the computer. It consists entirely of binary (1s and 0s). It is extremely difficult for humans to read or write, but the computer can execute it instantly without any translation.
2. Assembly Language: This is a step up from machine code. Instead of binary, it uses short abbreviations called mnemonics (like ADD, SUB, or MOV). Each instruction in Assembly usually maps directly to one machine code instruction.
High-Level Languages
These are "high" because they are closer to human language. Examples include Python, Java, and C#. They use English-like keywords (like if, while, and print).
Imperative High-Level Languages: Most languages you use are "imperative." This means the code consists of a series of instructions that tell the computer exactly how to complete a task, step-by-step.
Analogy Time: Think of a High-Level Language as a recipe in a cookbook ("Bake the cake for 30 minutes"). Low-Level Language is like the tiny mechanical movements the oven's gears make to turn the timer and ignite the gas.
Quick Review: The Pros and Cons
• High-Level is easier to learn, faster to debug, and portable (it can run on different types of CPUs). However, it is usually slower because it needs translation.
• Low-Level gives you total control over the hardware and is very memory-efficient. However, it is very hard to write and is processor-specific (Assembly written for one CPU won't work on another).
Key Takeaway: High-level languages favor the programmer (ease of use), while low-level languages favor the machine (efficiency and control).
2. Translating the Code
Since computers only understand Machine Code, any code written in a high-level language or Assembly must be translated. Think of these like language translators at the UN.
The Three Types of Translators
1. Assembler: Translates Assembly Language into Machine Code.
2. Compiler: Translates the entire high-level source code into machine code all at once, creating an executable file (like an .exe). You only need to compile it once, and then the machine code can be run over and over again without the compiler.
3. Interpreter: Translates high-level code line-by-line. It reads a line, converts it to machine code, runs it, and then moves to the next line. If it hits an error, it stops right there.
Memory Aid: Think of a Compiler like a Full Translation of a book—you wait a while for the translation, but then you can read the whole thing anytime. Think of an Interpreter like a Live Translator—they translate as you speak, but if you stop speaking, the translation stops.
Did you know? Python is typically an interpreted language, which is why you can see errors happen halfway through running your program! Java uses a mix of both.
Key Takeaway: Compilers produce fast, independent files; Interpreters are great for testing code line-by-line but are slower to run.
3. Intermediate Logic: Bytecode
Sometimes, a compiler doesn't go all the way to Machine Code. Instead, it translates the source code into something called Intermediate Language or Bytecode.
Why use Bytecode?
The main reason is Portability. Different computers have different CPUs. If you compile directly to Machine Code for an Intel chip, it won't work on an ARM chip (like in a phone).
By translating to Bytecode first, the "Intermediate Language" can be sent to any device. That device then uses its own specific "Virtual Machine" to turn that Bytecode into its own Machine Code. This is how Java achieves its "Write Once, Run Anywhere" goal!
Quick Review: Common Mistake Alert!
Don't confuse Source Code with Object Code.
• Source Code: The code YOU write (e.g., Python or C#).
• Object Code: The translated Machine Code that the computer actually runs.
Key Takeaway: Bytecode is a middle-step that makes software easier to run on many different types of hardware.
Final Summary Checklist
• Do you know that Machine Code is binary and Assembly uses mnemonics?
• Can you explain why High-Level languages are easier for humans?
• Can you describe the difference between a Compiler (whole thing) and an Interpreter (line-by-line)?
• Do you understand that Bytecode allows code to be portable across different devices?
Don't worry if this seems like a lot to take in! Just remember: it's all about translation. We want to work in English-like languages, and the computer wants 1s and 0s. Everything in this chapter is just a tool to make that conversation happen.