JavaRanch Home    
 
This page:         last edited 09 September 2014         What's Changed?         Edit

Learn Scheme   

Scheme is a functional language, so it is somewhat similar to Scala, although the syntax is rather different. Everything in Scheme is a function - there are no classes or objects.

A good Scheme implementation written in Java is Kawa. All you need to get started is this jar file.

You'll also want to get a copy of the Scheme Report, which not only describes the language but also contains an introduction: online HTML, zipped HTML files, PDF. A very good introductory textbook for Scheme is Structure and Interpretation of Computer Programs

Scheme question can be asked in the Other Languages forum here at JavaRanch.

An example

To start with, here's a short Scheme program that solves the first problem of Project Euler : If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. Find the sum of all the multiples of 3 or 5 below 1000.

Save the following code in a file called euler1.scm in the same directory where you put the Kawa jar file.

(define (dividableBy3or5? N)
    (or 
        (= 0 (modulo N 3))
        (= 0 (modulo N 5))))

(define (euler1 LIMIT)
    (cond 
        ((< LIMIT 2)
            0)
        ((dividableBy3or5? LIMIT)
            (+ LIMIT (euler1 (- LIMIT 1))))
        (else
            (euler1 (- LIMIT 1)))))
One thing to get used to in Scheme (as in all Lisp-derived languages) is the prefix notation of functions: The operator is listed first, and then the arguments. So "(or A B)" is the same as "A || B" in Java. And "=" is not used for assignments, it is the test for equality. So the first define section is a function called dividableBy3or5? that returns true if the argument is dividable by 3 or 5, and false otherwise.

The second define section is the actual program. It receives a single parameter LIMIT (which -in the above example- would be 1000) and proceeds to test all numbers up to 1000 recursively. cond is like an if-then-elsif in Java; it can have as many conditions as desired, and if none matches, the result of the else clause will be the result of the function.

The following are the commands to start a Kawa session from the command line, load the file we created, evaluate the sums until 10 and 1000, respectively, and then exit Kawa. You need to hit return/enter at the end of each line to have Kawa interpret it.

% java -classpath kawa-1.14.jar kawa.repl 
#|kawa:1|# (load 'euler1.scm)
#|kawa:2|# (euler1 10)
33
#|kawa:3|# (euler1 1000)
234168
#|kawa:4|# (exit)
%
That's close, but not quite there. The result for 10 is 33 - not 23. That's because the recursion starts at 10 inclusively, not exclusively as the problem description states. We can avoid that by introducing a little helper function that starts the calculation at the number below LIMIT. We also move the definitions of dividableBy3or5? and euler1Minus1 inside of euler1; that way they don't clutter up the global namespace, because they're not visible outside of euler1.
(define (euler1 LIMIT) 

    (define (dividableBy3or5? N)
        (or 
            (= 0 (modulo N 3))
            (= 0 (modulo N 5))))

    (define (euler1Minus1 LIMIT)
        (cond 
            ((< LIMIT 2)
                0)
            ((dividableBy3or5? LIMIT)
                (+ LIMIT (euler1Minus1 (- LIMIT 1))))
            (else
                (euler1Minus1 (- LIMIT 1)))))

    (euler1Minus1 (- LIMIT 1)))

More examples

Scheme is particularly well suited for problems that are defined recursively, or that can solved by recursive algorithms. Here are functions that calculate the WikiPedia:Factorial of a number (n!) and the numbers of the WikiPedia:Fibonacci_number sequence.

Note that the fibonacci function is very inefficient, and will become slow very quickly for growing n. But the code mirrors the recursive definition closely, and is thus the "natural" implementation.

(define (factorial n)
  (if (= n 0)
      1
      (* n (factorial (- n 1)))))

(define (fibonacci n)
  (cond ((= n 0) 0)
        ((= n 1) 1)
        (else (+ (fibonacci (- n 1))
                 (fibonacci (- n 2))))))


CategoryLearnSomethingNew

JavaRanchContact us — Copyright © 1998-2014 Paul Wheaton