Assignment (computer science)

Last updated

In computer programming, an assignment statement sets and/or re-sets the value stored in the storage location(s) denoted by a variable name; in other words, it copies a value into the variable. In most imperative programming languages, the assignment statement (or expression) is a fundamental construct.

Contents

Today, the most commonly used notation for this operation is x = expr (originally Superplan 1949–51, popularized by Fortran 1957 and C). The second most commonly used notation is [1] x := expr (originally ALGOL 1958, popularised by Pascal). [2] Many other notations are also in use. In some languages, the symbol used is regarded as an operator (meaning that the assignment statement as a whole returns a value). Other languages define assignment as a statement (meaning that it cannot be used in an expression).

Assignments typically allow a variable to hold different values at different times during its life-span and scope. However, some languages (primarily strictly functional languages) do not allow that kind of "destructive" reassignment, as it might imply changes of non-local state. The purpose is to enforce referential transparency, i.e. functions that do not depend on the state of some variable(s), but produce the same results for a given set of parametric inputs at any point in time. Modern programs in other languages also often use similar strategies, although less strict, and only in certain parts, in order to reduce complexity, normally in conjunction with complementing methodologies such as data structuring, structured programming and object orientation.

Semantics

An assignment operation is a process in imperative programming in which different values are associated with a particular variable name as time passes. [1] The program, in such model, operates by changing its state using successive assignment statements. [2] [3] Primitives of imperative programming languages rely on assignment to do iteration. [4] At the lowest level, assignment is implemented using machine operations such as MOVE or STORE. [2] [4]

Variables are containers for values. It is possible to put a value into a variable and later replace it with a new one. An assignment operation modifies the current state of the executing program. [3] Consequently, assignment is dependent on the concept of variables. In an assignment:

Example: Assuming that a is a numeric variable, the assignment a := 2*a means that the content of the variable a is doubled after the execution of the statement.

An example segment of C code:

intx=10;floaty;x=23;y=32.4f;

In this sample, the variable x is first declared as an int, and is then assigned the value of 10. Notice that the declaration and assignment occur in the same statement. In the second line, y is declared without an assignment. In the third line, x is reassigned the value of 23. Finally, y is assigned the value of 32.4.

For an assignment operation, it is necessary that the value of the expression is well-defined (it is a valid rvalue) and that the variable represents a modifiable entity (it is a valid modifiable (non-const) lvalue). In some languages, typically dynamic ones, it is not necessary to declare a variable prior to assigning it a value. In such languages, a variable is automatically declared the first time it is assigned to, with the scope it is declared in varying by language.

Single assignment

Any assignment that changes an existing value (e.g. x := x + 1) is disallowed in purely functional languages. [4] In functional programming, assignment is discouraged in favor of single assignment, more commonly known as initialization. Single assignment is an example of name binding and differs from assignment as described in this article in that it can only be done once, usually when the variable is created; no subsequent reassignment is allowed.

An evaluation of an expression does not have a side effect if it does not change an observable state of the machine, [5] other than producing the result, and always produces same value for the same input. [4] Imperative assignment can introduce side effects while destroying and making the old value unavailable while substituting it with a new one, [6] and is referred to as destructive assignment for that reason in LISP and functional programming, similar to destructive updating.

Single assignment is the only form of assignment available in purely functional languages, such as Haskell, which do not have variables in the sense of imperative programming languages [4] but rather named constant values possibly of compound nature, with their elements progressively defined on-demand, for the lazy languages. Purely functional languages can provide an opportunity for computation to be performed in parallel, avoiding the von Neumann bottleneck of sequential one step at a time execution, since values are independent of each other. [7]

Impure functional languages provide both single assignment as well as true assignment (though true assignment is typically used with less frequency than in imperative programming languages). For example, in Scheme, both single assignment (with let) and true assignment (with set!) can be used on all variables, and specialized primitives are provided for destructive update inside lists, vectors, strings, etc. In OCaml, only single assignment is allowed for variables, via the let name = value syntax; however destructive update can be used on elements of arrays and strings with separate <- operator, as well as on fields of records and objects that have been explicitly declared mutable (meaning capable of being changed after their initial declaration) by the programmer.

Functional programming languages that use single assignment include Clojure (for data structures, not vars), Erlang (it accepts multiple assignment if the values are equal, in contrast to Haskell), F#, Haskell, JavaScript (for constants), Lava, OCaml, Oz (for dataflow variables, not cells), Racket (for some data structures like lists, not symbols), SASL, Scala (for vals), SISAL, Standard ML. Non-backtracking Prolog code can be considered explicit single-assignment, explicit in a sense that its (named) variables can be in explicitly unassigned state, or be set exactly once. In Haskell, by contrast, there can be no unassigned variables, and every variable can be thought of as being implicitly set, when it is created, to its value (or rather to a computational object that will produce its value on demand).

Value of an assignment

In some programming languages, an assignment statement returns a value, while in others it does not.

In most expression-oriented programming languages (for example, C), the assignment statement returns the assigned value, allowing such idioms as x = y = a, in which the assignment statement y = a returns the value of a, which is then assigned to x. In a statement such as while((ch=getchar())!=EOF){}, the return value of a function is used to control a loop while assigning that same value to a variable.

In other programming languages, Scheme for example, the return value of an assignment is undefined and such idioms are invalid.

In Haskell, [8] there is no variable assignment; but operations similar to assignment (like assigning to a field of an array or a field of a mutable data structure) usually evaluate to the unit type, which is represented as (). This type has only one possible value, therefore containing no information. It is typically the type of an expression that is evaluated purely for its side effects.

Variant forms of assignment

Certain use patterns are very common, and thus often have special syntax to support them. These are primarily syntactic sugar to reduce redundancy in the source code, but also assists readers of the code in understanding the programmer's intent, and provides the compiler with a clue to possible optimization.

Augmented assignment

The case where the assigned value depends on a previous one is so common that many imperative languages, most notably C and the majority of its descendants, provide special operators called augmented assignment, like *=, so a = 2*a can instead be written as a *= 2. [3] Beyond syntactic sugar, this assists the task of the compiler by making clear that in-place modification of the variable a is possible.

Chained assignment

A statement like w = x = y = z is called a chained assignment in which the value of z is assigned to multiple variables w, x, and y. Chained assignments are often used to initialize multiple variables, as in

a = b = c = d = f = 0

Not all programming languages support chained assignment. Chained assignments are equivalent to a sequence of assignments, but the evaluation strategy differs between languages. For simple chained assignments, like initializing multiple variables, the evaluation strategy does not matter, but if the targets (l-values) in the assignment are connected in some way, the evaluation strategy affects the result.

In some programming languages (C for example), chained assignments are supported because assignments are expressions, and have values. In this case chain assignment can be implemented by having a right-associative assignment, and assignments happen right-to-left. For example, i = arr[i] = f() is equivalent to arr[i] = f(); i = arr[i]. In C++ they are also available for values of class types by declaring the appropriate return type for the assignment operator.

In Python, assignment statements are not expressions and thus do not have a value. Instead, chained assignments are a series of statements with multiple targets for a single expression. The assignments are executed left-to-right so that i = arr[i] = f() evaluates the expression f(), then assigns the result to the leftmost target, i, and then assigns the same result to the next target, arr[i], using the new value of i. [9] This is essentially equivalent to tmp = f(); i = tmp; arr[i] = tmp though no actual variable is produced for the temporary value.

Parallel assignment

Some programming languages, such as APL, Common Lisp, [10] Go, [11] JavaScript (since 1.7), PHP, Maple, Lua, occam 2, [12] Perl, [13] Python, [14] REBOL, Ruby, [15] and PowerShell allow several variables to be assigned in parallel, with syntax like:

a, b := 0, 1

which simultaneously assigns 0 to a and 1 to b. This is most often known as parallel assignment; it was introduced in CPL in 1963, under the name simultaneous assignment, [16] and is sometimes called multiple assignment, though this is confusing when used with "single assignment", as these are not opposites. If the right-hand side of the assignment is a single variable (e.g. an array or structure), the feature is called unpacking [17] or destructuring assignment: [18]

var list := {0, 1} a, b := list

The list will be unpacked so that 0 is assigned to a and 1 to b. Furthermore,

a, b := b, a

swaps the values of a and b. In languages without parallel assignment, this would have to be written to use a temporary variable

var t := a a := b b := t

since a := b; b := a leaves both a and b with the original value of b.

Some languages, such as Go, F# and Python, combine parallel assignment, tuples, and automatic tuple unpacking to allow multiple return values from a single function, as in this Python example,

deff():return1,2a,b=f()

while other languages, such as C# and Rust, shown here, require explicit tuple construction and deconstruction with parentheses:

// Valid C# or Rust syntax(a,b)=(b,a);
// C# tuple return(string,int)f()=>("foo",1);var(a,b)=f();
// Rust tuple returnletf=||("foo",1);let(a,b)=f();

This provides an alternative to the use of output parameters for returning multiple values from a function. This dates to CLU (1974), and CLU helped popularize parallel assignment generally.

C# additionally allows generalized deconstruction assignment with implementation defined by the expression on the right-hand side, as the compiler searches for an appropriate instance or extension Deconstruct method on the expression, which must have output parameters for the variables being assigned to. [19] For example, one such method that would give the class it appears in the same behavior as the return value of f() above would be

voidDeconstruct(outstringa,outintb){a="foo";b=1;}

In C and C++, the comma operator is similar to parallel assignment in allowing multiple assignments to occur within a single statement, writing a = 1, b = 2 instead of a, b = 1, 2. This is primarily used in for loops, and is replaced by parallel assignment in other languages such as Go. [20] However, the above C++ code does not ensure perfect simultaneity, since the right side of the following code a = b, b = a+1 is evaluated after the left side. In languages such as Python, a, b = b, a+1 will assign the two variables concurrently, using the initial value of a to compute the new b.

Assignment versus equality

The use of the equals sign = as an assignment operator has been frequently criticized, due to the conflict with equals as comparison for equality. This results both in confusion by novices in writing code, and confusion even by experienced programmers in reading code. The use of equals for assignment dates back to Heinz Rutishauser's language Superplan, designed from 1949 to 1951, and was particularly popularized by Fortran:

A notorious example for a bad idea was the choice of the equal sign to denote assignment. It goes back to Fortran in 1957 [lower-alpha 1] and has blindly been copied by armies of language designers. Why is it a bad idea? Because it overthrows a century old tradition to let “=” denote a comparison for equality, a predicate which is either true or false. But Fortran made it to mean assignment, the enforcing of equality. In this case, the operands are on unequal footing: The left operand (a variable) is to be made equal to the right operand (an expression). x = y does not mean the same thing as y = x. [21]

Niklaus Wirth, Good Ideas, Through the Looking Glass

Beginning programmers sometimes confuse assignment with the relational operator for equality, as "=" means equality in mathematics, and is used for assignment in many languages. But assignment alters the value of a variable, while equality testing tests whether two expressions have the same value.

In some languages, such as BASIC, a single equals sign ("=") is used for both the assignment operator and the equality relational operator, with context determining which is meant. Other languages use different symbols for the two operators. For example:

The similarity in the two symbols can lead to errors if the programmer forgets which form ("=", "==", ":=") is appropriate, or mistypes "=" when "==" was intended. This is a common programming problem with languages such as C (including one famous attempt to backdoor the Linux kernel), [22] where the assignment operator also returns the value assigned (in the same way that a function returns a value), and can be validly nested inside expressions. If the intention was to compare two values in an if statement, for instance, an assignment is quite likely to return a value interpretable as Boolean true, in which case the then clause will be executed, leading the program to behave unexpectedly. Some language processors (such as gcc) can detect such situations, and warn the programmer of the potential error.

Notation

The two most common representations for the copying assignment are equals sign (=) and colon-equals (:=). Both forms may semantically denote either an assignment statement or an assignment operator (which also has a value), depending on language and/or usage.

variable = expression Fortran, PL/I, C (and descendants such as C++, Java, etc.), Bourne shell, Python, Go (assignment to pre-declared variables), R, PowerShell, Nim, etc.
variable := expression ALGOL (and derivatives), Simula, CPL, BCPL, Pascal [23] (and descendants such as Modula), Mary, PL/M, Ada, Smalltalk, Eiffel, [24] [25] Oberon, Dylan, [26] Seed7, Python (an assignment expression), [27] Go (shorthand for declaring and defining a variable), [28] Io, AMPL, ML (assigning to a reference value), [29] AutoHotkey etc.

Other possibilities include a left arrow or a keyword, though there are other, rarer, variants:

variable << expression Magik
variable <- expression F#, OCaml, R, S
variable <<- expression R
assign("variable", expression) R
variableexpression APL, [30] Smalltalk, BASIC Programming
variable =: expression J
LET variable = expression BASIC
let variable := expression XQuery
set variable to expression AppleScript
set variable = expression C shell
Set-Variable variable(expression) PowerShell
variable : expression Macsyma, Maxima, K
variable: expression Rebol
var variableexpression mIRC scripting language
reference-variable :- reference-expression Simula

Mathematical pseudo code assignments are generally depicted with a left-arrow.

Some platforms put the expression on the left and the variable on the right:

MOVE expression TO variable COBOL
expressionvariable TI-BASIC, Casio BASIC
expression -> variable POP-2, BETA, R
put expression into variable LiveCode
PUT expression IN variable ABC

Some expression-oriented languages, such as Lisp [31] [32] and Tcl, uniformly use prefix (or postfix) syntax for all statements, including assignment.

(setf variableexpression) Common Lisp
(set! variableexpression) Scheme [33] [34] [35]
set variableexpression Tcl
expressionvariable ! Forth

See also

Notes

  1. Use of = predates Fortran, though it was popularized by Fortran.

Related Research Articles

In computer science, functional programming is a programming paradigm where programs are constructed by applying and composing functions. It is a declarative programming paradigm in which function definitions are trees of expressions that map values to other values, rather than a sequence of imperative statements which update the running state of the program.

<span class="mw-page-title-main">Lisp (programming language)</span> Programming language family

Lisp is a family of programming languages with a long history and a distinctive, fully parenthesized prefix notation. Originally specified in the late 1950s, it is the second-oldest high-level programming language still in common use, after Fortran. Lisp has changed since its early days, and many dialects have existed over its history. Today, the best-known general-purpose Lisp dialects are Common Lisp, Scheme, Racket, and Clojure.

<span class="mw-page-title-main">Python (programming language)</span> General-purpose programming language

Python is a high-level, general-purpose programming language. Its design philosophy emphasizes code readability with the use of significant indentation.

In computer science, syntactic sugar is syntax within a programming language that is designed to make things easier to read or to express. It makes the language "sweeter" for human use: things can be expressed more clearly, more concisely, or in an alternative style that some may prefer. Syntactic sugar is usually a shorthand for a common operation that could also be expressed in an alternate, more verbose, form: The programmer has a choice of whether to use the shorter form or the longer form, but will usually use the shorter form since it is shorter and easier to type and read.

In computer science, an operation, function or expression is said to have a side effect if it has any observable effect other than its primary effect of reading the value of its arguments and returning a value to the invoker of the operation. Example side effects include modifying or reading a non-local variable, a static local variable or a mutable argument passed by reference; raising errors or exceptions; performing I/O; or calling other functions with side-effects. In the presence of side effects, a program's behaviour may depend on history; that is, the order of evaluation matters. Understanding and debugging a function with side effects requires knowledge about the context and its possible histories. Side effects play an important role in the design and analysis of programming languages. The degree to which side effects are used depends on the programming paradigm. For example, imperative programming is commonly used to produce side effects, to update a system's state. By contrast, declarative programming is commonly used to report on the state of system, without side effects.

In computer science, control flow is the order in which individual statements, instructions or function calls of an imperative program are executed or evaluated. The emphasis on explicit control flow distinguishes an imperative programming language from a declarative programming language.

In computer programming, the scope of a name binding is the part of a program where the name binding is valid; that is, where the name can be used to refer to the entity. In other parts of the program, the name may refer to a different entity, or to nothing at all. Scope helps prevent name collisions by allowing the same name to refer to different objects – as long as the names have separate scopes. The scope of a name binding is also known as the visibility of an entity, particularly in older or more technical literature—this is in relation to the referenced entity, not the referencing name.

In programming languages, a closure, also lexical closure or function closure, is a technique for implementing lexically scoped name binding in a language with first-class functions. Operationally, a closure is a record storing a function together with an environment. The environment is a mapping associating each free variable of the function with the value or reference to which the name was bound when the closure was created. Unlike a plain function, a closure allows the function to access those captured variables through the closure's copies of their values or references, even when the function is invoked outside their scope.

In combinatory logic for computer science, a fixed-point combinator, is a higher-order function that returns some fixed point of its argument function, if one exists.

In computer programming, a parameter or a formal argument is a special kind of variable used in a subroutine to refer to one of the pieces of data provided as input to the subroutine. These pieces of data are the values of the arguments with which the subroutine is going to be called/invoked. An ordered list of parameters is usually included in the definition of a subroutine, so that, each time the subroutine is called, its arguments for that call are evaluated, and the resulting values can be assigned to the corresponding parameters.

<span class="mw-page-title-main">Conditional (computer programming)</span> Control flow statement that executes code according to some condition(s)

In computer science, conditionals are programming language commands for handling decisions. Specifically, conditionals perform different computations or actions depending on whether a programmer-defined Boolean condition evaluates to true or false. In terms of control flow, the decision is always achieved by selectively altering the control flow based on some condition . Although dynamic dispatch is not usually classified as a conditional construct, it is another way to select between alternatives at runtime. Conditional statements are the checkpoints in the programme that determines behaviour according to situation.

The equals sign or equal sign, also known as the equality sign, is the mathematical symbol =, which is used to indicate equality in some well-defined sense. In an equation, it is placed between two expressions that have the same value, or for which one studies the conditions under which they have the same value.

In computer programming, the ternary conditional operator is a ternary operator that is part of the syntax for basic conditional expressions in several programming languages. It is commonly referred to as the conditional operator, ternary if, or inline if. An expression a ? b : c evaluates to b if the value of a is true, and otherwise to c. One can read it aloud as "if a then b otherwise c". The form a ? b : c is by far and large the most common, but alternative syntaxes do exist; for example, Raku uses the syntax a ?? b !! c to avoid confusion with the infix operators ? and !, whereas in Visual Basic .NET, it instead takes the form If(a, b, c).

In computer programming, a statement is a syntactic unit of an imperative programming language that expresses some action to be carried out. A program written in such a language is formed by a sequence of one or more statements. A statement may have internal components.

In computer science, a programming language is said to have first-class functions if it treats functions as first-class citizens. This means the language supports passing functions as arguments to other functions, returning them as the values from other functions, and assigning them to variables or storing them in data structures. Some programming language theorists require support for anonymous functions as well. In languages with first-class functions, the names of functions do not have any special status; they are treated like ordinary variables with a function type. The term was coined by Christopher Strachey in the context of "functions as first-class citizens" in the mid-1960s.

In computer science, a relational operator is a programming language construct or operator that tests or defines some kind of relation between two entities. These include numerical equality and inequalities.

In computer programming, an anonymous function is a function definition that is not bound to an identifier. Anonymous functions are often arguments being passed to higher-order functions or used for constructing the result of a higher-order function that needs to return a function. If the function is only used once, or a limited number of times, an anonymous function may be syntactically lighter than using a named function. Anonymous functions are ubiquitous in functional programming languages and other languages with first-class functions, where they fulfil the same role for the function type as literals do for other data types.

The greater-than sign is a mathematical symbol that denotes an inequality between two values. The widely adopted form of two equal-length strokes connecting in an acute angle at the right, >, has been found in documents dated as far back as 1631. In mathematical writing, the greater-than sign is typically placed between two values being compared and signifies that the first number is greater than the second number. Examples of typical usage include 1.5 > 1 and 1 > −2. The less-than sign and greater-than sign always "point" to the smaller number. Since the development of computer programming languages, the greater-than sign and the less-than sign have been repurposed for a range of uses and operations.

The null coalescing operator is a binary operator that is part of the syntax for a basic conditional expression in several programming languages, such as : C# since version 2.0, Dart since version 1.12.0, PHP since version 7.0.0., Perl since version 5.10 as logical defined-or, PowerShell since 7.0.0, and Swift as nil-coalescing operator.

References

  1. 1 2 "2cs24 Declarative". www.csc.liv.ac.uk. Archived from the original on 24 April 2006. Retrieved 20 April 2018.
  2. 1 2 3 "Imperative Programming". uah.edu. Archived from the original on 4 March 2016. Retrieved 20 April 2018.
  3. 1 2 3 Ruediger-Marcus Flaig (2008). Bioinformatics programming in Python: a practical course for beginners. Wiley-VCH. pp. 98–99. ISBN   978-3-527-32094-3 . Retrieved 25 December 2010.
  4. 1 2 3 4 5 Crossing borders: Explore functional programming with Haskell Archived November 19, 2010, at the Wayback Machine , by Bruce Tate
  5. Mitchell, John C. (2003). Concepts in programming languages. Cambridge University Press. p. 23. ISBN   978-0-521-78098-8 . Retrieved 3 January 2011.
  6. "Imperative Programming Languages (IPL)" (PDF). gwu.edu. Retrieved 20 April 2018.
  7. John C. Mitchell (2003). Concepts in programming languages. Cambridge University Press. pp. 81–82. ISBN   978-0-521-78098-8 . Retrieved 3 January 2011.
  8. Hudak, Paul (2000). The Haskell School of Expression: Learning Functional Programming Through Multimedia. Cambridge: Cambridge University Press. ISBN   0-521-64408-9.
  9. "7. Simple statements — Python 3.6.5 documentation". docs.python.org. Retrieved 20 April 2018.
  10. "CLHS: Macro SETF, PSETF". Common Lisp Hyperspec. LispWorks. Retrieved 23 April 2019.
  11. The Go Programming Language Specification: Assignments
  12. INMOS Limited, ed. (1988). Occam 2 Reference Manual. New Jersey: Prentice Hall. ISBN   0-13-629312-3.
  13. Wall, Larry; Christiansen, Tom; Schwartz, Randal C. (1996). Perl Programming Language (2 ed.). Cambridge: O´Reilly. ISBN   1-56592-149-6.
  14. Lutz, Mark (2001). Python Programming Language (2 ed.). Sebastopol: O´Reilly. ISBN   0-596-00085-5.
  15. Thomas, David; Hunt, Andrew (2001). Programming Ruby: The Pragmatic Programmer's Guide. Upper Saddle River: Addison Wesley. ISBN   0-201-71089-7.
  16. D.W. Barron et al., "The main features of CPL", Computer Journal6:2:140 (1963). full text (subscription)
  17. "PEP 3132 -- Extended Iterable Unpacking". legacy.python.org. Retrieved 20 April 2018.
  18. "Destructuring assignment". MDN Web Docs. Retrieved 20 April 2018.
  19. "Deconstructing tuples and other types". Microsoft Docs. Microsoft. Retrieved 29 August 2019.
  20. Effective Go: for, "Finally, Go has no comma operator and ++ and -- are statements not expressions. Thus if you want to run multiple variables in a for you should use parallel assignment (although that precludes ++ and --)."
  21. Niklaus Wirth. "Good Ideas, Through the Looking Glass". CiteSeerX   10.1.1.88.8309 .
  22. Corbet (6 November 2003). "An attempt to backdoor the kernel".
  23. Moore, Lawrie (1980). Foundations of Programming with Pascal. New York: John Wiley & Sons. ISBN   0-470-26939-1.
  24. Meyer, Bertrand (1992). Eiffel the Language. Hemel Hempstead: Prentice Hall International(UK). ISBN   0-13-247925-7.
  25. Wiener, Richard (1996). An Object-Oriented Introduction to Computer Science Using Eiffel. Upper Saddle River, New Jersey: Prentice Hall. ISBN   0-13-183872-5.
  26. Feinberg, Neal; Keene, Sonya E.; Mathews, Robert O.; Withington, P. Tucker (1997). Dylan Programming. Massachusetts: Addison Wesley. ISBN   0-201-47976-1.
  27. "PEP 572 Assignment Expressions". python.org. 28 February 2018. Retrieved 4 March 2020.
  28. "The Go Programming Language Specification - The Go Programming Language". golang.org. Retrieved 20 April 2018.
  29. Ullman, Jeffrey D. (1998). Elements of ML Programming: ML97 Edition. Englewood Cliffs, New Jersey: Prentice Hall. ISBN   0-13-790387-1.
  30. Iverson, Kenneth E. (1962). A Programming Language. John Wiley and Sons. ISBN   0-471-43014-5. Archived from the original on 2009-06-04. Retrieved 2010-05-09.
  31. Graham, Paul (1996). ANSI Common Lisp. New Jersey: Prentice Hall. ISBN   0-13-370875-6.
  32. Steele, Guy L. (1990). Common Lisp: The Language. Lexington: Digital Press. ISBN   1-55558-041-6.
  33. Dybvig, R. Kent (1996). The Scheme Programming Language: ANSI Scheme. New Jersey: Prentice Hall. ISBN   0-13-454646-6.
  34. Smith, Jerry D. (1988). Introduction to Scheme. New Jersey: Prentice Hall. ISBN   0-13-496712-7.
  35. Abelson, Harold; Sussman, Gerald Jay; Sussman, Julie (1996). Structure and Interpretation of Computer Programs. New Jersey: McGraw-Hill. ISBN   0-07-000484-6.