Scheme was created by Guy L. Steele and Gerald Jay Sussman in 1975 at the MIT Artificial Intelligence Laboratory.
Developed as a minimalist dialect of Lisp, it was designed to explore the actor model of computation and study lexical scoping rules.
Standardized across major revisions, notably R5RS (Revised^5 Report on the Algorithmic Language Scheme, widely regarded as the classic minimalist standard) and R7RS (offering modern modular library structures).
Scheme introduced two critical innovations to the Lisp family: lexical scoping (enabling modular closures) and a strict requirement for tail-call optimization (TCO).
Who:
Guy L. Steele and Gerald Jay Sussman (creators).
Why:
Developed to create a clean, simple, and mathematically elegant programming language with a minimal set of core primitives that can easily express complex computational patterns.
Introduction
Advantages
Minimalist Core — The entire standard language consists of only a few core concepts and primitives, making it exceptionally easy to learn and modify.
Hygienic Macro System — Unlike C-style preprocessors, Scheme’s syntax-rules macros prevent variable name conflicts (variable capture) automatically.
Tail-Call Optimization (TCO) — The standard guarantees that recursive tail calls run in constant stack space, allowing recursion to act as efficient loops.
First-Class Continuations — Using call/cc, programmers can save and restore the execution state of the program at any point, enabling custom thread pools and exception handlers.
Disadvantages
Readability (Nested Parentheses) — The heavy prefix notation and nesting of parentheses ((((x)))) can be visually difficult to parse.
Fragmented Implementations — Scheme has many different implementations (Racket, Chicken, Guile, Chez), each adding incompatible library systems and extensions.
Dynamic Typing Errors — Type mismatches are caught only during execution, requiring extensive test coverage.
Remember Points
Prefix Notation — Operations are written before their arguments: (+ 2 3) instead of 2 + 3.
Homoiconicity — Code is formatted in standard data structures (Lists), meaning code can be processed and generated directly as data.
; This is a single-line comment in Scheme; display prints output to console(display "Hello, World!")(newline) ; prints newline
Prefix notation is used: (operator arg1 arg2 ...).
Semicolon ; begins comments.
Variables and Data Types
; 1. Global Definitions (define)(define name "VR Rathod")(define age 25); 2. Mutating Variables (set!)(set! age 26) ; Updates age to 26; 3. Core Types:; Symbols (unique, immutable identifiers prefixed by quote)(define status 'success); Lists (linked lists of pairs)(define colors '(red green blue))
Local Bindings (let, let*, letrec)
Scope Declarations
In Scheme, local variables are bound within a let block structure:
; 1. let: binds variables in parallel (variables cannot reference each other)(let ((x 10) (y 20)) (+ x y)) ; returns 30; 2. let*: binds variables sequentially (y can reference x)(let* ((x 5) (y (* x 2))) (+ x y)) ; returns 15; 3. letrec: binds variables recursively (useful for local recursive functions)(letrec ((factorial (lambda (n) (if (<= n 1) 1 (* n (factorial (- n 1))))))) (factorial 5)) ; returns 120
Control Flow
Conditionals: if, cond
; 1. IF expression: (if condition then-expr else-expr)(if (>= age 18) (display "Adult") (display "Minor")); 2. COND (Switch-case equivalent)(cond ((< age 13) (display "Child")) ((< age 20) (display "Teenager")) (else (display "Adult")))
Loops via Recursion (Tail-Call Optimization)
Scheme does not have traditional for or while loop constructs. Iteration is performed using recursion:
; Declaring lambda: (lambda (params) body)(define add (lambda (a b) (+ a b))); Shorthand function definition:(define (subtract a b) (- a b)); Higher-Order Functions(define nums '(1 2 3 4)); map(define doubled (map (lambda (x) (* x 2)) nums)) ; '(2 4 6 8); filter(define evens (filter even? nums)) ; '(2 4)
Pairs & Lists
List Operations
Lists are constructed using nested Pairs (cons cells).
; cons: creates a pair cell -> (head . tail)(define p (cons 1 2)) ; (1 . 2); car: extracts first element of pair(car p) ; 1; cdr: extracts second element of pair (tail)(cdr p) ; 2; Lists are chains of pairs ending with empty list '()(define my-list (cons 10 (cons 20 '()))) ; '(10 20)(car my-list) ; 10(cdr my-list) ; '(20)
Hygienic Macros
compile-time translations
; define-syntax and syntax-rules create pattern-matching compiler macros(define-syntax my-unless (syntax-rules () ((_ condition body) (if (not condition) body)))); Usage:(my-unless (= age 0) (display "Age is not zero"))
First-Class Continuations
call-with-current-continuation (call/cc)
; call/cc captures the current execution stack pointer and passes it as a function argument(define exit-continuation #f)(define (search-list val lst) (call/cc (lambda (k) (set! exit-continuation k) ; k represents execution exit route (for-each (lambda (x) (if (= x val) (k #t))) ; exits immediately returning #t lst) #f)))