Professional Documents
Culture Documents
Historical Origins
• The imperative and functional models grew out of work undertaken Alan
Turing, Alonzo Church, Stephen Kleene, Emil Post, etc. ~1930s
• These results led Church to conjecture that any intuitively appealing model
of computing would be equally powerful as well
– the logic programmer writes a set of axioms that allow the computer
to discover a constructive proof for each particular set of inputs
A Review/Overview of Scheme
• As mentioned, Scheme is a particularly elegant Lisp
– Interpreter runs a read-eval-print loop
– Things typed into the interpreter are evaluated (recursively) once
– Anything in parentheses is a function call (unless quoted)
– Parentheses are NOT just grouping, as they are in Algol-family
languages
• Adding a level of parentheses changes meaning
• As mentioned earlier, Scheme is a particularly elegant Lisp
– Interpreter runs a read-eval-print loop
– Things typed into the interpreter are evaluated (recursively) once
– Anything in parentheses is a function call (unless quoted)
– Parentheses are NOT just grouping, as they are in Algol-family
languages
• Adding a level of parentheses changes meaning
(+ 3 4) Þ 7
((+ 3 4))) Þ error
(the ' Þ' arrow means 'evaluates to‘)
• Scheme standard functions (this is not a complete list):
– arithmetic
– boolean operators
– equivalence
– list operators
– symbol?
– number?
– complex?
– real?
– rational?
– integer?
Bindings
A binding associates an identifier with a value or function. You use the let
keyword to bind a name to a value or function.
In program compilation, the point in time when symbolic references to data are
converted into physical machine addresses. See bind. (2) When a variable is
assigned its type (integer, string, etc.) in a programming language. Traditional
compilers and assemblers provide early binding and assign types at compilation.
Lists and Numbers
A list is an ordered collection (of any length) of elements of the same type
Like all Lisp dialects, Scheme provides a wealth of functions to manipulate lists.
EXAMPLE 10.12 We saw many of these in Section 7.8; we do not repeat them all
here. The three
Basic list operations most important are car, which returns the head of a list, cdr
(“coulder”), which
returns the rest of the list (everything after the head), and cons, which joins a
head to the rest of a list:
(car ’(2 3 4)) =⇒ 2
(cdr ’(2 3 4)) =⇒ (3 4)
(cons 2 ’(3 4)) =⇒ (2 3 4)
Also useful is the null? predicate, which determines whether its argument is the
empty list. Recall that the notation ’(2 3 4) indicates a proper list, in which the
final element is the empty list:
(cdr ’(2)) =⇒ ()
(cons 2 3) =⇒ (2 . 3) ; an improper list _
For fast access to arbitrary elements of a sequence, Scheme provides a vector
type that is indexed by integers, like an array, and may have elements of
heterogeneous
types, like a record. Interested readers are referred to the Scheme
manual [SDF+07] for further information. Scheme also provides a wealth of
numeric and logical (Boolean) functions
and special forms Scheme also provides a wealth of numeric and logical (Boolean)
functions
and special forms
EqualityTesting and Searching
We can test certain expressions for equality: -
2 = 1+1;
> val it = true : bool - 1.414*1.414 = 2.0;
> val it = false : bool - [] = [1];
> val it = false : bool
Equality testing can be used with the basic types, and with tuples and lists, but
not with functions. - (fn x => x+2) = (fn x => 2+x);
! Type clash: match rule of type ! ’a -> ’b ! cannot have equality type ’’c
Scheme provides several different equality-testing functions. For numerical
comparisons,= performs type conversions where necessary (e.g., to compare an
integer and a floating-point number). For general-purpose use, eqv? performs
a shallow comparison, while equal? performs a deep (recursive) comparison,
using eqv? at the leaves. The eq? function also performs a shallow comparison,
and may be cheaper than eqv? in certain circumstances (in particular, eq?
is not required to detect the equality of discrete values stored in different
locations,
though it may in some implementations).
Control Flow and Assignment
In computer science, control flow (or flow of control) 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.
Recursion, of course, is the principal means of doing things repeatedly in
Scheme. Many issues related to recursion were discussed in Section 6.6; we do
not repeat that discussion here.
For programmers whowish to make use of side effects, Scheme provides
assignEXAMPLE
10.16 ment, sequencing, and iteration constructs.
the introduction of high-level languages and compilers, much work has been
devoted to approximating, at compile time, which values the variables of a given
program may denote at run time. The problem has been named data-flow
analysis or just flow analysis. In a language without higher-order functions, the
operator of a function call is apparent from the text of the program: it is a lexically
visible identifier and therefore the called function is available at compile time.
One can thus base an analysis for such a language on the textual structure of the
program, since it determines the exact control flow of the program, e.g., as a flow
chart. On the other hand, in a language with higher-order functions, the operator
of a function call may not be apparent from the text of the program: it can be the
result of a computation and therefore the called function may not be available
until run time. A control-flow analysis approximates at compile time which
functions may be applied at run time, i.e., it determines an approximate control
flow of a given program.
Programs as Lists
As should be clear by now, a program in Scheme takes the form of a list. In
technical terms, we say that Lisp and Scheme are homoiconic—self-representing.
A parenthesized string of symbols (in which parentheses are balanced) is called
an S-expression regardless of whether we think of it as a program or as a list. In
fact, an unevaluated program is a list, and can be constructed, deconstructed, and
otherwise manipulated with all the usual list functions.