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)