Scheme to C++ translations; aid for students learning C++ after Scheme 
Author Message
 Scheme to C++ translations; aid for students learning C++ after Scheme


Quote:


>>as in chapters 9-11 of Springer and Friedman's book, especially chapter 11.

>>Scheme                          approximate C++ code
>>-------------------------------------------------------------
>>(add1 i)                        ++i
>>(sub1 i)                        --i
>This seems to confuse a lot of the people I talk to who are going from
>C++ to Scheme or Scheme to C++.
>(add1 i)                is like             i+1
>(sub1 i)                is like             i-1
>Mostly, my C++ friends who try Scheme think that (add1 i) is i++.  :(
>Please make the difference clear in your document!  :)

Absolutely right.  My mistake.  Thanks for spotting that.

        Gary
--
        229 Atanasoff Hall, Department of Computer Science

        phone: (515) 294-1580 fax: (515) 294-0258 ftp site: ftp.cs.iastate.edu



Sun, 23 Feb 1997 10:22:24 GMT  
 Scheme to C++ translations; aid for students learning C++ after Scheme

Quote:

>as in chapters 9-11 of Springer and Friedman's book, especially chapter 11.

>Scheme                          approximate C++ code
>-------------------------------------------------------------
>(myfunction 3 4)                myfunction(3,4)
>(+ 2 3)                         2 + 3
>(* (+ 2 2) 7)                   (2 + 2) * 7
>(add1 i)                        ++i
>(sub1 i)                        --i

This seems to confuse a lot of the people I talk to who are going from
C++ to Scheme or Scheme to C++.

(add1 i)                is like             i+1
(sub1 i)                is like             i-1
(begin
  (set! i (add1 i))
  i)                    is like             ++i
(let ([old-i i])
  (set! i (add1 i))
  old-i)                is like             i++

Mostly, my C++ friends who try Scheme think that (add1 i) is i++.  :(
Please make the difference clear in your document!  :)

Quote:
>(define add1                    int add1(int x) {
>  (lambda (x)                     return x + 1;
>    (+ x 1)))                   }

Yes, that's it!  :)

        - Amit
--
        o
     --/--
     __\
<|>     \



Sun, 23 Feb 1997 08:28:38 GMT  
 Scheme to C++ translations; aid for students learning C++ after Scheme
Students and educators who have to learn/teach C++ after Scheme,
as is done here at Iowa State, might want to do something like the
following, or adapt it for their use.  It's somewhat specialized for students
who have studied using Springer and Friedman's book: Scheme and the Art
of Programming.

I'm interested in corrections or suggestions on this as well.

-----------------------------------------------------------------------
                  Translations from Scheme into C++

                           Gary T. Leavens
        Department of Computer Science, Iowa State University
                      Ames, Iowa 50011-1040 USA

                 9 May 1994, Revised 23 August 1994

        This translation of Scheme expressions and program fragments
into C++ is intended to ease your transition to C++.
That is, the main idea is to help explain the syntax and semantics of C++
from the perspective of Scheme.

          Unfortunately, programming is more than knowing syntax and semantics,
just as speaking a language like Russian is more than knowing its vocabulary
and grammar. So although a literal translation of Scheme to C++ may be a good
start at writing C++ programs, it is only helpful for *understanding* C++.
A literal translation is *not* a good way to write programs.  (Imagine
trying to translate English into Russian by looking up every word
in a Russian-English dictionary.  No Russian would call that ``Russian''.)
What you need to learn is the *way* in which C++ is typically and best used.
(This is called ``pragmatics''.)  For that you will need your C++ text.

        In particular, you should be aware that iteration is more idiomatic
in C++ than recursion (because C++ is not tail-recursive).  Furthermore,
such iteration is typically expressed using while-loops, not recursion.
For example, consider the following.  It is an example of an iterative
Scheme factorial function on the left, with an idiomatic C++ translation
on the right.  Note that in C++, assignment (set! in Scheme) is written ``=''.
The second assignment statement in the while-loop below has to be second,
otherwise the value of n needed to produce the new value of acc will not
be correct.

Scheme                            C++ code
--------------------------------------------------------------------
(define fact                      int fact (int n) {
  ; TYPE: (-> (integer) integer)    // PRE: n >= 0
  (lambda (n)                       // POST: result is n!
   ; REQUIRES: n >= 0               int acc = 1;
   ; ENSURES: result is n!          while (n != 0) {
   (letrec                            acc = n * acc;
    ((fact-it                         n = n - 1;
      (lambda (n acc)               }
        (if (zero? n)               return acc;
            acc                   }    
            (fact-it                
              (sub1 n)            
              (* n acc))))))      
     (fact-it n 1))))

        You can write something in Scheme more like the C++, using Scheme's
``while-proc'', and it is a good exercise to compare that to the C++ code.
If you are familiar with how to code using ``while-proc'' in Scheme,
by all means think that way for C++; if you are not familiar with
``while-proc'', you will be learning the relevant ideas when you learn
to deal with while-loops in C++.

        In the rest of this note you will find the following:
approximate translations from Scheme to C++ (Section 1),
some more exact but not idiomatic translations (Section 2),
some things that can't be easily translated from Scheme to C++ (Section 3),
an example of how abstract data types are supported in C++ (Section 4),
and an example of how object-oriented idioms are supported in C++ (Section 5).

1. APPROXIMATE TRANSLATIONS TO AID YOUR UNDERSTANDING OF C++

        The following is a table of approximate translations from
Scheme to C++.  Translations that are not exact in more than
just details like naming conventions are indicated by a C++ comment
noting the inexactness.   In this table, one can tell what is a statement
in C++ because a statement either ends in a semicolon (;) or
a right curly brace (}).  Other translations are expressions.

        The presentation of Scheme roughly follows the order in the book
"Scheme and the Art of Programming" by George Springer and Daniel P. Friedman
(1989, McGraw-Hill and MIT Press).  Some of the translations are only
approximate, but this should be a help initially.  A more faithful translation
can often be made by defining C++ functions, and a still more faithful
translation can often be made by defining C++ classes and/or macros,
but that would not be as helpful in learning C++.

        The main semantic difficulty in translating Scheme to C++ is that
while C++ is technically an expression language, its expressions are
weak compared to Scheme's.  Thus you will have to learn
to think in the world of statements and imperative programming,
as in chapters 9-11 of Springer and Friedman's book, especially chapter 11.

Scheme                          approximate C++ code
-------------------------------------------------------------
(myfunction 3 4)                myfunction(3,4)
(+ 2 3)                         2 + 3
(* (+ 2 2) 7)                   (2 + 2) * 7
(add1 i)                        ++i
(sub1 i)                        --i

; a comment                     // a comment

'ten    ; symbols               "ten"           // only approximately the same
(eq? x y)                       x == y          // when x and y are pointers

#t      ; booleans              1               // no boolean type in older C++
#f                              0
(eqv? x y)                      x == y
(and (> x 0) (> z (/ x y)))     (x > 0) && (z > (x/y))
(or (> x 0) (> z (/ x y)))      (x > 0) || (z > (x/y))
(not (< x y))                   !(x < y)

(define ten (+ 5 5))            int ten = 5 + 5;
(define mylist '(a b xyz))      char *myarr[3] = {"a", "b", "xyz"}; // approx.

(define add1                    int add1(int x) {
  (lambda (x)                     return x + 1;
    (+ x 1)))                   }

(if (> x 0)                     if (x > 0) {
 (set! s 1)                       s = 1;
 (set! s 0))                    } else {
                                  s = 0;
                                }

(if (< 0 x)                     if (0 < x) {
  (writeln "x negative"))         cout << "x negative" << endl;
                                }

(cond                           if (f(x) > 0) {
  ((> (f x) 0) (set! s 1))        s = 1;
  ((= (f x) 0) (set! s 0))      } elseif (f(x) == 0) {
  (else (set! s -1)))             s = 0;
                                } else {
                                  s = -1;
                                }

(begin                          {
   (set! x (+ 3 y))               x = 3 + y;
   (writeln "x is" x)             cout << "x is " << x << endl;
   (set! y (+ 3 x)))              y = 3 + x;
                                }

"a string"                      "a string"
(string-length s)               strlen(s)
(string=? s1 s2)                strcmp(s1,s2) == 0
(string-ci=? s1 s2)             strcasecmp(s1,s2) == 0

(error "should be" 5)           cerr << "should be " << 5 << endl;
                                abort();

(let                            {  // only works for statements in the body
  ((pi 3.14159)                   double pi = 3.14159;
   (y (+ 22.567 z)))              double y = 22.567 + z;
  (set! ans (cos (* pi y))))      ans = cos(pi * y);
                                }

(letrec                         // have to declare these first...
  ((odd                         int odd(int i) {
     (lambda (i)                  if (i == 0) {
       (if (= 0 i)                  return 0;
           #f                     } else {
           (even (sub1 i)))))       return even(--i);
   (even                          }
     (lambda (i)                }
       (if (= 0 i)              int even(int i) {
           #t                     if (i == 0) {
           (odd (sub1 i))))))       return 1;
 (odd 227))                       } else {
                                    return odd(--i);
                                  }
                                }
                                // and then where the letrec would be ...
                                  odd(227)

(display "more data? ")         cout << "more data? ";
(set! response (read))          cin >> response;
(write "string with quotes")    cout << "\"string with quotes\"";
(newline)                       cout << endl;

(define v (make-vector 3))      int v[3];   // the usual way in C++
(define my-vec (vector 1 2 3))  int my_vec[3] = {1, 2, 3};
(vector-ref my-vec 2)           my_vec[2]
(vector-set! my-vec i 99)       my_vec[i] = 99

((matrix-ref mat) 3 4)          mat[3][4]

(set! x (+ y 3))                x = y + 3;

(while-proc                     while (i < new_size) {
  (lambda () (< i new-size))      if (i < size) {
  (lambda ()                        res[i] = vec[i];
    (if (< i size)                } else {    
      (vector-set! res i            res[i] = 0;
        (vector-ref vec i))       }
      (vector-set! res i 0))      i = i+1; // or one could write i++; here
    (set! i (add1 i))))         }

(let ((i 0))                    for (int i = 0; i < new_size; i++) {
 (while-proc                      if (i < size) {
  (lambda () (< i new-size))        res[i] = vec[i]
  (lambda ()                      } else {
    (if (< i size)                  res[i] = 0;
      (vector-set! res i          }
        (vector-ref vec i))     }
      (vector-set! res i 0))
    (set! i (add1 i)))))

(case e                         switch (e) {
 ((1 2 3) (set! x 1))             case 1: case 2: case 3:
 ((4 5 6) (set! x 2))               x = 1;
 (else (set! x 3)))                 break;
                                  case 4: case 5: case 6:
                                    x = 2;
...

read more »



Sun, 23 Feb 1997 01:39:45 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. Translations from Scheme to C++ as aid to teaching C++ after Scheme

2. Scheme to C++ translations; aid for students learning C++ after Scheme

3. Eiffel/C++ (was Re: teaching and learning with LISP/Scheme)

4. C++/Smalltalk differences and keys to learning C++

5. Metaprogramming: C++ templates vs Scheme macros?

6. Lambda abstractions in C++ vs. Scheme

7. CLIPS / Scheme from C++

8. Calling Scheme form C++

9. Scheme OO extensions in a C++ environment

10. 10 Reasons Why Scheme is Better Than C/C++

11. Announcement: Header2Scheme 1.3, a C++ FFI generator for Scheme

12. Announcement: Header2Scheme 1.0, a C++ FFI generator for Scheme

 

 
Powered by phpBB® Forum Software