2

I am learning Scheme, and I've read the basics but I still can't figure how to "map" a Java class to Scheme code. Could any of you guys help me out here? I just need someone to show me how this looks in Scheme to grasp the final details and get things going in my head:

public class sumFibonacciValues {
    public static void main(String [] args) {
        int n = 4000000;
        long i2 = 1, i1 = 1, Fibo = 0, temp = 1;
        while(i2 < n) {
            temp = i1 + i2;
            i1 = i2;
            i2 = temp;
            if(i2 % 2 == 0)
                Fibo += i2;
        }
        System.out.println(Fibo);
    }
}
Tsundoku
  • 9,104
  • 29
  • 93
  • 127
  • SO is not a code generation machine. – Andrew Thompson Sep 03 '11 at 11:32
  • I am not asking for code generation, I'm asking for code translation. I can write my own code, but have NEVER written anything like what I post here in Scheme and would like some help to figure how this should go about. – Tsundoku Sep 03 '11 at 11:34
  • I suspect a direct "stateful" mapping to Scheme is possible, but an idiomatic Scheme implementation of this program will look very, very different. My Scheme skills are rusty, so I'm afraid I can't contribute with an answer, but be warned. – Jong Bor Lee Sep 03 '11 at 11:39
  • 1
    You might find http://en.literateprograms.org/Fibonacci_numbers_(Scheme) interesting. – Thorbjørn Ravn Andersen Sep 03 '11 at 11:51
  • make that https://rosettacode.org/wiki/Fibonacci_sequence#Scheme. literateprograms.org had disappeared by now. – Will Ness Jan 21 '22 at 16:01

1 Answers1

10

I wouldn't have answered something that looks so much like homework, but the "idiomatic" comment just begged for a demonstration that it's really not that far. First, a direct translation:

(define (sum-fibonacci-values)
  (define n 4000000)
  (define i2 1)
  (define i1 1)
  (define fibo 0)
  (define temp 1)
  (let loop ()
    (when (< i2 n)
      (set! temp (+ i1 i2))
      (set! i1 i2)
      (set! i2 temp)
      (when (zero? (modulo i2 2)) (set! fibo (+ fibo i2)))
      (loop)))
  (write fibo))

Second, make it "idiomatic", by removing the redundant mutations, and instead just bind new values, and using a tail-recursive loop. Note that this code is still in direct correlation with the original:

(define (sum-fibonacci-values)
  (define n 4000000)
  (let loop ([i2 1] [i1 1] [fibo 0] [temp 1])
    (if (< i2 n)
      (let* ([temp (+ i1 i2)]
             [i1 i2]
             [i2 temp]
             [fibo (if (zero? (modulo i2 2)) (+ fibo i2) fibo)])
        (loop i2 i1 fibo temp))
      fibo)))

Finally, now that the code is clearer, you can see that there are some redundancies. Here's a cleaned up version:

(define (sum-fibonacci-values)
  (define n 4000000)
  (let loop ([i2 1] [i1 1] [fibo 0])
    (if (< i2 n)
      (let ([i3 (+ i1 i2)])
        (loop i3 i2 (if (zero? (modulo i3 2)) (+ fibo i3) fibo)))
      fibo)))

Note that the same cleanup can be done on the Java code. (But that's really left as an exercise to the reader...)

Eli Barzilay
  • 29,301
  • 3
  • 67
  • 110
  • Your answer accurately fits Luis Armando's request of mapping Java to Scheme and hopefully it will be useful for his learning of Scheme. However, I think it is worth pointing out that given the same task (summing the first n even Fibonacci numbers, it seems) and no Java implementation to start with, the resulting Scheme code could have been different, which is the point I was trying to make with my "idiomatic" comment. I admit this may be beyond what Luis Armando requested, though. – Jong Bor Lee Sep 03 '11 at 15:41
  • I know it looks as homework question but it's not I can assure you, I just wanted an example that would require some interesting thinking involved and the first thing that came to my mind was this piece of code I wrote some months ago. Thank you for this, it really helped me get the idea of how to work with Scheme =) – Tsundoku Sep 03 '11 at 15:51