Hello World in Scheme
Your first Scheme program - the classic Hello World example with Docker setup
Every programming journey starts with Hello World. Let’s write our first Scheme program and experience one of the most elegant and influential programming languages ever created.
The Code
Create a file named hello.scm:
| |
Understanding the Code
Let’s break down this simple but foundational program:
(display "Hello, World!")- Outputs the string to standard output. Like all Lisp dialects, Scheme uses S-expressions where the function comes first, followed by arguments.(newline)- Outputs a newline character. Scheme’s I/O primitives are minimal and composable.
Why Two Lines?
Unlike many languages where print includes a newline, Scheme’s display is more primitive - it just outputs the value. This is intentional: Scheme provides minimal building blocks that you compose into larger solutions.
You can combine them into one expression:
| |
The begin form sequences multiple expressions and returns the value of the last one.
Running with Docker
The easiest way to run this without installing Scheme locally:
| |
Running Locally
If you have GNU Guile installed:
| |
For Chicken Scheme:
| |
For Chez Scheme:
| |
Expected Output
Hello, World!
Understanding S-Expressions
Scheme uses prefix notation with parentheses, called S-expressions:
| |
This uniform syntax is what makes Lisp’s macro system possible - code and data share the same structure.
Alternative Approaches
Using format (GNU Guile)
GNU Guile provides a format function similar to Common Lisp:
| |
#t- Output to standard output (liketin Common Lisp)~%- Newline directive
Defining a Main Procedure
For a more structured program:
| |
define- Creates a binding (variable or procedure)(main)- Empty parameter list means no arguments- The procedure body is implicitly a
beginblock
Using write vs display
Scheme has multiple output functions:
| |
display- Human-readable output (no quotes on strings)write- Machine-readable output (includes quotes, escapes)
Key Concepts
- S-Expressions - Code is written as nested lists:
(function arg1 arg2) - Prefix Notation - The operator/function always comes first
- Everything is an Expression - Every construct returns a value
- Minimal Core - Few primitives, build everything from them
- Immutability Preferred - Though mutation is possible
Scheme Booleans
In Scheme:
#t- True#f- False
Unlike Common Lisp where NIL is false, only #f is false in Scheme. Even '() (empty list) is true!
| |
The REPL Experience
Scheme shines in the REPL (Read-Eval-Print Loop):
$ guile
GNU Guile 3.0.9
scheme@(guile-user)> (display "Hello, World!")
Hello, World!
scheme@(guile-user)> (+ 1 2 3)
$1 = 6
scheme@(guile-user)> (define (greet name) (display name) (newline))
scheme@(guile-user)> (greet "Schemer")
Schemer
Interactive development is central to the Scheme experience.
Scheme vs Other Languages
Python:
| |
JavaScript:
| |
Common Lisp:
| |
Scheme:
| |
Notice how Scheme is more primitive than Common Lisp’s format but follows the same S-expression syntax.
Why display and newline?
Scheme’s philosophy is to provide minimal, orthogonal primitives:
display- Output a datumnewline- Output a newlinewrite- Output a datum in machine-readable form
You combine these to achieve what print does in other languages. This composability is central to Scheme’s design philosophy.
GNU Guile
Our Docker image uses GNU Guile, which is:
- Full R7RS Support - Modern Scheme standard
- Fast - JIT compilation in recent versions
- Extensible - The official GNU extension language
- Practical - Rich library ecosystem
- Well-documented - Excellent manual and tutorials
Other popular implementations include Chez Scheme (fastest), Chicken (practical), and Racket (educational).
Historical Note
When Sussman and Steele created Scheme in 1975, they were studying the Actor model. Their insight that actors and closures are equivalent led to Scheme’s emphasis on lambda expressions and first-class procedures. This influenced everything from JavaScript to modern functional programming.
Next Steps
Continue exploring Scheme’s elegant features:
- Variables and data types (numbers, symbols, pairs, lists)
- Lambda expressions and closures
- Recursion and tail-call optimization
- Lists and list processing (car, cdr, cons)
- Higher-order functions (map, filter, fold)
- Macros and metaprogramming
Scheme rewards those who appreciate elegance and simplicity. Its influence on modern programming is profound - understanding Scheme helps you understand why languages are designed the way they are.
Welcome to the world of Scheme!
Running Today
All examples can be run using Docker:
docker pull weinholt/guile:latest