Scheme is a programming language derived from AlgolLanguage and LispLanguage. It is a small, efficient language defined by R5RS. Scheme is an impure functional language (it can also be adapted to be object oriented, database oriented, etc. Basically, it can do whatever you want it to).
Scheme was one of the first Lisp dialects to use static scope (see: StaticScope) instead of dynamic scope (DynamicScope). CommonLispLanguage also used static scope because of Scheme. Scheme features properly tail recursive (TailRecursion) function calls, Continuations, and the ability to incrementally compile programs one definition at a time.
Since Scheme is a language targetted towards education, there are several good textbooks on it. A popular one is How To Design Programs which is targetted towards people who have never programmed before or have "at worst" (according to the authors) taken the College Board AP Computer Science classes. The classic text on Scheme is Structure and Interpretation of Computer Programs, the text for which Scheme was created.
There are many implementations of Scheme, including PLT Scheme, GNU Guile, MIT/GNU Scheme, and Bigloo. A more complete list can be found at schemers.org. The DrScheme system, based on PLT Scheme, is particularly well-suited to learning Scheme. Obligatory 'Hello, World!':
(display "Hello, World!") (newline)
Example of object-oriented stuff:
;; (make-point X Y) returns a point object.
;; It responds to the selectors:
;; x - returns the X value
;; y - returns the Y value
;; move DX DY - return (make-point (+ X DX) (+ Y DY))
;; set-x! X - replace the X value
;; set-y! Y - replace the Y value
;; move! DX DY - destructively move
;; ->string - return a printed representation of the point
;; = P - compares two points
(define (make-point x y)
;; Recursively bind SELF to the actual object (a closure) --
;; recursively so it can reference itself.
(letrec
((self
(lambda (selector)
;; This is like C's 'switch' statement.
(case selector
;; If SELECTOR is the symbol X, return a method that
;; returns the X value.
((x) (lambda () x))
((y) (lambda () y))
;; Functional updates.
((move) (lambda (dx dy)
(make-point (+ x dx)
(+ y dy))))
;; Destructive updates.
((set-x!) (lambda (new-x) (set! x new-x)))
((set-y!) (lambda (new-y) (set! y new-y)))
;; Reference SELF.
((move!) (lambda (dx dy)
((self 'set-x!) (+ x dx))
((self 'set-y!) (+ y dy))))
((->string) (lambda ()
(string-append "("
(number->string x)
", "
(number->string y)
")")))
((=) (lambda (p)
(and (= x ((p 'x))) (= y ((p 'y))))))
(else (error "Unknown selector" selector))))))
;; Return the object we just created.
self))
;;; Examples of using points
;; Methods are invoked with:
;; ((object 'method) argument ...)
(define p1 (make-point 5 3))
((p1 'x)) ;; ==> 5
((p1 'y)) ;; ==> 3
(define p2 ((p1 'move) -2 2))
((p2 'x)) ;; ==> 3
((p2 'y)) ;; ==> 5
((p1 'set-x!) 9)
((p1 'set-y!) 4)
((p1 '->string)) ;; ==> "(9, 4)"
((p2 '->string)) ;; ==> "(3, 5)"
((p1 'move!) -6 1)
((p1 '->string)) ;; ==> "(3, 5)"
((p2 '->string)) ;; ==> "(3, 5)"
((p1 '=) p2) ;; ==> #t
((p2 '=) p1) ;; ==> #t
;;; Subclassing
;; 3D points respond to the following selectors, as well as all those
;; defined by the original points: (o means 'overrided')
;; z - return the Z value
;; o move DX DY DZ -
;; return (make-3d-point (+ X DX) (+ Y DY) (+ Z DZ))
;; set-z! Z - set the Z value
;; o move! DX DY DZ - destructively move the point
;; o ->string - return a printed representation of the point
(define (make-3d-point x y z)
(let ((super (make-point x y)))
(letrec
((self
(lambda (selector)
(case selector
((z) (lambda () z))
;; Overriding
((move) (lambda (dx dy dz)
(make-3d-point (+ ((self 'x)) dx)
(+ ((self 'y)) dy)
(+ z dz))))
((set-z!) (lambda (new-z) (set! z new-z)))
;; Reference to SUPER.
((move!) (lambda (dx dy dz)
((super 'move!) dx dy)
((self 'set-z!) (+ z dz))))
((->string) (lambda ()
(string-append "("
((self 'x))
", "
((self 'y))
", "
z
")")))
((=) (lambda (p)
(and ((super '=) p)
(= z ((p 'z))))))
;; Otherwise, invoke SUPER's method.
(else (super selector))))))
self)))