[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Message a011267 LONG message - part 2




user can distinguish obj1 and obj2, then eq? will return 
#!false.  On the other hand, it is guaranteed that objects 
maintain their identity despite being fetched from or stored 
into variables or data structures.  

The notion of identity used by eq? is stronger than the notions 
of equivalence used by the eqv? and equal? predicates.  The 
constants #!true and #!false are identical to themselves and are 
different from everything else, except that in some 
implementations the empty list is identical to #!false for 
historical reasons.  Two symbols are identical if they print the 
same way (except that some implementations may have "uninterned 
symbols" that violate this rule).  For structured objects such 
as pairs and vectors the notion of sameness is defined in terms 
of the primitive mutation procedures defined on those objects.  
For example, two pairs are the same if and only if a set-car! 
operation on one changes the car field of the other.  The rules 
for identity of numbers are extremely implementation-dependent 
and should not be relied on.  

Generally speaking, the equal? procedure should be used to 
compare lists, vectors, and arrays.  The string-equal? procedure 
should be used to compare strings, and the =? procedure should 
be used to compare numbers.  The eqv? procedure is just like eq? 
except that it is more inclined to say that two numbers are the 
same.  

        (eq? 'a 'a)                     -->  #!true
        (eq? 'a 'b)                     -->  #!false
        (eq? '(a) '(a))                 -->  unspecified
        (eq? "a" "a")                   -->  unspecified
        (eq? 2 2)                       -->  unspecified
        (eq? (cons 'a 'b) (cons 'a 'b)) -->  #!false
        (let ((x (read)))
          (eq? (cdr (cons 'b x)) x)))   -->  #!true


(eqv? obj1 obj2)                              essential procedure

eqv? is just like eq? except that if obj1 and obj2 are exact 
numbers then eqv? is guaranteed to return #!true if obj1 and 
obj2 are equal according to the =? procedure.  

                (eq? 100000 100000)     -->  unspecified
                (eqv? 100000 100000)    -->  #!true

See section II.6 for a discussion of exact numbers.  


(equal? obj1 obj2)                            essential procedure

Returns #!true if obj1 and obj2 are identical objects or if they 
are equivalent numbers, lists, strings, vectors, or arrays.  Two 
objects are generally considered equivalent if they print the 
same.  equal? may not terminate if its arguments are circular 
data structures.  

        (equal? 'a 'a)                  -->  #!true
        (equal? '(a) '(a))              -->  #!true
        (equal? '(a (b) c) '(a (b) c))  -->  #!true
        (equal? "abc" "abc")            -->  #!true
        (equal? 2 2)                    -->  #!true
        (equal? (make-vector 5 'a)
                (make-vector 5 'a))     -->  #!true

equal? is a blunderbuss of a predicate and should not be used 
when a less liberal or more specific predicate will suffice.  
II.4.  Pairs and lists 


Lists are Lisp's -- and therefore Scheme's -- characteristic 
data structures.  Even Lisp and Scheme programs are lists.  

The empty list is a special object that is written as an opening 
parenthesis followed by a closing parenthesis: 

                               ()

The empty list has no elements, and its length is zero.  The 
empty list is not a pair.  

Larger lists are built out of pairs.  A pair (sometimes called a 
"dotted pair") is a record structure with two fields called the 
car and cdr fields (for historical reasons).  Pairs are created 
by the constructor procedure cons.  The car and cdr fields are 
accessed by the selector procedures car and cdr.  The car and 
cdr fields are assigned by the mutator procedures set-car! and 
set-cdr!.  

The most general notation used for Scheme pairs is the "dotted" 
notation (c1 .  c2) where c1 is the value of the car field and 
c2 is the value of the cdr field.  For example 

                        (4 . 5)

is a pair whose car is 4 and whose cdr is 5.  

The dotted notation is not often used, because more streamlined 
notations exist for the common case where the cdr is the empty 
list or a pair.  (c1 .  ()) is usually written as (c1).  (c1 .  
(c2 .  c3)) is usually written as (c1 c2 .  c3).  Usually these 
special notations permit a structure to be written without any 
dotted pair notation at all.  For example 

                (a . (b . (c . (d . (e . ())))))

would normally be written as                                     

                        (a b c d e)

When all the dots can be made to disappear as in the example 
above, the entire structure is called a proper list.  Proper 
lists are so common that when people speak of a list, they 
usually mean a proper list.  For those who prefer an inductive 
definition: 

        1.  The empty list is a proper list.
        2.  If l is a proper list, then any pair whose cdr is 
            l is also a proper list.
        3.  There are no other proper lists.

A proper list is therefore either the empty list or a pair from 
which the empty list can be obtained by applying the cdr 
procedure a finite number of times.  

Whether a given pair is a proper list depends upon what is 
stored in the cdr field.  When the set-cdr! procedure is used, 
an object can be a proper list one moment and not the next: 

                (define x '(a b c))     -->  x
                (define y x)            -->  y
                (set-cdr! x 4)          -->  unspecified
                x                       -->  (a . 4)
                (eq? x y)               -->  #!true
                y                       -->  (a . 4)

A pair object, on the other hand, will always be a pair object.  


It is often convenient to speak of a homogeneous (proper) list 
of objects of some particular data type, as for example (1 2 3) 
is a list of integers.  To be more precise, suppose D is some 
data type.  (Any predicate defines a data type consisting of 
those objects of which the predicate is true.) Then 

        1.  The empty list is a list of D.
        2.  If l is a list of D, then any pair
            whose cdr is l and whose car satisfies the data
            type D is also a list of D. 
        3.  There are no other lists of D.


(pair? obj)                                   essential procedure

Returns #!true if obj is a pair, otherwise returns #!false.  

                (pair? '(a . b))        -->  #!true
                (pair? '(a b c))        -->  #!true
                (pair? '())             -->  #!false
                (pair? '#(a b))         -->  #!false


(cons obj1 obj2)                              essential procedure

Returns a newly allocated pair whose car is obj1 and whose cdr 
is obj2.  The pair is guaranteed to be different (in the sense 
of eq?) from every existing object.  

                (cons 'a '())           -->  (a)
                (cons '(a) '(b c d))    -->  ((a) b c d)
                (cons "a" '(b c))       -->  ("a" b c)
                (cons 'a 3)             -->  (a . 3)
                (cons '(a b) 'c)        -->  ((a b) . c)


(car pair)                                    essential procedure

Returns the contents of the car field of pair.  pair must be a 
pair.  Note that taking the car of the empty list is an error.  

                (car '(a b c))          -->  a
                (car '((a) b c d))      -->  (a)
                (car '(1 . 2))          -->  1
                (car '())               -->  error


(cdr pair)                                    essential procedure

Returns the contents of the cdr field of pair.  pair must be a 
pair.  Note that taking the cdr of the empty list is an error.  

                (cdr '((a) b c d))      -->  (b c d)
                (cdr '(1 . 2))          -->  2
                (cdr '())               -->  error


(set-car! pair obj)                           essential procedure

Stores obj in the car field of pair.  pair must be a pair.  The 
value returned by set-car! is unspecified.  This procedure can 
be very confusing if used indiscriminately.  


(set-cdr! pair obj)                           essential procedure

Stores obj in the cdr field of pair.  pair must be a pair.  The 
value returned by set-cdr! is unspecified.  This procedure can 
be very confusing if used indiscriminately.  


(caar pair)                                   essential procedure
(cadr pair)                                   essential procedure
(cdar pair)                                   essential procedure
(cddr pair)                                   essential procedure
(caaar pair)                                  essential procedure
(caadr pair)                                  essential procedure
(cadar pair)                                  essential procedure
(caddr pair)                                  essential procedure
(cdaar pair)                                  essential procedure
(cdadr pair)                                  essential procedure
(cddar pair)                                  essential procedure
(cdddr pair)                                  essential procedure
(caaaar pair)                                 essential procedure
(caaadr pair)                                 essential procedure
(caadar pair)                                 essential procedure
(caaddr pair)                                 essential procedure
(cadaar pair)                                 essential procedure
(cadadr pair)                                 essential procedure
(caddar pair)                                 essential procedure
(cadddr pair)                                 essential procedure
(cdaaar pair)                                 essential procedure
(cdaadr pair)                                 essential procedure
(cdadar pair)                                 essential procedure
(cdaddr pair)                                 essential procedure
(cddaar pair)                                 essential procedure
(cddadr pair)                                 essential procedure
(cdddar pair)                                 essential procedure
(cddddr pair)                                 essential procedure

These procedures are compositions of car and cdr, where for 
example caddr could be defined by 

        (define caddr (lambda (x) (car (cdr (cdr x)))))


'()                                            essential constant
#!null                                                   constant

() is the empty list.  The #!null notation does not have to be 
quoted in programs.  The '() notation must include the quote, 
however, because otherwise it would be a procedure call without 
a procedure expression.  

Rationale: Because many current Scheme interpreters deal with 
expressions as list structures rather than as character strings, 
they will treat an unquoted () as though it were quoted.  It is 
entirely possible, however, that some implementations of Scheme 
will be able to detect this error.  


(null? obj)                                   essential procedure

Returns #!true if obj is the empty list, otherwise returns 
#!false.  


(list obj1 ...)                               essential procedure

Returns a list of its arguments.  

        (list 'a (+ 3 4) 'c)            -->  (a 7 c)


(length plist)                                essential procedure

Returns the length of plist, which must be a proper list.  

        (length '())                    -->  0
        (length '(a b c))               -->  3
        (length '(a (b) (c d e)))       -->  3


(append plist1 plist2)                        essential procedure
(append plist ...)                                      procedure

Returns a list consisting of the elements of the first plist 
followed by the elements of the other plists.  All plists should 
be proper lists.  

        (append '(x) '(y))              -->  (x y)
        (append '(a) '(b c d))          -->  (a b c d)
        (append '(a (b)) '((c)))        -->  (a (b) (c))


(append! plist ...)                                     procedure

Like append but may side effect its arguments.  


(reverse plist)                                         procedure

Returns a list consisting of the elements of plist in reverse 
order.  plist must be a proper list.  

        (reverse '(a b c))              -->  (c b a)
        (reverse '(a (b c) d (e (f))))  -->  ((e (f)) d (b c) a)


(list-ref x n)                                          procedure

Returns the car of (list-tail x n).  


(list-tail x n)                                         procedure

Returns the sublist of x obtained by omitting the first n 
elements.  Could be defined by 

        (define list-tail
          (lambda (x n)
            (if (zero? n)
                x
                (list-tail (cdr x) (- n 1)))))


(last-pair x)                                           procedure

Returns the last pair in the nonempty list x.  Could be defined 
by 

        (define last-pair
          (lambda (x)
            (if (pair? (cdr x))
                (last-pair (cdr x))
                x)))


(memq obj plist)                              essential procedure
(memv obj plist)                              essential procedure
(member obj plist)                            essential procedure

Finds the first occurrence of obj in the proper list plist and 
returns the first sublist of plist beginning with obj.  If obj 
does not occur in plist, returns #!false.  memq uses eq? to 
compare obj with the elements of plist, while memv uses eqv? and 
member uses equal?.  

        (memq 'a '(a b c))              -->  (a b c)
        (memq 'b '(a b c))              -->  (b c)
        (memq 'a '(b c d))              -->  #!false
        (memq (list 'a) '(b (a) c))     -->  #!false
        (memq 101 '(100 101 102))       -->  unspecified
        (memv 101 '(100 101 102))       -->  (101 102)
        (member (list 'a) '(b (a) c))   -->  ((a) c)


(assq obj alist)                              essential procedure
(assv obj alist)                              essential procedure
(assoc obj alist)                             essential procedure

alist must be a proper list of pairs.  Finds the first pair in 
alist whose car field is obj and returns that pair.  If no pair 
in alist has obj as its car, returns #!false.  assq uses eq? to 
compare obj with the car fields of the pairs in alist, while 
assv uses eqv? and assoc uses equal?.  

        (assq 'a '((a 1) (b 2) (c 3)))     -->  (a 1)
        (assq 'b '((a 1) (b 2) (c 3)))     -->  (b 2)
        (assq 'd '((a 1) (b 2) (c 3)))     -->  #!false
        (assq '(a) '(((a)) ((b)) ((c))))   -->  #!false
        (assq 5 '((2 3) (5 7) (11 13)))    -->  unspecified
        (assv 5 '((2 3) (5 7) (11 13)))    -->  (5 7)
        (assoc '(a) '(((a)) ((b)) ((c))))   -->  ((a))

Rationale: memq, memv, member, assq, assv, assoc do not have 
question marks in their names because they return useful values 
rather than just #!true.  
II.5.  Symbols 


Symbols are objects whose usefulness rests entirely on the fact 
that two symbols are identical (in the sense of eq?) if and only 
if their names are spelled the same way.  This is exactly the 
property that is needed for identifiers in programs, and so most 
implementations of Scheme use them internally for that purpose.  
Programmers may also use symbols as they use enumerated types in 
Pascal.  

The rules for writing a symbol are the same as the rules for 
writing an identifier (see section I.2).  As with identifiers, 
different implementations of Scheme use slightly different 
rules, but it is always the case that a sequence of characters 
that contains no special characters and begins with a character 
that cannot begin a number is taken to be a symbol; in addition 
+, -, 1+, and -1+ are symbols.  

The case in which a symbol is written in unimportant.  Some 
implementations of Scheme convert any upper case letters to 
lower case, and others convert lower case to upper case.  

It is guaranteed that any symbol that has been read using the 
read procedure and subsequently written out using the write 
procedure will read back in as the identical symbol (in the 
sense of eq?).  The string->symbol procedure, however, can 
create symbols for which the write/read invariance may not hold 
because their names contain special characters or letters in the 
non-standard case.  

Rationale: Some implementations of Lisp have a feature known as 
"slashification" in order to guarantee write/read invariance for 
all symbols, but historically the most important use of this 
feature has been to compensate for the lack of a string data 
type.  Some implementations have "uninterned symbols", which 
defeat write/read invariance even in implementations with 
slashification and also generate exceptions to the rule that two 
symbols are the same if and only if their names are spelled the 
same.  It is questionable whether these features are worth their 
complexity, so they are not standard in Scheme.  


(symbol? obj)                                 essential procedure

Returns #!true is obj is a symbol, otherwise returns #!false.  

                (symbol? 'foo)          -->  #!true
                (symbol? (car '(a b)))  -->  #!true
                (symbol? "bar")         -->  #!false


(symbol->string symbol)                       essential procedure

Returns the name of symbol as a string.  symbol->string performs 
no case conversion.  See string->symbol.  The following examples 
assume the read procedure converts to lower case: 

        (symbol->string 'flying-fish)   -->  "flying-fish"
        (symbol->string 'Martin)        -->  "martin"
        (symbol->string
          (string->symbol "Malvina"))   -->  "Malvina"


(string->symbol string)                       essential procedure

Returns the symbol whose name is string.  string->symbol can 
create symbols with special symbols or upper case letters in 
their names, but it is usually a bad idea to create such symbols 
because in some implementations of Scheme they cannot be read as 
themselves.  See symbol->string.  

    'mISSISSIppi                        -->  mississippi

    (string->symbol "mISSISSIppi")      -->  mISSISSIppi

    (eq? 'bitBlt
         (string->symbol "bitBlt"))     -->  #!false

    (eq? 'JollyWog
         (string->symbol
           (symbol->string 'JollyWog))) -->  #!true

    (string-equal?
      "K. Harper, M.D."
      (symbol->string
        (string->symbol
          "K. Harper, M.D.")))          -->  #!true


II.6.  Numbers (part 1) 


Numerical computation has traditionally been neglected by the 
Lisp community.  Until Common Lisp there has been no carefully 
thought out strategy for organizing numerical computation, and 
with the exception of the MacLisp system there has been little 
effort to execute numerical code efficiently.  We applaud the 
excellent work of the Common Lisp committee and we accept many 
of their recommendations.  In some ways we simplify and 
generalize their proposals in a manner consistent with the 
purposes of Scheme.  

Scheme's numerical operations treat numbers as abstract data, as 
independent of the machine representation as is possible.  Thus, 
the casual user should be able to write simple programs without 
having to know that the implementation may use fixed-point, 
floating-point, and perhaps other representations for his data.  
Unfortunately, this illusion of uniformity can only be sustained 
approximately -- the implementation of numbers will leak out of 
our abstraction whenever the user must be in control of 
precision, or accuracy, or when he must construct especially 
efficient computations.  Thus we also must provide escape 
mechanisms so that a sophisticated programmer can exercise more 
control of the execution of his code and the representation of 
his data when it is essential to do so.  

We separate out several apparently related issues of 
representation -- the abstract numbers, their machine 
representation, and the input/output formats of the symbolic 
expressions which denote numerical constants.  We will use 
mathematical words such as NUMBER, COMPLEX, REAL, RATIONAL, and 
INTEGER for properties of the abstract numbers, data-structure 
names such as FIXNUM, BIGNUM, RATNUM, and FLONUM for machine 
representations, and names like INT, FIX, FLO, SCI, RAT, POLAR, 
and RECT for input/output formats.  

Notations for numbers are the subject of section II.7.  


Numbers.  

A Scheme system provides data of type NUMBER, which is the most 
general numerical type supported by that system.  NUMBER is 
likely to be a complicated union type implemented in terms of 
FIXNUMs, BIGNUMS, FLONUMS, etc.  but this should not be apparent 
to a naive user.  What the user sees is that the obvious 
operations on numbers produce the mathematically expected 
results, within the limits of the implementation.  Thus if the 
user divides 3 by 2, he should get something like 1.5 (or, the 
exact fraction 3/2).  If he adds that result to itself, and if 
the implementation can swing it, he should get an exact 3.  

Mathematically, numbers may be arranged into a tower of subtypes 
with natural projections and injections relating adjacent 
members of the tower: 

                                NUMBER
                                COMPLEX
                                REAL
                                RATIONAL
                                INTEGER

We impose a uniform rule of downward coercion -- a number of one 
type is also of a lower type if the injection (up) of the 
projection (down) of a number leaves the number unchanged.  
Since this tower is a real mathematical entity, Scheme provides 
predicates and procedures that access the tower.  

Not all Scheme implementations must provide the whole tower, but 
they are required to implement a coherent subset, consistent 
with the purposes of Scheme.  


Exactness.  

Numbers are either EXACT or INEXACT.  A number is exact if it 
was derived from EXACT numbers using only EXACT operations.  A 
number is INEXACT if it models a quantity known only 
approximately, if it was derived using INEXACT ingredients, or 
if it was derived using INEXACT operations.  Thus INEXACTness is 
a contagious property of a number.  Some operations, such as the 
square root (of non-square numbers) must be INEXACT because of 
the finite precision of our representations.  Other operations 
are inexact because of implementation requirements.  We 
emphasize that exactness is independent of the position of the 
number on the tower.  It is perfectly possible to have an 
INEXACT INTEGER or an EXACT REAL; 355/113 may be an EXACT 
RATIONAL or it may be an INEXACT RATIONAL approximation to pi, 
depending on the application.  

Operationally, it is the system's responsibility to combine 
EXACT numbers using exact methods, such as infinite precision 
integer and rational arithmetic, where possible.  An 
implementation may not be able to do this (if it does not use 
infinite precision integers and rationals), but if a number 
becomes inexact for implementation reasons there is probably an 
important error condition, such as integer overflow, to be 
reported.  Arithmetic on INEXACT numbers is not so constrained.  
The system may use floating point and other flaky representation 
strategies for INEXACT numbers.  This is not to say that 
implementors need not use the best known algorithms for INEXACT 
computations -- only that high-quality approximate methods are 
allowed.  In a system which cannot explicitly distinguish exact 
from inexact numbers the system must do its best to maintain 
precision.  Scheme systems must not burden users with numerical 
operations described in terms of hardware and operating-system 
dependent representations such as FIXNUM and FLONUM.  These 
representation issues should not be germane to the user's 
problems.  

We highly recommend that the IEEE 32-bit and 64-bit 
floating-point standards be adopted for implementations that use 
floating-point internal representations.  To minimize loss of 
precision we adopt the following rules: If an implementation 
uses several different sizes of floating-point formats, the 
results of any operation with a floating-point result must be 
expressed in the largest format used to express any of the 
floating-point arguments to that operation.  It is desirable 
(but not required) for potentially irrational operations such as 
sqrt, when applied to EXACT arguments, to produce EXACT answers 
when that is possible (eg.  sqrt[4]=2, exactly).  If an EXACT 
number (or an INEXACT number represented as a FIXNUM, a BIGNUM, 
or a RATNUM) is operated upon so as to produce an INEXACT result 
(as by sqrt), and if the result is represented as a FLONUM, then 
the largest available format FLONUM must be used; but if the 
result is expressed as a RATNUM then the rational approximation 
must have at least as much precision as the largest available 
format FLONUM.  (Note that this last rule is much stronger than 
that used in Common Lisp.  Consider the result of the square 
root of a rational, for example.) 


Numerical operations.  

Scheme provides the usual set of operations for manipulating 
numbers.  In general, numerical operations require numerical 
arguments.  For succintness we let the following meta-symbols 
range over the indicated types of object in our descriptions, 
and we let these meta-symbols specify the types of the arguments 
to numeric operations.  It is an error for an operation to be 
presented with an argument that it is not specified to handle.  

  obj                    any arbitrary object
  z, z1, ... zi, ...     complex, real, rational, integer
  x, x1, ... xi, ...     real, rational, integer
  q, q1, ... qi, ...     rational, integer
  n, n1, ... ni, ...     integer


(number? obj)                                 essential procedure
(complex? obj)                                essential procedure
(real? obj)                                   essential procedure
(rational? obj)                               essential procedure
(integer? obj)                                essential procedure

These numerical type predicates can be applied to any kind of 
argument.  They return true if the object is of the named type.  
In general, if a type predicate is true of a number then all 
higher type predicates are also true of that number.  Not every 
system supports all of these types; it is entirely possible to 
have a Scheme system that has only INTEGERs.  Nonetheless every 
implementation of Scheme must have all of these predicates.  


(zero? z)                                     essential procedure
(positive? x)                                 essential procedure
(negative? x)                                 essential procedure
(odd? n)                                      essential procedure
(even? n)                                     essential procedure
(exact? z)                                    essential procedure
(inexact? z)                                  essential procedure

These numerical predicates test a number for a particular 
property.  They return a boolean value.  


(= z1 z2)                                     essential procedure
(=? z1 z2)                                    essential procedure
(= z1 z2 z3 ...)                                        procedure
(=? z1 z2 z3 ...)                                       procedure
(< x1 x2)                                     essential procedure
(<? x1 x2)                                    essential procedure
(< x1 x2 x3 ...)                                        procedure
(<? x1 x2 x3 ...)                                       procedure
(> x1 x2)                                     essential procedure
(>? x1 x2)                                    essential procedure
(> x1 x2 x3 ...)                                        procedure
(>? x1 x2 x3 ...)                                       procedure
(<= x1 x2)                                    essential procedure
(<=? x1 x2)                                   essential procedure
(<= x1 x2 x3 ...)                                       procedure
(<=? x1 x2 x3 ...)                                      procedure
(>= x1 x2)                                    essential procedure
(>=? x1 x2)                                   essential procedure
(>= x1 x2 x3 ...)                                       procedure
(>=? x1 x2 x3 ...)                                      procedure

The numerical comparison predicates have redundant names (with 
and without the terminal "?") to make all populations happy.  
They optionally take many arguments, as in Common Lisp, to 
facilitate range checks.  These procedures return true if their 
arguments are (respectively): numerically equal, monotonically 
increasing, monotonically decreasing, monotonically 
nondecreasing, or monotonically nonincreasing.  Warning: On 
INEXACT numbers equality tests will give unreliable results; 
other numerical comparisons are only heuristically useful (ask a 
numerical analyst about this!).  


(max x1 x2)                                   essential procedure
(max x1 x2 ...)                                         procedure
(min x1 x2)                                   essential procedure
(min x1 x2 ...)                                         procedure

Returns the maximum or minimum of its arguments, respectively.  


(+ z1 z2)                                     essential procedure
(+ z1 ...)                                              procedure
(* z1 z2)                                     essential procedure
(* z1 ...)                                              procedure

These procedures return the sum or product of their arguments.  

                (+ 3 4)                 -->  7
                (+ 3)                   -->  3
                (+)                     -->  0
                (* 4)                   -->  4
                (*)                     -->  1


(- z1 z2)                                     essential procedure
(- z1 z2 ...)                                           procedure
(/ z1 z2)                                     essential procedure
(/ z1 z2 ...)                                           procedure

With two or more arguments, these procedures return the 
difference or (complex) quotient of their arguments, associating 
to the left.  With one argument, however, they return the 
additive or multiplicative inverse of their argument.  

                (- 3 4)                 -->  -1
                (- 3 4 5)               -->  -6
                (- 3)                   -->  -3
                (/ 3 4 5)               -->  3/20
                (/ 3)                   -->  1/3


(1+ z)                                                  procedure
(-1+ z)                                                 procedure

These procedures return the result of adding or subtracting 1 to 
their argument.  


(abs z)                                       essential procedure

Returns the magnitude of its argument.  

                (abs -7)                -->  7
                (abs -3+4i)             -->  5


(quotient n1 n2)                              essential procedure
(remainder n1 n2)                             essential procedure
(modulo n1 n2)                                          procedure

In general, these are intended to implement number-theoretic 
(integer) division, where for positive integers n1 and n2 if n3 
and n4 are integers such that 

               n1 = n3 * n2 + n4 and 0 <= n4 < n2

then 

                (quotient n1 n2)        -->  n3
                (remainder n1 n2)       -->  n4
                (modulo n1 n2)          -->  n4

remainder and modulo differ on negative arguments as do the 
Common Lisp rem and mod procedures -- the remainder always has 
the sign of the dividend, the modulo always has the sign of the 
divisor: 

                (modulo 13 4)           -->  1
                (remainder 13 4)        -->  1

                (modulo -13 4)          -->  3
                (remainder -13 4)       -->  -1

                (modulo 13 -4)          -->  -3
                (remainder 13 -4)       -->  1

                (modulo -13 -4)         -->  -1
                (remainder -13 -4)      -->  -1


(gcd n1 ...)                                            procedure
(lcm n1 ...)                                            procedure

These procedures return the greatest common divisor or least 
common multiple of their arguments.  The arguments to lcm should 
be nonzero.  The result is always non-negative.  

                (gcd 32 -36)            -->  4
                (gcd)                   -->  0
                (lcm 32 -36)            -->  288
                (lcm)                   -->  1


(floor x)                                               procedure
(ceiling x)                                             procedure
(truncate x)                                            procedure
(round x)                                               procedure
(rationalize x y)                                       procedure
(rationalize x)                                         procedure

These procedures create integers and rationals.  Their results 
are not EXACT -- in fact, their results are clearly INEXACT, 
though they can be made EXACT with an explicit exactness 
coercion.  

floor returns the largest integer not larger than x.  ceiling 
returns the smallest integer not smaller than x.  truncate 
returns the integer of maximal absolute value not larger than x.  
round returns the closest integer to x, rounding to even when x 
is halfway between two integers.  With two arguments, 
rationalize produces the best rational approximation to x within 
the tolerance specified by y.  With one argument, rationalize 
produces the best rational approximation to x, preserving all of 
the precision in its representation.  


(exp z)                                                 procedure
(log z)                                                 procedure
(expt z1 z2)                                            procedure
(sqrt z)                                                procedure
(sin z)                                                 procedure
(cos z)                                                 procedure
(tan z)                                                 procedure
(asin z)                                                procedure
(acos z)                                                procedure
(atan z1 z2)                                            procedure           

These procedures are part of every implementation that supports 
real numbers.  Their meanings conform with the Common Lisp 
standard.  (Be careful of the branch cuts if complex numbers are 
allowed.) 


(make-rectangular x1 x2)                                procedure
(make-polar x3 x4)                                      procedure
(real-part z)                                           procedure
(imag-part z)                                           procedure
(magnitude z)                                           procedure
(angle z)                                               procedure

These procedures are part of every implementation that supports 
complex numbers.  Suppose x1, x2, x3, and x4 are real numbers 
and z is a complex number such that 

                 z = x1 + x2 i = x3 * e ^ (x4 i)

Then make-rectangular and make-polar return z, real-part returns 
x1, imag-part returns x2, magnitude returns x3, and angle 
returns x4.  


(exact->inexact z)                                      procedure
(inexact->exact z)                                      procedure

exact->inexact returns an inexact representation of z, which is 
a pretty harmless thing to do.  inexact->exact returns an exact 
representation of z; be sure you know what you are doing here! 
II.7.  Numbers (part 2) 


Numerical Input and Output.  

Scheme allows all of the traditional ways of expressing 
numerical constants, though any particular implementation may 
support only some of them.  These expressions are intended to be 
purely notational; any kind of number may be expressed in any 
form that the user deems convenient.  Of course, expressing 1/7 
as a limited-precision decimal fraction will not exactly express 
the number, but this approximate expression may be just what the 
user wants to see.  

The expressions of numerical constants can be specified using 
formats.  The system provides a procedure, number->string, which 
takes a number and a format and which produces a string which is 
the printed expression of the given number in the given format.  



(number->string number format)                          procedure

This procedure will mostly be used by sophisticated users and in 
system programs.  In general, a naive user will need to know 
nothing about the formats because the system printer will have 
reasonable default formats for all types of NUMBERs.  The system 
reader will construct reasonable default numerical types for 
numbers expressed in each of the formats it recognizes.  If a 
user needs control of the coercion from strings to numbers he 
will use string->number, which takes a string, an exactness, and 
a radix and which produces a number of the maximally precise 
applicable type expressed by the given string.  


(string->number string exactness radix)                 procedure

The exactness is a symbol, either E (for EXACT) or I (for 
INEXACT).  The radix is also a symbol: B for binary, O for 
octal, D for decimal, and X for hexadecimal.  Returns a number 
parsed from the string.  


Formats may have parameters.  For example, the (SCI 5 2) format 
specifies that a number is to be expressed in Fortran scientific 
format with 5 significant places and two places after the radix 
point.  

The following are all numerical constant expressions.  The 
comment shows the format that was used to produce the 
expression: 

    123  +123  -123                    ; (INT)
    12345678901234567890123456789      ; A big one!
    355/113  -355/113  +355/113        ; (RAT)
    +123.45  -123.45                   ; (FIX 2)
    3.14159265358979                   ; (FIX 14)
    3.14159265358979                   ; (FLO 15)
    123.450                            ; (FLO 6)
    -123.45E-1                         ; (SCI 5 2)
    123E3  123E-3  -123E-3             ; (SCI 3 0)
    -1+2i                              ; (RECT (INT) (INT))
    1.2@1.570796                       ; (POLAR (FIX 1) (FLO 7))

A numerical constant may be specified with an explicit radix by 
a prefix.  The prefixes are: #B (binary), #O (octal), #D 
(decimal), #X (hex).  A format may specify that a number be 
expressed in a particular radix.  The radix prefix may be 
suppressed.  For example, one may express a complex number in 
polar form with the magnitude in octal and the angle in decimal 
as follows: 

    #o1.2@#d1.570796327  ; (POLAR (FLO 2 (RADIX O)) (FLO (RADIX D)))
    #o1.2@1.570796327    ; (POLAR (FLO 2 (RADIX O)) (FLO (RADIX D S))

A numerical constant may be specified to be either EXACT or 
INEXACT by a prefix.  The prefixes are: #I (inexact), #E 
(exact).  An exactness prefix may appear before or after any 
radix prefix that is used.  A format may specify that a number 
be expressed with an explicit exactness prefix, or it may force 
the exactness to be suppressed.  For example, the following are 
ways to output an inexact value for pi: 

    #I355/113           ; (RAT (EXACTNESS))
    355/113             ; (RAT (EXACTNESS S))
    #I3.1416            ; (FIX 4 (EXACTNESS))

An attempt to produce more digits than are available in the 
internal machine representation of a number will be marked with 
a "#" filling the extra digits.  This is not a statement that 
the implementation knows or keeps track of the significance of a 
number, just that the machine will flag attempts to produce 20 
digits of a number which has only 15 digits of machine 
representation: 

    3.14158265358979#####       ; (FLO 20 (EXACTNESS S))

In systems with both single and double precision FLONUMs one may 
want to specify which size we want to use to internally 
represent a constant.  For example, we may want a constant that 
is pi rounded to the single precision length, or we might want a 
long number which has the value 6/10.  In either case, we are 
specifying an explicit way to represent an INEXACT number.  For 
this purpose, we allow one to express a number with a prefix 
which indicates short or long FLONUM representation: 

    #S3.14159265358979          ; Round to short -- 3.141593
    #L.6                        ; Extend to long -- .600000000000000



Details of formats.  

The format of a number is notated as a list beginning with a 
format descriptor, such as SCI.  Following the descriptor are 
parameters used by that descriptor, such as the number of 
significant digits to be used.  Parameters which are omitted are 
defaulted.  Next, one may specify modifiers, such as RADIX or 
EXACTNESS, which themselves may be parameterized.  The format 
descriptors are: 

 (INT)
   Express as an integer.  The radix point is implicit.  If there are
   not enough significant places, as in trying to express 6.0238E23
   (internally represented as a 7 digit FLONUM) as an integer we would
   get "6023800################".

 (RAT n)
   Express as a rational fraction.  n specifies the largest
   denominator to be used in constructing a rational approximation to
   the number being expressed.  If n is omitted it defaults to
   infinity. 

 (FIX n)
   Express with a fixed radix point.  n specifies the number of
   places to the right of the radix point.  n defaults to the size of a
   single-precision FLONUM.  If there are not enough significant
   places, as in trying to express 6.0238E23 (internally represented
   as a 7 digit FLONUM) as a (FIX 2) we would get
   "6023800################.##".

 (FLO n) 
   Express with a floating radix point.  n specifies the total number
   of places to be displayed.  n defaults to the size of a single-
   precision FLONUM.  If the number is out of range, it is converted
   to (SCI).  (FLO H) allows the system to heuristically express a FLO
   for human consumption (as in the MacLisp printer).

 (SCI n m)
   Express in exponential notation.  n specifies the total number of
   places to be displayed.  n defaults to the size of a single-
   precision FLONUM.  m specifies the number of places to the right of
   the radix point.  m defaults to n-1.  (SCI H) does heuristic
   expression. 

 (RECT r i)
   Express as a rectangular form complex number.  r and i are formats
   for the real and imaginary parts respectively.  They default to