What is Coding?
Before we write a single line of Go, let's zoom out. Coding (also called programming or software development) is the act of writing precise instructions that a computer can carry out. Those instructions add up to everything from a tiny shell script to the app store in your pocket, from a spreadsheet to a jet's autopilot.
This chapter answers four questions that will make the rest of the course make sense: what is code, how does a computer actually run it, what kinds of languages exist, and where does Go sit among them.
Learning objectives
- Explain, in one sentence, what code is.
- Describe the path source code takes from your editor to the CPU.
- Distinguish compiled, interpreted, and bytecode/JIT languages, and know which bucket Go is in.
- Recognize the major language families (systems, scripting, functional, markup, query).
- Articulate why Go was a deliberate choice for this course.
What is coding?
At its core, a program is a recipe: a numbered list of steps detailed enough that a machine with no common sense can follow it and get the same result every time. You write the recipe in a programming language, a notation humans can read that can be translated into something the computer understands.
A trivial example in Go looks like this:
package main
import "fmt"
func main() {
name := "world"
fmt.Println("Hello,", name)
}
That's six lines of precise instruction: declare a program, bring in a
tool for printing, define an entry point, store the word
"world" in a labeled box called name, and print
a greeting. We'll unpack every part of this program in Chapter 4.
For now, just notice that the code describes behavior using
English-looking words and punctuation, not 1s and 0s.
How computers actually run code
Deep down, a CPU only understands one thing: binary instructions. Every program you've ever run (your browser, your game, this very web page's JavaScript) ends its life as a stream of 1s and 0s shuffling through silicon.
From source to silicon
A sequence of translations gets us from human-readable code to CPU-executable electricity:
Why binary?
Transistors (the building blocks of a CPU) are essentially switches:
they're either on or off. We call
those states 1 and 0. A modern CPU contains
billions of them. By combining them into patterns, the hardware
can represent numbers, characters, colors, and (crucially) the
operations it should perform.
Here's a whirlwind translation of our Hello, world! in three
layers, from the most human to the least:
// Level 1: Go source (what you read and write)
fmt.Println("Hello,", "world")
# Level 2: x86-64 assembly (roughly, a human-readable sketch of machine code)
MOV RDI, addr_of_string
CALL fmt.Println
# Level 3: Raw machine code (what the CPU actually decodes)
48 8D 3D 00 00 00 00
E8 00 00 00 00
You will never write level 3 by hand (and level 2 only in very niche situations). That's the whole point of a high-level language like Go: it keeps you in level 1 while handling levels 2 and 3 automatically.
go tool objdump -s main.main ./hello
to see the actual machine instructions Go generated from your code.
Don't worry about this now, but know that Go is never a black box.
Compiled vs interpreted
Languages differ in when the translation from source code to machine code happens. The three broad models are:
What each model trades off
| Model | Translation | Runtime speed | Portability | Examples |
|---|---|---|---|---|
| Compiled | Once, ahead of time | Fastest | One binary per OS/CPU | Go, C, C++, Rust |
| Interpreted | Every run, line by line | Slowest (often) | Runs anywhere the interpreter does | Python, Ruby, Bash |
| Bytecode + JIT | Ahead of time to bytecode, JIT at runtime | Close to compiled, after warm-up | Run anywhere the VM runs | Java, C#, Kotlin, modern JS |
Go is firmly in the compiled camp. When you run
go build, Go produces a single, self-contained binary file
that the CPU runs directly. No virtual machine, no interpreter, no
"node_modules", no JVM. This is a big reason Go programs start so
quickly and ship so easily (Chapter 4 will show this in action).
.pyc files) before interpreting. JavaScript
engines like V8 use aggressive JIT compilation. Even Go has a
runtime for goroutine scheduling and garbage collection. Don't
let purists fight over precise definitions. The table above captures
the practical differences.
Types of programming languages
Besides when they translate (compiled vs interpreted), languages differ in what they're designed for. You'll hear people group them by family:
- Systems / general-purpose: build pretty much anything; performance-sensitive code, infrastructure, CLIs. Examples: Go, C, C++, Rust, Java.
- Scripting / dynamic: quick automation, glue code, prototypes, data analysis. Examples: Python, Ruby, Bash, Lua.
- Functional: emphasize pure functions and immutability. Examples: Haskell, Elixir, OCaml, Clojure.
- Markup: describe structure rather than behavior. Not really programming languages, but you'll read and write them constantly. Examples: HTML, XML, Markdown.
- Query: ask questions of data stores. Examples: SQL, GraphQL, SPARQL.
- Domain-specific: hyper-specialized. Examples: Dockerfile, Terraform HCL, regex, CSS.
Many languages fit in more than one box. Go, for instance, is general-purpose but especially loved for backend services, CLIs, and networked infrastructure.
Where Go fits
If you squint at the families above, you can see why someone would pick one over another for a given job. Where does Go sit?
- Speed of a compiled language: Go compiles to a static binary that runs as fast as C or C++ for most day-to-day code.
- Simplicity of a scripting language: the syntax is intentionally small. You can read a Go program you've never seen and roughly understand it. This is by design.
- Concurrency built in:
goand channels are language keywords. No extra libraries needed. (Chapters 24–26.) - Ergonomic tooling: formatter, linter, test runner, benchmark runner, and doc generator all ship with the compiler.
- A single deployable file: the classic Go pitch. Build once, copy the binary, run anywhere.
That's why Go powers so much modern infrastructure: Docker, Kubernetes, Terraform, Prometheus, etcd, CockroachDB, Caddy, Hugo, and so on. When you need a fast, reliable backend service or command-line tool, Go is a strong default. You'll meet each of these strengths firsthand throughout this course.
Why learn to code?
A quick aside worth reading if you're on the fence:
- Problem-solving muscle. Coding teaches you to break fuzzy problems into tiny, precise steps. This skill transfers to basically everything else.
- Leverage. A short script can do in seconds what would take a human hours, every week, forever.
- Career optionality. Software touches every industry; coding skills expand what jobs and roles are available to you.
- Creation, not just consumption. Knowing how software works changes you from a user into a maker. You can build the tool you wished existed.
Check your understanding
Practice exercises
Classify the language
For each of the following languages, write down whether you think it's compiled, interpreted, or bytecode + JIT. If unsure, guess, then look it up.
- Go
- Python
- Rust
- JavaScript (in a modern browser like V8)
- Bash
- Java
No code to write. This is a thinking exercise.
Show one possible answer
- Go: compiled. Produces a static binary via
go build. - Python: mostly interpreted (it compiles to
.pycbytecode behind the scenes, then interprets that). - Rust: compiled. LLVM-backed, produces native binaries.
- JavaScript: bytecode + JIT in modern engines like V8. "Interpreted" is the textbook answer but practically inaccurate today.
- Bash: interpreted. The
bashprogram reads and runs your script line by line. - Java: bytecode + JIT. Compiled to
.classfiles, run by the JVM which JITs hot code to native.
Read (not write!) your first Go program
Below is a slightly bigger Go snippet than the one at the top of this chapter. You don't know Go yet, but you know English. Read it slowly and try to predict, in plain words, what it will print when you click Open Go Playground and run it there.
package main
import "fmt"
func main() {
languages := []string{"Go", "Python", "Rust", "JavaScript"}
fmt.Println("Languages I know about:")
for i, lang := range languages {
fmt.Printf(" %d. %s\n", i+1, lang)
}
fmt.Printf("That's %d languages total.\n", len(languages))
}
Then click Open Go Playground, run the snippet there, and compare the output to your prediction. Did you get it right? Anything surprising?
Show expected output & notes
Languages I know about:
1. Go
2. Python
3. Rust
4. JavaScript
That's 4 languages total.
Things to notice, even without "knowing" Go yet:
[]string{"Go", "Python", ...}: a list of text items. Go calls these slices (Chapter 13).for i, lang := range languages: loop over the list, giving each item an indexiand a valuelang.%dis a placeholder for a number,%sfor a string, same idea asprintfin other languages.len(...): the built-in length function.
We'll meet every one of these in future chapters. Today, the goal is just to see that you can already mostly read Go.
Further reading
- go.dev: the official home of Go.
- Compiled vs interpreted languages (Wikipedia): deeper dive into the spectrum.
- Machine code (Wikipedia): what the CPU really speaks.
- Russ Cox, A primer on implementing languages: an accessible compiler/interpreter essay from one of Go's core contributors.
Felt solid? Lock it in.