SchemeDialect of programming language Lisp
Scheme is one of the two most popular Lisp dialects. It follows minimalist philosophy, so it provides a small core language and a powerful toolkit for expanding the language.
Scheme was developed by Guy L. Steele and Gerald Jay Sussman in 1975 and presented to the programming community in a series of articles, so called Lambda Papers, during the next five years. Scheme is standardized in IEEE Standard for the Scheme Programming Language (1995), and in a series of de facto standards called the Revised n Report on the Algorithmic Language Scheme (RnRS):
- Scheme, 1975 : Sussman, Steele
- R1RS, 1978 : Steele, Sussman
- R2RS, 1985: Clinger
- R3RS, 1986: Clinger, Rees
- R4RS, 1991: Clinger, Rees
- R5RS, 1998: Kelsey et al.
- R6RS, 2007: Sperber et al.
- R7RS, 201x: in 2009 Scheme Steering Committee which supervises the standardization process announced the intention to break the dialect in two parts, Small and Large. Small will follow minimalistic traditions, while Large will be a modern evolved language while staying a proper superset of Small.
Main Scheme features (differences from other Lisp dialects):
- minimalism based on lambda-calculus: it is used to derive a huge part of language syntax (11 constructs of 23) from other, simpler ones.
- static lexical scope: variable name refers to the most local context possible.
blocks are implemented with three constructs:
- “proper” tail recursion allows to write loops in idiomatic recursive form, and optimizes them so that unlimited quantity of tail calls can be supported.
continuations (abstract representations of program state) are first-class objects (procedure
- procedures and variables have a common namespace.
Fibonacci numbers:Example for versions JScheme 7.2, MIT/GNU Scheme 7.7.9, guile 1.8.5
This example uses recursive definition of Fibonacci numbers.
(define (fibonacci x) (if (< x 2) x (+ (fibonacci (- x 1)) (fibonacci (- x 2))))) (do ((i 1 (+ i 1))) ((> i 16)) (display (string-append (number->string (fibonacci i)) ", "))) (display "...") (newline)
Factorial:Example for versions JScheme 7.2, MIT/GNU Scheme 7.7.9, guile 1.8.5
(define (factorial x) (if (< x 2) 1 (* x (factorial (- x 1))))) (do ((i 0 (+ i 1))) ((> i 16)) (display (string-append (number->string i) "! = ")) (display (number->string (factorial i))) (newline))
Hello, World!:Example for versions JScheme 7.2, MIT/GNU Scheme 7.7.9, guile 1.8.5
Printing a message is a side effect of this command. Depending on the chosen implementation, the command will return either the message printed, or
Unspecified return value.
(write "Hello, World!")
Quadratic equation:Example for versions guile 1.8.5
begin is used to execute several commands in row.
(define A (read)) (define B (read)) (define C (read)) (define D (- (* B B) (* 4 A C))) (if (= A 0) (display "Not a quadratic equation.") (begin (define k1 (/ B -2 A)) (define k2 (/ (sqrt (abs D)) 2 A)) (if (= D 0) (begin (display "x = ") (display k1)) (if (> D 0) (begin (display "x1 = ") (display (+ k1 k2)) (newline) (display "x2 = ") (display (- k1 k2))) (begin (display "x1 = (") (display k1) (display ", ") (display k2) (display ")") (newline) (display "x2 = (") (display k1) (display ", ") (display (- k2)) (display ")"))))))
CamelCase:Example for versions guile 1.8.5
This program shows how to use regular expressions from
regex module. First two commands load the necessary modules. The third one reads a line from input stream using
read-line command (
rdelim module) — unlike plain
read, it consumes characters till the end of line, not till the first whitespace — and converts it to lowercase.
The fourth command finds all matches for a regexp which describes a sequence of lowercase letters. Then it replaces each match with a return of a certain function applied to it (bound using
lambda). In this case the function is
string-titlecase which converts the first character of the string to uppercase.
Finally, the fifth command removes all non-letter characters from the string.
(use-modules (ice-9 regex)) (use-modules (ice-9 rdelim)) (define text (string-downcase (read-line))) (define text (regexp-substitute/global #f "[a-z]+" text 'pre (lambda (m) (string-titlecase (match:substring m))) 'post)) (define text (regexp-substitute/global #f "[^a-zA-Z]+" text 'pre 'post)) (display text)