The Scheme language is standardized in the officialInstitute of Electrical and Electronics Engineers (IEEE) standard[3] and ade facto standard called theRevisedn Report on the Algorithmic Language Scheme (RnRS). A widely implemented standard is R5RS (1998).[4] The most recently ratified standard of Scheme is "R7RS-small" (2013).[5] The more expansive and modular R6RS was ratified in 2007.[6] Both trace their descent from R5RS; the timeline below reflects the chronological order of ratification.
Scheme started in the 1970s as an attempt to understandCarl Hewitt'sActor model, for which purpose Steele and Sussman wrote a "tiny Lisp interpreter" usingMaclisp and then "added mechanisms for creating actors and sending messages".[7] Scheme was originally called "Schemer", in the tradition of otherLisp-derived languages such asPlanner orConniver. The current name resulted from the authors' use of theITS operating system, which limited filenames to two components of at most six characters each. Currently, "Schemer" is commonly used to refer to a Scheme programmer.
A new language standardization process began at the 2003 Scheme workshop, with the goal of producing an R6RS standard in 2006. This process broke with the earlier RnRS approach of unanimity.
R6RS features a standard module system, allowing a split between the core language andlibraries. Several drafts of the R6RS specification were released, the final version being R5.97RS. A successful vote resulted in ratifying the new standard, announced on August 28, 2007.[6]
Currently the newest releases of various Scheme implementations[8] support the R6RS standard. There is a portable reference implementation of the proposed implicitly phased libraries for R6RS, called psyntax, which loads and bootstraps itself properly on various older Scheme implementations.[9]
A feature of R6RS is the record-type descriptor (RTD). When an RTD is created and used, the record type representation can show the memory layout. It also calculated object field bit mask and mutable Scheme object field bit masks, and helped the garbage collector know what to do with the fields without traversing the whole fields list that are saved in the RTD. RTD allows users to expand the basic RTD to create a new record system.[10]
R6RS introduces numerous significant changes to the language.[11] The source code is now specified inUnicode, and a large subset of Unicode characters may now appear in Scheme symbols andidentifiers, and there are other minor changes to the lexical rules. Character data is also now specified in Unicode. Many standard procedures have been moved to the new standard libraries, which themselves form a large expansion of the standard, containing procedures and syntactic forms that were formerly not part of the standard. A new module system has been introduced, and systems for exception handling are now standardized. Syntax-rules has been replaced with a more expressive syntactic abstraction facility (syntax-case) which allows the use of all of Scheme at macro expansion time. Compliant implementations are nowrequired to support Scheme's fullnumeric tower, and the semantics of numbers have been expanded, mainly in the direction of support for theIEEE 754 standard for floating point numerical representation.
The R6RS standard has caused controversy because some see it as a departure from the minimalist philosophy.[12][13] In August 2009, the Scheme Steering Committee, which oversees the standardization process, announced its intention to recommend splitting Scheme into two languages: a large modern programming language for programmers; and a small version, a subset of the large version retaining the minimalism praised by educators and casual implementors.[14] Two working groups were created to work on these two new versions of Scheme. The Scheme Reports Process site has links to the working groups' charters, public discussions and issue tracking system.
The ninth draft of R7RS (small language) was made available on April 15, 2013.[15] A vote ratifying this draft closed on May 20, 2013,[16] and the final report has been available since August 6, 2013, describing "the 'small' language of that effort: therefore it cannot be considered in isolation as the successor to R6RS".[5]
Scheme is primarily afunctional programming language. It shares many characteristics with other members of the Lisp programming language family. Scheme's very simple syntax is based ons-expressions, parenthesized lists in which a prefix operator is followed by its arguments. Scheme programs thus consist of sequences of nested lists. Lists are also the main data structure in Scheme, leading to a close equivalence between source code and data formats (homoiconicity). Scheme programs can easily create and evaluate pieces of Scheme code dynamically.
The reliance on lists as data structures is shared by all Lisp dialects. Scheme inherits a rich set oflist-processing primitives such ascons,car andcdr from its Lisp progenitors. Scheme uses strictly butdynamically typed variables and supportsfirst class procedures. Thus, procedures can be assigned as values to variables or passed as arguments to procedures.
This section concentrates mainly on innovative features of the language, including those features that distinguish Scheme from other Lisps. Unless stated otherwise, descriptions of features relate to the R5RS standard. In examples provided in this section, the notation "===> result" is used to indicate the result of evaluating the expression on the immediately preceding line. This is the same convention used in R5RS.
Scheme is a very simple language, much easier to implement than many other languages of comparableexpressive power.[17] This ease is attributable to the use oflambda calculus to derive much of the syntax of the language from more primitive forms. For instance of the 23 s-expression-based syntactic constructs defined in the R5RS Scheme standard, 14 are classed as derived or library forms, which can be written as macros involving more fundamental forms, principally lambda. As R5RS (§3.1) says: "The most fundamental of the variable binding constructs is the lambda expression, because all other variable binding constructs can be explained in terms of lambda expressions."[4]
Thus usinglet as defined above a Scheme implementation would rewrite "(let ((a 1)(b 2)) (+ b a))" as "((lambda (a b) (+ b a)) 1 2)", which reduces implementation's task to that of coding procedure instantiations.
In 1998, Sussman and Steele remarked that the minimalism of Scheme was not a conscious design goal, but rather the unintended outcome of the design process. "We were actually trying to build something complicated and discovered, serendipitously, that we had accidentally designed something that met all our goals but was much simpler than we had intended....we realized that the lambda calculus—a small, simple formalism—could serve as the core of a powerful and expressive programming language."[7]
Like most modern programming languages and unlike earlier Lisps such asMaclisp, Scheme is lexically scoped: all possible variable bindings in a program unit can be analyzed by reading the text of the program unit without consideration of the contexts in which it may be called. This contrasts with dynamic scoping which was characteristic of early Lisp dialects, because of the processing costs associated with the primitive textual substitution methods used to implement lexical scoping algorithms in compilers and interpreters of the day. In those Lisps, it was perfectly possible for a reference to afree variable inside a procedure to refer to quite distinct bindings external to the procedure, depending on the context of the call.
The impetus to incorporate lexical scoping, which was an unusual scoping model in the early 1970s, into their new version of Lisp, came from Sussman's studies ofALGOL. He suggested thatALGOL-like lexical scoping mechanisms would help to realize their initial goal of implementingHewitt's Actor model in Lisp.[7]
The key insights on how to introduce lexical scoping into a Lisp dialect were popularized in Sussman and Steele's 1975 Lambda Paper, "Scheme: An Interpreter for Extended Lambda Calculus",[18] where they adopted the concept of thelexical closure (on page 21), which had been described in anAI Memo in 1970 byJoel Moses, who attributed the idea toPeter J. Landin.[19]
Alonzo Church's mathematical notation, the lambda calculus, has inspired Lisp's use of "lambda" as a keyword for introducing a procedure, as well as influencing the development offunctional programming techniques involving the use ofhigher-order functions in Lisp. But early Lisps were not suitable expressions of the lambda calculus because of their treatment offree variables.[7]
A formal lambda system has axioms and a complete calculation rule. It is helpful for the analysis using mathematical logic and tools. In this system, calculation can be seen as a directional deduction. The syntax of lambda calculus follows the recursive expressions from x, y, z, ...,parentheses, spaces, the period and the symbol λ.[20] The function of lambda calculation includes: First, serve as a starting point of powerful mathematical logic. Second, it can reduce the requirement of programmers to consider the implementation details, because it can be used to imitate machine evaluation. Finally, the lambda calculation created a substantial meta-theory.[21]
The introduction of lexical scope resolved the problem by making an equivalence between some forms of lambda notation and their practical expression in a working programming language. Sussman and Steele showed that the new language could be used to elegantly derive all the imperative and declarative semantics of other programming languages including ALGOL andFortran, and the dynamic scope of other Lisps, by using lambda expressions not as simple procedure instantiations but as "control structures and environment modifiers".[22] They introducedcontinuation-passing style along with their first description of Scheme in the first of the Lambda Papers, and in subsequent papers, they proceeded to demonstrate the raw power of this practical use of lambda calculus.
Scheme inherits its block structure from earlier block structured languages, particularlyALGOL. In Scheme, blocks are implemented by threebinding constructs:let,let* andletrec. For instance, the following construct creates ablock in which a symbol calledvar is bound to the number 10:
(definevar"goose");; Any reference to var here will be bound to "goose"(let((var10));; statements go here. Any reference to var here will be bound to 10.);; Any reference to var here will be bound to "goose"
Blocks can benested to create arbitrarily complex block structures according to the need of the programmer. The use of block structuring to create local bindings alleviates the risk ofnamespace collision that can otherwise occur.
One variant oflet,let*, permits bindings to refer to variables defined earlier in the same construct, thus:
(let*((var110)(var2(+var112)));; But the definition of var1 could not refer to var2)
The other variant,letrec, is designed to enablemutually recursive procedures to be bound to one another.
;; Calculation of Hofstadter's male and female sequences as a list of pairs(define(hofstadter-male-femalen)(letrec((female(lambda(n)(if(=n0)1(-n(male(female(-n1)))))))(male(lambda(n)(if(=n0)0(-n(female(male(-n1))))))))(letloop((i0))(if(>in)'()(cons(cons(femalei)(malei))(loop(+i1)))))))(hofstadter-male-female8)===>((1.0)(1.0)(2.1)(2.2)(3.2)(3.3)(4.4)(5.4)(5.5))
All procedures bound in a singleletrec may refer to one another by name, as well as to values of variables defined earlier in the sameletrec, but they may not refer tovalues defined later in the sameletrec.
A variant oflet, the "named let" form, has an identifier after thelet keyword. This binds the let variables to the argument of a procedure whose name is the given identifier and whose body is the body of the let form. The body may be repeated as desired by calling the procedure. The named let is widely used to implement iteration.
Scheme has an iteration construct,do, but it is moreidiomatic in Scheme to usetail recursion to expressiteration. Standard-conforming Scheme implementations are required to optimize tail calls so as to support an unbounded number of active tail calls (R5RS sec. 3.5)[4]—a property the Scheme report describes asproper tail recursion—making it safe for Scheme programmers to write iterative algorithms using recursive structures, which are sometimes more intuitive. Tail recursive procedures and thenamedlet form provide support for iteration using tail recursion.
;; Building a list of squares from 0 to 9:;; Note: loop is simply an arbitrary symbol used as a label. Any symbol will do.(define(list-of-squaresn)(letloop((in)(res'()))(if(<i0)res(loop(-i1)(cons(*ii)res)))))(list-of-squares9)===>(0149162536496481)
Continuations in Scheme arefirst-class objects. Scheme provides the procedurecall-with-current-continuation (also known ascall/cc) to capture the current continuation by packing it up as an escape procedure bound to a formal argument in a procedure provided by the programmer. (R5RS sec. 6.4)[4] First-class continuations enable the programmer to create non-localcontrol constructs such asiterators,coroutines, andbacktracking.
Continuations can be used to emulate the behavior ofreturn statements in imperative programming languages. The following functionfind-first, given functionfunc and listlst, returns the first elementx inlst such that(func x) returns true.
The following example, a traditional programmer's puzzle, shows that Scheme can handle continuations as first-class objects, binding them to variables and passing them as arguments to procedures.
In contrast to Common Lisp, all data and procedures in Scheme share a common namespace, whereas in Common Lispfunctions and data have separate namespaces making it possible for a function and a variable to have the same name, and requiring special notation for referring to a function as a value. This is sometimes known as the "Lisp-1 vs. Lisp-2" distinction, referring to the unified namespace of Scheme and the separate namespaces of Common Lisp.[23]
In Scheme, the same primitives that are used to manipulate and bind data can be used to bind procedures. There is no equivalent of Common Lisp'sdefun and#' primitives.
;; Variable bound to a number:(definef10)f===>10;; Mutation (altering the bound value)(set!f(+ff6))f===>26;; Assigning a procedure to the same variable:(set!f(lambda(n)(+n12)))(f6)===>18;; Assigning the result of an expression to the same variable:(set!f(f1))f===>13;; functional programming:(apply+'(123456))===>21(set!f(lambda(n)(+n100)))(mapf'(123))===>(101102103)
This subsection documents design decisions that have been taken over the years which have given Scheme a particular character, but are not the direct outcomes of the original design.
Scheme specifies a comparatively full set of numerical datatypes includingcomplex andrational types, which is known in Scheme as the numerical tower (R5RS sec. 6.2[4]). The standard treats these as abstractions, and does not commit the implementor to any particular internal representations.
Numbers may have the quality of exactness. An exact number can only be produced by a sequence of exact operations involving other exact numbers—inexactness is thus contagious. The standard specifies that any two implementations must produce equivalent results for all operations resulting in exact numbers.
The R5RS standard specifies proceduresexact->inexact andinexact->exact which can be used to change the exactness of a number.inexact->exact produces "the exact number that is numerically closest to the argument".exact->inexact produces "the inexact number that is numerically closest to the argument". The R6RS standard omits these procedures from the main report, but specifies them as R5RS compatibility procedures in the standard library (rnrs r5rs (6)).
In the R5RS standard, Scheme implementations are not required to implement the whole numerical tower, but they must implement "a coherent subset consistent with both the purposes of the implementation and the spirit of the Scheme language" (R5RS sec. 6.2.3).[4] The new R6RS standard does require implementation of the whole tower, and "exact integer objects and exact rational number objects of practically unlimited size and precision, and to implement certain procedures...so they always return exact results when given exact arguments" (R6RS sec. 3.4, sec. 11.7.1).[6]
Example 1: exact arithmetic in an implementation that supports exact rational complex numbers.
;; Sum of three rational real numbers and two rational complex numbers(definex(+1/31/4-1/5-1/3i405/50+2/3i))x===>509/60+1/3i;; Check for exactness.(exact?x)===>#t
Example 2: Same arithmetic in an implementation that supports neither exact rational numbers nor complex numbers but does accept real numbers in rational notation.
;; Sum of four rational real numbers(definexr(+1/31/4-1/5405/50));; Sum of two rational real numbers(definexi(+-1/32/3))xr===>8.48333333333333xi===>0.333333333333333;; Check for exactness.(exact?xr)===>#f(exact?xi)===>#f
Both implementations conform to the R5RS standard but the second does not conform to R6RS because it does not implement the full numerical tower.
The lexical context of the original definition of the promise is preserved, and its value is also preserved after the first use offorce. The promise is only ever evaluated once.
These primitives, which produce or handle values known aspromises, can be used to implement advancedlazy evaluation constructs such asstreams.[24]
In the R6RS standard, these are no longer primitives, but instead, are provided as part of the R5RS compatibility library (rnrs r5rs (6)).
In R5RS, a suggested implementation ofdelay andforce is given, implementing the promise as a procedure with no arguments (athunk) and usingmemoization to ensure that it is only ever evaluated once, irrespective of the number of timesforce is called (R5RS sec. 6.4).[4]
SRFI 41 enables the expression of both finite and infinite sequences with extraordinary economy. For example, this is a definition of theFibonacci sequence using the functions defined in SRFI 41:[24]
;; Define the Fibonacci sequence:(definefibs(stream-cons0(stream-cons1(stream-map+fibs(stream-cdrfibs)))));; Compute the hundredth number in the sequence:(stream-reffibs99)===>218922995834555169026
Most Lisps specify an order of evaluation for procedure arguments. Scheme does not. Order of evaluation—including the order in which the expression in the operator position is evaluated—may be chosen by an implementation on a call-by-call basis, and the only constraint is that "the effect of any concurrent evaluation of the operator and operand expressions is constrained to be consistent with some sequential order of evaluation." (R5RS sec. 4.1.3)[4]
ev is a procedure that describes the argument passed to it, then returns the value of the argument. In contrast with other Lisps, the appearance of an expression in the operator position (the first item) of a Scheme expression is quite legal, as long as the result of the expression in the operator position is a procedure.
In calling the procedure "+" to add 1 and 2, the expressions(ev +), (ev 1) and(ev 2) may be evaluated in any order, as long as the effect is not as if they were evaluated in parallel. Thus the following three lines may be displayed in any order by standard Scheme when the above example code is executed, although the text of one line may not be interleaved with another because that would violate the sequential evaluation constraint.
In the R5RS standard and in later reports, the syntax of Scheme can easily be extended via the macro system. The R5RS standard introduced a powerful hygienic macro system that allows the programmer to add new syntactic constructs to the language using a simplepattern matching sublanguage (R5RS sec 4.3).[4] Prior to this, the hygienic macro system had been relegated to an appendix of the R4RS standard, as a "high level" system alongside a "low level" macro system, both of which were treated as extensions to Scheme rather than an essential part of the language.[25]
Implementations of the hygienic macro system, also calledsyntax-rules, are required to respect the lexical scoping of the rest of the language. This is assured by special naming and scoping rules for macro expansion and avoids common programming errors that can occur in the macro systems of other programming languages. R6RS specifies a more sophisticated transformation system,syntax-case, which has been available as a language extension to R5RS Scheme for some time.
;; Define a macro to implement a variant of "if" with a multi-expression;; true branch and no false branch.(define-syntaxwhen(syntax-rules()((whenpredexpexps...)(ifpred(beginexpexps...)))))
Invocations of macros and procedures bear a close resemblance—both are s-expressions—but they are treated differently. When the compiler encounters an s-expression in the program, it first checks to see if the symbol is defined as a syntactic keyword within the current lexical scope. If so, it then attempts to expand the macro, treating the items in the tail of the s-expression as arguments without compiling code to evaluate them, and this process is repeated recursively until no macro invocations remain. If it is not a syntactic keyword, the compiler compiles code to evaluate the arguments in the tail of the s-expression and then to evaluate the variable represented by the symbol at the head of the s-expression and call it as a procedure with the evaluated tail expressions passed as arguments to it.
Most Scheme implementations also provide additional macro systems. Among popular ones aresyntactic closures,explicit renaming macros anddefine-macro, a non-hygienic macro system similar todefmacro system provided inCommon Lisp.
The inability to specify whether or not a macro is hygienic is one of the shortcomings of the macro system. Alternative models for expansion such as scope sets provide a potential solution.[26]
Prior to R5RS, Scheme had no standard equivalent of theeval procedure which is ubiquitous in other Lisps, although the first Lambda Paper had describedevaluate as "similar to the LISP function EVAL"[18] and the first Revised Report in 1978 replaced this withenclose, which took two arguments. The second, third and fourth revised reports omitted any equivalent ofeval.
The reason for this confusion is that in Scheme with its lexical scoping the result of evaluating an expression depends on where it is evaluated. For instance, it is not clear whether the result of evaluating the following expression should be 5 or 6:[27]
(let((name'+))(let((+*))(evaluate(listname23))))
If it is evaluated in the outer environment, wherename is defined, the result is the sum of the operands. If it is evaluated in the inner environment, where the symbol "+" has been bound to the value of the procedure "*", the result is the product of the two operands.
R5RS resolves this confusion by specifying three procedures that return environments and providing a procedureeval that takes an s-expression and an environment and evaluates the expression in the environment provided. (R5RS sec. 6.5)[4] R6RS extends this by providing a procedure calledenvironment by which the programmer can specify exactly which objects to import into the evaluation environment.
With modern scheme (usually compatible with R5RS) to evaluate this expression, one needs to define a functionevaluate which can look like this:
In most dialects of Lisp including Common Lisp, by convention the valueNIL evaluates to the value false in a Boolean expression. In Scheme, since the IEEE standard in 1991,[3] all values except#f, includingNIL's equivalent in Scheme which is written as'(), evaluate to the value true in a Boolean expression. (R5RS sec. 6.3.1)[4]
Where the constant representing the Boolean value of true isT in most Lisps, in Scheme it is#t.
In Scheme the primitive datatypes are disjoint. Only one of the following predicates can be true of any Scheme object:boolean?,pair?,symbol?,number?,char?,string?,vector?,port?,procedure?. (R5RS sec 3.2)[4]
Within the numerical datatype, by contrast, the numerical values overlap. For example, an integer value satisfies all of theinteger?,rational?,real?,complex? andnumber? predicates at the same time. (R5RS sec 6.2)[4]
Scheme has three different types of equivalence between arbitrary objects denoted by three differentequivalence predicates, relational operators for testing equality,eq?,eqv? andequal?:
eq? evaluates to#f unless its parameters represent the same data object in memory;
eqv? is generally the same aseq? but treats primitive objects (e.g. characters and numbers) specially so that numbers that represent the same value areeqv? even if they do not refer to the same object;
equal? compares data structures such as lists, vectors and strings to determine if they have congruent structure andeqv? contents.(R5RS sec. 6.1)[4]
Type dependent equivalence operations also exist in Scheme:string=? andstring-ci=? compare two strings (the latter performs a case-independent comparison);char=? andchar-ci=? compare characters;= compares numbers.[4]
Up to the R5RS standard, the standard comment in Scheme was a semicolon, which makes the rest of the line invisible to Scheme. Numerous implementations have supported alternative conventions permitting comments to extend for more than a single line, and the R6RS standard permits two of them: an entires-expression may be turned into a comment (or "commented out") by preceding it with#; (introduced in SRFI 62[28]) and a multiline comment or "block comment" may be produced by surrounding text with#| and|#.
Scheme's input and output is based on theport datatype. (R5RS sec 6.6)[4] R5RS defines two default ports, accessible with the procedurescurrent-input-port andcurrent-output-port, which correspond to the Unix notions ofstandard input and standard output. Most implementations also providecurrent-error-port.Redirection of input and standard output is supported in the standard, by standard procedures such aswith-input-from-file andwith-output-to-file. Most implementations provide string ports with similar redirection capabilities, enabling many normal input-output operations to be performed on string buffers instead of files, using procedures described in SRFI 6.[29] The R6RS standard specifies much more sophisticated and capable port procedures and many new types of port.
The following examples are written in strict R5RS Scheme.
Example 1: With output defaulting to (current-output-port):
Example 3: As 1, but output is redirected to a newly created file
;; NB: with-output-to-file is an optional procedure in R5RS(let((hello0(lambda()(display"Hello world")(newline))))(with-output-to-file"helloworldoutputfile"hello0))
Example 4: As 2, but with explicit file open and port close to send output to file
Similar procedures are provided for input. R5RS Scheme provides the predicatesinput-port? andoutput-port?. For character input and output,write-char,read-char,peek-char andchar-ready? are provided. For writing and reading Scheme expressions, Scheme providesread andwrite. On a read operation, the result returned is the end-of-file object if the input port has reached the end of the file, and this can be tested using the predicateeof-object?.
With the standard, SRFI 28 also defines a basic formatting procedure resembling Common Lisp'sformat function, after which it is named.[30]
In Scheme, procedures are bound to variables. At R5RS the language standard formally mandated that programs may change the variable bindings of built-in procedures, effectively redefining them. (R5RS "Language changes")[4] For example,+ can be extended to accept strings as well as numbers by redefining it:
In R6RS every binding, including the standard ones, belongs to some library, and all exported bindings are immutable. (R6RS sec 7.1)[6] Because of this, redefinition of standard procedures by mutation is forbidden. Instead, it is possible to import a different procedure under the name of a standard one, which in effect is similar to redefinition.
In Standard Scheme, procedures that convert from one datatype to another contain the character string "->" in their name, predicates end with a "?", and procedures that change the value of already-allocated data end with a "!". These conventions are often followed by Scheme programmers.
In formal contexts such as Scheme standards, the word "procedure" is used in preference to "function" to refer to a lambda expression or primitive procedure. In normal usage, the words "procedure" and "function" are used interchangeably. Procedure application is sometimes referred to formally ascombination.
As in other Lisps, the term "thunk" is used in Scheme to refer to a procedure with no arguments. The term "proper tail recursion" refers to the property of all Scheme implementations, that they perform tail-call optimization so as to support an indefinite number of activetail calls.
The form of the titles of the standards documents since R3RS, "Revisedn Report on the Algorithmic Language Scheme", is a reference to the title of theALGOL 60 standard document, "Revised Report on the Algorithmic Language Algol 60," The Summary page of R3RS is closely modeled on the Summary page of the ALGOL 60 Report.[31][32]
The language is formally defined in the standards R5RS (1998)[4] and R6RS (2007).[6] They describe standard "forms": keywords and accompanying syntax, which provide the control structure of the language, and standard procedures which perform common tasks.
This table describes the standard forms in Scheme. Some forms appear in more than one row because they cannot easily be classified into a single function in the language.
Forms marked "L" in this table are classed as derived "library" forms in the standard and are often implemented as macros using more fundamental forms in practice, making the task of implementation much easier than in other languages.
Whilebegin is defined as a library syntax in R5RS, the expander must know about it to achieve the splicing function. In R6RS it is no longer a library syntax.
The following two tables describe the standard procedures in R5RS Scheme. R6RS is far more extensive and a summary of this type would not be practical.
Some procedures appear in more than one row because they cannot easily be classified into a single function in the language.
String and character procedures that contain "-ci" in their names perform case-independent comparisons between their arguments: upper case and lower case versions of the same character are taken to be equal.
Standard numeric procedures in the language R5RS Scheme
Because of Scheme's minimalism, many common procedures and syntactic forms are not defined by the standard. In order to keep the core language small but facilitate standardization of extensions, the Scheme community has a "Scheme Request for Implementation" (SRFI) process by which extension libraries are defined through careful discussion of extension proposals. This promotes code portability. Many of the SRFIs are supported by all or most Scheme implementations.
SRFIs with fairly wide support in different implementations include:[33]
The elegant, minimalist design has made Scheme a popular target for language designers, hobbyists, and educators, and because of its small size, that of a typicalinterpreter, it is also a popular choice forembedded systems andscripting. This has resulted in scores of implementations,[34] most of which differ from each other so much that porting programs from one implementation to another is quite difficult, and the small size of the standard language means that writing a useful program of any great complexity in standard, portable Scheme is almost impossible.[14] The R6RS standard specifies a much broader language, in an attempt to broaden its appeal to programmers.
Almost all implementations provide a traditional Lisp-styleread–eval–print loop for development and debugging. Many alsocompile Scheme programs to executable binary. Support for embedding Scheme code in programs written in other languages is also common, as the relative simplicity of Scheme implementations makes it a popular choice for adding scripting capabilities to larger systems developed in languages such asC. TheGambit,Chicken, andBigloo Scheme interpreters compile Scheme to C, which makes embedding far easier. Further, Bigloo's compiler can be configured to generatebytecode for theJava virtual machine (JVM), and has an experimental bytecode generator for.NET.
Some implementations support added features. For example,Kawa andJScheme provide integration withJava classes, and the Scheme to C compilers often make it easy to use external libraries written in C, up to allowing the embedding of C code in the Scheme source code. Another example is Pvts, which offers a set of visual tools that support Scheme learning.
Scheme is widely used by several[35] schools; in particular, several introductorycomputer science courses use Scheme in conjunction with the textbookStructure and Interpretation of Computer Programs (SICP).[36] For the past 12 years,PLT has run theProgramByDesign (formerly TeachScheme!) project, which has exposed close to 600 high school teachers and thousands of high school students to rudimentary Scheme programming.MIT's old introductory programming class 6.001 was taught in Scheme,[37] Although 6.001 has been replaced by more modern courses, SICP continues to be taught at MIT.[38] Likewise, the introductory class atUC Berkeley, CS 61A, was until 2011 taught entirely in Scheme, save minor diversions intoLogo to demonstrate dynamic scope. Today, like MIT, Berkeley has replaced the syllabus with a more modern version that is primarily taught inPython 3, but the current syllabus is still based on the old curriculum, and parts of the class are still taught in Scheme.[39]
The textbookHow to Design Programs is used by some institutes of higher education for their introductory computer science courses.Worcester Polytechnic Institute uses Scheme exclusively for its introductory course Introduction to Program Design (CS1101).[40]Rose-Hulman Institute of Technology uses Scheme in its more advanced Programming Language Concepts course.[41]Brandeis University's core course, Structure and Interpretations of Computer Programs (COSI121b), is also taught exclusively in Scheme by theoretical computer scientistHarry Mairson.[42]Indiana University's introductory class, C211, is taught entirely in Scheme. A self-paced version of the course, CS 61AS, continues to use Scheme.[43] The introductory computer science courses atYale andGrinnell College are also taught in Scheme.[44] The former introductory computer science course at the University of Minnesota - Twin Cities, CSCI 1901, also used Scheme as its primary language, followed by a course that introduced students to the Java language;[45] however, following the example of MIT, the department replaced 1901 with the Python-based CSCI 1133,[46] while functional programming is covered in detail in the third-semester course CSCI 2041.[47]
Guile has been adopted byGNU project as its official scripting language, and that implementation of Scheme is embedded in such applications asGNU LilyPond andGnuCash as a scripting language for extensions. Likewise, Guile used to be the scripting language for thedesktop environmentGNOME,[50] and GNOME still has a project that provides Guile bindings to its library stack.[51] There is a project to incorporate Guile intoGNU Emacs, GNU's flagship program, replacing the currentEmacs Lisp interpreter.[citation needed]
Shiro Kawai, senior programmer on the movieFinal Fantasy: The Spirits Within, used Scheme as a scripting language for managing the real-time rendering engine.[53]
^Common LISP: The Language, 2nd Ed., Guy L. Steele Jr. Digital Press; 1981.ISBN978-1-55558-041-4. "Common Lisp is a new dialect of Lisp, a successor to MacLisp, influenced strongly by ZetaLisp and to some extent by Scheme and InterLisp."
^ab1178-1990 (Reaff 2008) IEEE Standard for the Scheme Programming Language. IEEE part number STDPD14209,unanimously reaffirmed at a meeting of the IEEE-SA Standards Board Standards Review Committee (RevCom), March 26, 2008 (item 6.3 on minutes), reaffirmation minutes accessed October 2009. This document is available from IEEE for purchase only, and not online at time of writing: 2009.
^abcdSussman, Gerald Jay; Steele, Guy L. (1 December 1998). "The First Report on Scheme Revisited".Higher-Order and Symbolic Computation.11 (4):399–404.doi:10.1023/A:1010079421970.S2CID7704398.
^abWill Clinger, Marc Feeley, Chris Hanson, Jonathan Rees and Olin Shivers (2009-08-20)."Position Statement(draft)". Scheme Steering Committee. Retrieved2012-08-09.{{cite web}}: CS1 maint: multiple names: authors list (link)
^Will Clinger (2013-05-10)."extension of voting period". Scheme Language Steering Committee, scheme-reports mailing list. Archived fromthe original on 2013-07-21. Retrieved2013-07-07.
^TheScheme 48 implementation is so-named because the interpreter was written by Richard Kelsey and Jonathan Rees in 48 hours (August 6th – 7th, 1986. SeeRichard Kelsey; Jonathan Rees; Mike Sperber (2008-01-10)."The Incomplete Scheme 48 Reference Manual for release 1.8". Jonathan Rees, s48.org. Retrieved2012-08-09.
^Joel Moses (June 1970),The Function of FUNCTION in LISP, or Why the FUNARG Problem Should Be Called the Environment Problem,hdl:1721.1/5854,AI Memo 199,A useful metaphor for the difference between FUNCTION and QUOTE in LISP is to think of QUOTE as a porous or an open covering of the function since free variables escape to the current environment. FUNCTION acts as a closed or nonporous covering (hence the term "closure" used by Landin). Thus we talk of "open" Lambda expressions (functions in LISP are usually Lambda expressions) and "closed" Lambda expressions. [...] My interest in the environment problem began while Landin, who had a deep understanding of the problem, visited MIT during 1966-67. I then realized the correspondence between the FUNARG lists which are the results of the evaluation of "closed" Lambda expressions inLISP andISWIM's Lambda Closures.
^J.W. Backus; F.L. Bauer; J.Green; C. Katz; J. McCarthy P. Naur; et al. (January–April 1960)."Revised Report on the Algorithmic Language Algol 60".Numerische Mathematik, Communications of the ACM, and Journal of the British Computer Society. Retrieved2012-08-09.
^John DeNero (Fall 2019)."Computer Science 61A, Berkeley". Department of Electrical Engineering and Computer Sciences, Berkeley. Archived fromthe original on 2020-11-11. Retrieved2019-12-17.
^"The major scripting language for the GIMP that has been attached to it today is Scheme." FromDov Grobgeld (2002)."The GIMP Basic Scheme Tutorial". The GIMP Team. Retrieved2012-08-09.