We've now seen all of Scheme's data types: Booleans, characters, numbers, pairs and lists (together with the empty list), procedures, strings, symbols, ports, and vectors. (In Chez Scheme, the end-of-file object is an additional type, but in some versions of Scheme it is implemented as a value of one of the previously listed types.)
Scheme keeps values of these types distinct. However, in a few cases there is a straightforward and useful correspondence between values of different types. For these cases, Scheme provides special conversion procedures which take arguments of one type and return values of the other.
We encountered one pair of conversion procedures back in the lab on characters:
> (char->integer #\L) ;; assuming ASCII characters 76 > (integer->char 114) #\r
A second pair of conversion procedures relates the strings that denote
numbers with the numbers themselves. The string->number
procedure takes as its argument a string containing any Scheme numeral and
returns the number it stands for:
> (string->number "0038") 38 > (string->number (string-append "-32" "." "414")) -32.414 > (string->number (string-append "60/1" "50")) 2/5
The number->string procedure takes any number and returns
a string numeral for it -- the same numeral that would be printed by the
display or write procedure:
> (number->string 60/150) "2/5" > (number->string (* -14/3 35.0)) "-163.33333333333334" > (number->string #e1.5) ;; #e is the exactness prefix "3/2"
What does string->number return if it is given a string
that is not a numeral?
Is there any number n such that (string->number
(number->string n)) is not equal to n?
The remaining pair of standard Scheme conversion procedures relates symbols
and strings. For every Scheme symbol, there is a string that contains the
name of the symbol. The symbol->string procedure computes
and returns this string:
> (symbol->string 'apple) "apple" > (symbol->string (cadr '(alpha beta gamma))) "beta" > (symbol->string 'SAMPLE) "sample"
As the last example shows, each symbol is converted to the ``standard case'' of the particular Scheme implementation (in the case of Chez Scheme, lower case) before being converted to a string.
The string->symbol procedure takes any Scheme string and
returns a symbol that has that string as its name:
> (string->symbol "apple") apple > (string->symbol (substring "amphibian" 2 5)) phi
Some strings are converted into symbols that cannot otherwise be named in Scheme. When printed, these are enclosed in vertical-bar characters to mark them as specials:
> (string->symbol "ALL CAPS") |ALL CAPS| > (string->symbol "5(3)") |5(3)| > (string->symbol "") || > (symbol? (string->symbol "")) #t
Write a Scheme procedure symbol-list->string that takes as
argument a list ls in which every element is a symbol and
returns as value a string that begins with a left parenthesis, ends with a
right parenthesis, and in between contains string representations of all
the symbols in ls, separated by single spaces.
> (symbol-list->string '(alpha beta gamma)) "(alpha beta gamma)" > (symbol-list->string (list 'APPLE 'PEAR 'PEACH 'GRAPE)) "(apple pear peach grape)" > (symbol-list->string '()) "()"
Write the conversion procedure string->symbol-list that
goes in the opposite direction, taking a string and returning a list of
symbols. (If the argument string does not begin with a left parenthesis and
end with a right parenthesis, return instead a single symbol corresponding
to the entire argument string.)
Challenge problem (for students familiar with non-decimal systems of
numeration): Each of the procedures string->number and
number->string takes an optional second argument, which
must be an integer in the range from 2 to 36. If this argument is present,
its value is used as a base of numeration for the string. (That is,
string->number evaluates its argument as a numeral of that
base and number->string constructs and returns a numeral
using that base.) In bases larger than ten, the letters of the alphabet
are used as single digits, with A for ten, B for
eleven, and so on. For instance:
> (number->string 93 8) ;; 93 = (1 * 8^2) + (3 * 8) + 5 "135" > (string->number "7F" 16) ;; 127 = (7 * 16) + 15 127
Write a Scheme procedure decimal->octal that takes as
argument any string that is a base-ten numeral and returns the
octal (base-eight) numeral that has the same numeric value (as a string).
This document is available on the World Wide Web as
http://www.math.grin.edu/courses/Scheme/spring-1998/conversions.html
created November 16, 1997
last revised June 21, 1998