|
| 1 | +--- |
| 2 | +language: "Scheme" |
| 3 | +filename: scheme.scm |
| 4 | +contributors: |
| 5 | +- ["Bruno Ciccarino", "https://github.com/BrunoCiccarino"] |
| 6 | +--- |
| 7 | + |
| 8 | +Scheme is a minimalist dialect of Lisp that is widely used in education, research, and industry. It emphasizes simplicity, powerful abstractions, and functional programming paradigms. |
| 9 | + |
| 10 | +A classic resource to learn Scheme is [Structure and Interpretation of Computer Programs (SICP)](https://web.mit.edu/6.001/6.037/sicp.pdf). For a modern introduction, consider [The Scheme Programming Language](https://www.scheme.org/). |
| 11 | + |
| 12 | +```scheme |
| 13 | +;;;----------------------------------------------------------------------------- |
| 14 | +;;; 0. Syntax |
| 15 | +;;;----------------------------------------------------------------------------- |
| 16 | +
|
| 17 | +;;; General form |
| 18 | +
|
| 19 | +;;; Scheme has two fundamental elements of syntax: ATOM and S-EXPRESSION. |
| 20 | +;;; S-expressions are used for both data and code. |
| 21 | +
|
| 22 | +10 ; a number atom; evaluates to itself |
| 23 | +'symbol ; a symbol atom; evaluates to itself when quoted |
| 24 | +#t ; boolean true |
| 25 | +(+ 1 2 3) ; an s-expression (function application) |
| 26 | +'(4 'foo #t) ; quoted s-expression (a list) |
| 27 | +
|
| 28 | +
|
| 29 | +;;; Comments |
| 30 | +
|
| 31 | +;;; Single-line comments start with a semicolon: |
| 32 | +; This is a single-line comment |
| 33 | +
|
| 34 | +;;; Block comments use `#|` and `|#`: |
| 35 | +#| This is a block comment. |
| 36 | + It spans multiple lines. |
| 37 | +|# |
| 38 | +
|
| 39 | +
|
| 40 | +;;; REPL and environment |
| 41 | +
|
| 42 | +;;; Scheme is typically developed interactively in a Read-Eval-Print Loop (REPL). |
| 43 | +;;; Implementations such as Racket, Guile, or MIT Scheme provide REPLs for interactive exploration. |
| 44 | +;;; Libraries and tools can be installed depending on the specific implementation. |
| 45 | +
|
| 46 | +
|
| 47 | +
|
| 48 | +;;;----------------------------------------------------------------------------- |
| 49 | +;;; 1. Primitive datatypes and operators |
| 50 | +;;;----------------------------------------------------------------------------- |
| 51 | +
|
| 52 | +;;; Numbers |
| 53 | +
|
| 54 | +42 ; integers |
| 55 | +#b101 ; binary => 5 |
| 56 | +#o777 ; octal => 511 |
| 57 | +#xFF ; hexadecimal => 255 |
| 58 | +3.14 ; floating-point numbers |
| 59 | +1/2 ; fractions (exact rational numbers) |
| 60 | +(make-rectangular 1 2) ; complex numbers |
| 61 | +
|
| 62 | +
|
| 63 | +;;; Basic arithmetic |
| 64 | +
|
| 65 | +(+ 1 2) ; => 3 |
| 66 | +(- 7 3) ; => 4 |
| 67 | +(* 2 5) ; => 10 |
| 68 | +(/ 10 3) ; => 10/3 |
| 69 | +(sqrt 4) ; => 2 |
| 70 | +(expt 2 3) ; => 8 |
| 71 | +
|
| 72 | +
|
| 73 | +;;; Booleans |
| 74 | +
|
| 75 | +#t ; true |
| 76 | +#f ; false |
| 77 | +(and #t #f) ; => #f |
| 78 | +(or #t #f) ; => #t |
| 79 | +(not #t) ; => #f |
| 80 | +
|
| 81 | +
|
| 82 | +;;; Strings |
| 83 | +
|
| 84 | +"Hello, World!" |
| 85 | +(string-append "Hello, " "World!") ; => "Hello, World!" |
| 86 | +
|
| 87 | +
|
| 88 | +;;; Lists |
| 89 | +
|
| 90 | +'(1 2 3) ; a list |
| 91 | +(cons 1 '(2 3)) ; => '(1 2 3) |
| 92 | +(car '(1 2 3)) ; => 1 |
| 93 | +(cdr '(1 2 3)) ; => '(2 3) |
| 94 | +(append '(1 2) '(3 4)) ; => '(1 2 3 4) |
| 95 | +
|
| 96 | +
|
| 97 | +;;;----------------------------------------------------------------------------- |
| 98 | +;;; 2. Variables |
| 99 | +;;;----------------------------------------------------------------------------- |
| 100 | +
|
| 101 | +;;; Define a variable |
| 102 | +
|
| 103 | +(define x 10) |
| 104 | +x ; => 10 |
| 105 | +
|
| 106 | +
|
| 107 | +;;; Define a local variable |
| 108 | +
|
| 109 | +(let ((x 5)) (+ x 10)) ; => 15 |
| 110 | +x ; => 10 (unchanged globally) |
| 111 | +
|
| 112 | +
|
| 113 | +;;;----------------------------------------------------------------------------- |
| 114 | +;;; 3. Functions |
| 115 | +;;;----------------------------------------------------------------------------- |
| 116 | +
|
| 117 | +;;; Define a named function |
| 118 | +
|
| 119 | +(define (square x) |
| 120 | + (* x x)) |
| 121 | +
|
| 122 | +(square 4) ; => 16 |
| 123 | +
|
| 124 | +
|
| 125 | +;;; Define an anonymous (lambda) function |
| 126 | +
|
| 127 | +((lambda (x) (* x x)) 5) ; => 25 |
| 128 | +
|
| 129 | +
|
| 130 | +;;; Higher-order functions |
| 131 | +
|
| 132 | +(define (apply-twice f x) |
| 133 | + (f (f x))) |
| 134 | +
|
| 135 | +(apply-twice square 2) ; => 16 |
| 136 | +
|
| 137 | +
|
| 138 | +;;;----------------------------------------------------------------------------- |
| 139 | +;;; 4. Conditionals and control flow |
| 140 | +;;;----------------------------------------------------------------------------- |
| 141 | +
|
| 142 | +;;; If statements |
| 143 | +
|
| 144 | +(if (> 5 3) |
| 145 | + 'yes |
| 146 | + 'no) ; => 'yes |
| 147 | +
|
| 148 | +
|
| 149 | +;;; Cond expressions (multi-branch conditionals) |
| 150 | +
|
| 151 | +(cond |
| 152 | + [(< 5 3) 'less] |
| 153 | + [(> 5 3) 'greater] |
| 154 | + [else 'equal]) ; => 'greater |
| 155 | +
|
| 156 | +
|
| 157 | +;;;----------------------------------------------------------------------------- |
| 158 | +;;; 5. Structs and collections |
| 159 | +;;;----------------------------------------------------------------------------- |
| 160 | +
|
| 161 | +;;; Define a structure |
| 162 | +
|
| 163 | +(define-struct dog (name breed age)) |
| 164 | +
|
| 165 | +(define my-dog (make-dog "Fido" "Labrador" 5)) |
| 166 | +
|
| 167 | +(dog-name my-dog) ; => "Fido" |
| 168 | +(dog-age my-dog) ; => 5 |
| 169 | +
|
| 170 | +
|
| 171 | +;;;----------------------------------------------------------------------------- |
| 172 | +;;; 6. Common patterns |
| 173 | +;;;----------------------------------------------------------------------------- |
| 174 | +
|
| 175 | +;;; Recursive functions |
| 176 | +
|
| 177 | +(define (factorial n) |
| 178 | + (if (= n 0) |
| 179 | + 1 |
| 180 | + (* n (factorial (- n 1))))) |
| 181 | +
|
| 182 | +(factorial 5) ; => 120 |
| 183 | +
|
| 184 | +
|
| 185 | +;;;----------------------------------------------------------------------------- |
| 186 | +;;; 7. Libraries and modules |
| 187 | +;;;----------------------------------------------------------------------------- |
| 188 | +
|
| 189 | +;;; Importing libraries/modules depends on the implementation. |
| 190 | +;;; For example, in Racket: |
| 191 | +
|
| 192 | +(require racket/math) |
| 193 | +
|
| 194 | +(sqrt 16) ; => 4 |
| 195 | +
|
| 196 | +;;;----------------------------------------------------------------------------- |
| 197 | +;;; 8. Macros |
| 198 | +;;;----------------------------------------------------------------------------- |
| 199 | +
|
| 200 | +;;; Macros allow you to create new syntactic constructs. |
| 201 | +
|
| 202 | +(define-syntax when |
| 203 | + (syntax-rules () |
| 204 | + [(when test body ...) |
| 205 | + (if test |
| 206 | + (begin body ...))])) |
| 207 | +
|
| 208 | +(when #t |
| 209 | + (display "Condition is true!\n")) ; Output: Condition is true! |
| 210 | +
|
| 211 | +
|
| 212 | +;;;----------------------------------------------------------------------------- |
| 213 | +;;; 9. Input and Output (I/O) |
| 214 | +;;;----------------------------------------------------------------------------- |
| 215 | +
|
| 216 | +;;; Printing to the console |
| 217 | +
|
| 218 | +(display "Hello, Scheme!") ; => prints "Hello, Scheme!" |
| 219 | +(newline) ; => moves to the next line |
| 220 | +
|
| 221 | +
|
| 222 | +;;; Reading input |
| 223 | +
|
| 224 | +(let ((user-input (read))) |
| 225 | + (display "You entered: ") |
| 226 | + (display user-input)) |
| 227 | +
|
| 228 | +
|
| 229 | +;;; File I/O |
| 230 | +
|
| 231 | +(define output-port (open-output-file "example.txt")) |
| 232 | +(display "Writing to a file." output-port) |
| 233 | +(close-output-port output-port) |
| 234 | +
|
| 235 | +(define input-port (open-input-file "example.txt")) |
| 236 | +(let ((file-content (read input-port))) |
| 237 | + (display file-content)) |
| 238 | +(close-input-port input-port) |
| 239 | +
|
| 240 | +
|
| 241 | +;;;----------------------------------------------------------------------------- |
| 242 | +;;; 10. Iteration |
| 243 | +;;;----------------------------------------------------------------------------- |
| 244 | +
|
| 245 | +;;; Iterating with `do` |
| 246 | +
|
| 247 | +(do ((i 0 (+ i 1))) ; initialize i to 0, increment by 1 |
| 248 | + ((>= i 5)) ; stop when i >= 5 |
| 249 | + (display i) ; print i |
| 250 | + (newline)) |
| 251 | +
|
| 252 | +
|
| 253 | +;;; Using recursion for iteration |
| 254 | +
|
| 255 | +(define (countdown n) |
| 256 | + (if (= n 0) |
| 257 | + (display "Blastoff!\n") |
| 258 | + (begin |
| 259 | + (display n) |
| 260 | + (newline) |
| 261 | + (countdown (- n 1))))) |
| 262 | +
|
| 263 | +(countdown 5) ; Output: 5 4 3 2 1 Blastoff! |
| 264 | +
|
| 265 | +
|
| 266 | +;;;----------------------------------------------------------------------------- |
| 267 | +;;; 11. Error handling |
| 268 | +;;;----------------------------------------------------------------------------- |
| 269 | +
|
| 270 | +;;; Using `guard` for error handling (Racket example) |
| 271 | +
|
| 272 | +(guard [e (displayln (format "Error: ~a" e))] |
| 273 | + (/ 1 0)) ; Output: Error: division by zero |
| 274 | +
|
| 275 | +
|
| 276 | +;;; Catching exceptions manually |
| 277 | +
|
| 278 | +(with-handlers ([exn:fail? (lambda (e) (displayln "Caught an error!"))]) |
| 279 | + (error "Something went wrong!")) ; Output: Caught an error! |
| 280 | +
|
| 281 | +
|
| 282 | +;;;----------------------------------------------------------------------------- |
| 283 | +;;; 12. Advanced concepts |
| 284 | +;;;----------------------------------------------------------------------------- |
| 285 | +
|
| 286 | +;;; Continuations with `call/cc` |
| 287 | +
|
| 288 | +(call/cc |
| 289 | + (lambda (cont) |
| 290 | + (display "Before continuation\n") |
| 291 | + (cont #f) |
| 292 | + (display "After continuation\n"))) ; Output: Before continuation |
| 293 | +
|
| 294 | +
|
| 295 | +;;; Lazy evaluation (streams) |
| 296 | +
|
| 297 | +(define (make-stream start step) |
| 298 | + (cons start |
| 299 | + (lambda () (make-stream (+ start step) step)))) |
| 300 | +
|
| 301 | +(define nums (make-stream 0 1)) ; Infinite stream starting at 0, incrementing by 1 |
| 302 | +
|
| 303 | +(define (stream-ref stream n) |
| 304 | + (if (= n 0) |
| 305 | + (car stream) |
| 306 | + (stream-ref ((cdr stream)) (- n 1)))) |
| 307 | +
|
| 308 | +(stream-ref nums 5) ; => 5 |
| 309 | +
|
| 310 | +
|
| 311 | +;;;----------------------------------------------------------------------------- |
| 312 | +;;; 13. Meta-programming |
| 313 | +;;;----------------------------------------------------------------------------- |
| 314 | +
|
| 315 | +;;; Evaluate expressions dynamically |
| 316 | +
|
| 317 | +(eval '(+ 1 2)) ; => 3 |
| 318 | +
|
| 319 | +
|
| 320 | +;;; Quasiquoting for meta-programming |
| 321 | +
|
| 322 | +`(1 2 ,(+ 3 4)) ; => '(1 2 7) |
| 323 | +
|
| 324 | +``` |
0 commit comments