Com S 227 -- Introduction to Computer Programming
A Rosetta Stone for Scheme
Gary T. Leavens
Department of Computer Science, Iowa State University
Ames, Iowa 50011-1040 USA
leavens@cs.iastate.edu
August 8, 1993
This comparison of Scheme program constructs (special forms) and those
in other languages is intended to help those who know one of the other
languages. The presentatation is the same order as in the book
"Scheme and the Art of Programming" by George Springer and Daniel P. Friedman
(1989, McGraw-Hill and MIT Press). Please note that when doing an exercise
from that textbook, you are expected to use only the parts of Scheme that
have been introduced up to that point in the book.
The purpose of this comparison is to help minimize your confusions
as you learn a different way of thinking and a different style of programming.
It probably will NOT help you write Scheme programs by writing them in one
of the other languages and then translating them into Scheme.
The problem is that such a tranlation would involve more knowledge
of programming concepts and semantics than you are likely to have;
in short, it would be very difficult for you. I know this from experience.
One way to see this is the convoluted way that the Scheme spectial forms are
expressed in the other languages; note the use of many auxiliary functions.
Instead it is best to set aside your notions of how to program as best you can.
Later in the course we will relate Scheme programs to how programs are
written in other languages, but in the beginning of the course we will be doing
things that you probably have little experience with.
Don't be mislead into thinking that these comparisons are exact;
they are intended to be suggestive, but often do not generalize well
for the other languages. Also we often conceal the whole truth about
Scheme for the sake of simplicity. Because of this, the other languages
look more powerful than they really are. For example, in Scheme, one can
write (DEFINE x (+ y 5)), but in Pascal one cannot write "const x y+5;".
Similarly, the id function defined in Scheme by (DEFINE id (LAMBDA (x) x))
is polymorphic, but the id functions defined in the other languages only
take integer arguments. There are many more examples of this kind of thing below.
Where there is no equivalent given, there is simply no easy way to translate
from Scheme to the other languages. Direct translations of the kind of programs
you are probably used to are discussed in the text starting in Chapter 11.
The Pascal dialect is ISO Standard Pascal. The C dialect is ANSI C.
The BASIC dialect is Micro-Soft QBasic. The FORTRAN dialect is FORTRAN 77.
Scheme Pascal C BASIC FORTRAN
-----------------------------------------------------------------------
(DEFINE x 3) const x 3; #define x 3 CONST x = 3 PARAMETER (x=3)
(DEFINE id function int id(int x) DEFINT A-Z INTEGER FUNCTION ID(X)
(LAMBDA (x) x)) id(x:Integer) { FUNCTION id (x) INTEGER X
begin return x; id = x ID = X
id := x } END FUNCTION END
end;
(QUOTE name)
'name
(+ 3 4) 3 + 4 3 + 4 3 + 4 3 + 4
(f x y) f(x,y) f(x,y) f (x),(y) f(x,y)
#t true (~0) -1 .TRUE.
#f false 0 0 .FALSE.
"a string" 'a string' "a string" "a string" 'a string'
(LAMBDA (x) x) &id
(COND function (x == 0) DEFINT A-Z INTEGER FUNCTION T(x)
((zero? x) 1) t(x:Integer) ? 1 FUNCTION t (x) INTEGER x
((< 2 x) x) : Integer : ((2 < x) SELECT CASE x IF (x .EQ. 0) THEN
(ELSE (g x)))) begin ? x CASE 0 T = 1
if x = 0 : g(x)) t = 1 ELSE IF (2 .LT. x) THEN
then t := 1 CASE IS > 2 T = X
else if 2 < x t = x ELSE
then t := x CASE ELSE T = G(x)
else t := g(x) t = g(x) ENDIF
end; END SELECT END
(* ... *) END FUNCTION
t(x) ' ... T(x)
t(x)
(IF (zero? x) function (x==0)?1:g(x) DEFINT A-Z INTEGER FUNCTION T2(x)
1 t2(x:Integer) FUNCTION t2 (x) INTEGER x
(g x)) : Integer IF 0 = x IF (x .EQ. 0) THEN
begin THEN t2 = 1 T2 = 1
if x = 0 ELSE t2 = g(x) ELSE
then t2 := 1 END IF T2 = g(x)
else t2 := g(x) END FUNCTION END IF
end; ' ... END
(* ... *) t2(x)
t2(x) T2(x)
(AND function f(ls) > 3 DEFINT A-Z LOGICAL FUNCTION T3(ls)
(> (f ls) 3) t3(ls:List) && g(ls) == 4 FUNCTION t3 INTEGER ls
(= (g ls) 4) : Boolean && h(ls) == 5 (ls AS List) IF .NOT.f(ls).GT. 3 THEN
(= (h ls) 5)) begin IF T3 = .FALSE.
if NOT(f(ls)>3) ELSEIF
not(f(ls) > 3) THEN .NOT. g(ls) .EQ. 4 THEN
then t3 = 0 T3 = .FALSE.
t3 := false ELSEIF ELSE
else if NOT(g(ls)=4) T3 = h(ls) .EQ. 5
not(g(ls) = 4) THEN END IF
then t3 = 0 END
t3 := false ELSE t3 =
else t3 := (h(ls)=5) T3(ls)
h(ls) = 5 END IF
end END FUNCTION
(* ... *) ' ...
t3(ls) t3(ls)
(OR function f(ls) > 3 DEFINT A-Z LOGICAL FUNCTION T4(ls)
(> (f ls) 3) t4(ls:List) || g(ls) == 4 FUNCTION t4 INTEGER ls
(= (g ls) 4) : Boolean || h(ls) == 5 (ls AS List) IF f(ls) .GT. 3 THEN
(= (h ls) 5)) begin IF f(ls) > 3 T4 = .TRUE.
if f(ls) > 3 THEN t4 = -1 ELSEIF g(ls) .EQ. 4 THEN
then t4 := true ELSEIF T4 = .TRUE.
else if g(ls) = 4 ELSE
g(ls) = 4 THEN t4 = 0 T4 = h(ls) .EQ. 5
then t4 := true ELSE t4 = END IF
else t4 := h(ls) = 5 END
h(ls) = 5 END IF
end END FUNCTION T4(ls)
(* ... *) ' ...
t4(ls) t4(ls)
(BEGIN function #include \ DEFINT A-Z INTEGER FUNCTION T5(x,y)
(writeln x y) t5(x,y:Integer) FUNCTION t5(x,y) INTEGER x, y
(+ x y)) : Integer /* ... */ PRINT x,y PRINT 10, x, y
begin printf( t5 = x+y 10 FORMAT I,I
writeln(x,y); "%d %d\n", END FUNCTION T5 = x + y
t5 := x+y x, y), ' ... END
end x+y t5(x),(y) C ...
(* ... *) T5(x,y)
t5(x,y)
(LET function int t6(int x,y) DEFINT A-Z INTEGER FUNCTION T6(x,y)
((x (+ x y)) t6(x,y:Integer){ FUNCTION t6( INTEGER x, y
(y 3)) : Integer return x * y; BYVAL x, y) T6 = x + y
(* x y)) begin } t6 = x * y END
t6 := x * y /* ... */ END FUNCTION
end; t6(x+y,3) ' ... T6(x+y,3)
(* ... *) t6 (x+y),3
t6(x+y,3)
(LETREC function
((fact t7
(LAMBDA (n) : Integer
(IF (< 1 n) function
1 fact(n:Integer)
(fact : Integer
(* n begin
(fact if n < 1
(sub1 n)) then fact := 1
)))))) else fact :=
(fact 6)) n * fact(n-1)
end (* fact *);
begin
fact(6)
end;
(* ... *)
t7
(LAMBDA args
(length args))
(define x 3) var int x = 3; INTEGER x
x: Integer; DATA x/3/
(* ... *)
begin
x := 3;
(* ... *)
(set! x 4) x := 4 x = 4 x = 4 x = 4
(CASE x function int t9(int x) DEFINT A-Z LOGICAL FUNCTION T9(x)
((1 3 5) #t) t9(x:Integer) { FUNCTION t9(x) INTEGER x
((2 4 6) #f) : Boolean switch (x) { SELECT CASE x IF x .EQ. 1 .OR.
(else #t)) begin case 1: CASE 1,3,5 - x .EQ. 3 .OR.
if x < 1 case 3: t9 = -1 - x .EQ. 5 THEN
or x > 6 case 5: CASE 2,4,6 T9 = .TRUE.
then return ~0; t9 = 0 ELSEIF x .EQ. 2 .OR.
t9 := true break; CASE ELSE - x .EQ. 4 .OR.
else case 2: t9 := -1 - x .EQ. 6 THEN
case x case 4: END SELECT T9 = .FALSE.
1,3,5: case 6: ' ... ELSE
t9 := true; return 0; t9(x) T9 = .TRUE.
2,4,6: break; END IF
t9 := false default: END
end return ~0;
end break; T9(x)
(* ... *) }
t9(x) }
/* ... */
t9(x)