[racket-dev] racket vs. scheme vs. clojure (as it appears to others)

From: Eli Barzilay (eli at barzilay.org)
Date: Fri Apr 29 12:50:16 EDT 2011

8 minutes ago, Danny Yoo wrote:
> >>  "Scheme" is usually a liability when someone used it in school
> >>  years ago (other than with HtDP).
> 
> Small anecdote: I had gone a small presentation at WPI about
> teaching alternative concurrent programming models to
> undergraduates.  The presenter wanted to explore teaching with
> channels and actors.  They chose Google Go as the language to
> explore those models.  I raised the question in the after-session:
> why not use Racket?  The presenter responded with some shock: he had
> no idea Racket supported threads or had channels.

This is completely off-topic wrt the original thread, but IMO having
these tools in Racket means that you can play with them and contrast
various approaches in a better way.  One example I show in my class is
the sieve way of generating prime numbers -- I do that first in lazy
racket:

  (define nats (cons 1 (map add1 nats)))
  (define (divides? n m)
    (zero? (modulo m n)))
  (define (sift n l)
    (filter (lambda (x) (not (divides? n x))) l))
  (define (sieve l)
    (cons (first l) (sieve (sift (first l) (rest l)))))
  (define primes (sieve (rest nats)))

and then I show them a solution that is based on channels which is
more or less a direct translation from Rob Pike's talk at google
(which is why it relies heavily on state in each thread), and then one
more that uses generators.

  ----------------------------------------------------------------------
  #lang racket

  (define-syntax-rule (bg expr ...) (thread (lambda () expr ...)))

  (define nats
    (let ([out (make-channel)])
      (define (loop i) (channel-put out i) (loop (add1 i)))
      (bg (loop 1))
      out))
  (define (divides? n m)
    (zero? (modulo m n)))
  (define (filter pred c)
    (define out (make-channel))
    (define (loop)
      (let ([x (channel-get c)])
        (when (pred x) (channel-put out x))
        (loop)))
    (bg (loop))
    out)
  (define (sift n c)
    (filter (lambda (x) (not (divides? n x))) c))
  (define (sieve c)
    (define out (make-channel))
    (define (loop c)
      (define first (channel-get c))
      (channel-put out first)
      (loop (sift first c)))
    (bg (loop c))
    out)
  (define primes
    (begin (channel-get nats) (sieve nats)))

  (define (take n c)
    (if (zero? n) '() (cons (channel-get c) (take (sub1 n) c))))

  (take 10 primes)
  ----------------------------------------------------------------------

  ----------------------------------------------------------------------
  #lang racket

  (require racket/generator)

  (define nats
    (generator ()
      (letrec ([loop (lambda (i)
                       (yield i)
                       (loop (add1 i)))])
        (loop 1))))
  (define (divides? n m)
    (zero? (modulo m n)))
  (define (filter pred g)
    (generator ()
      (letrec ([loop (lambda ()
                       (let ([x (g)])
                         (when (pred x) (yield x))
                         (loop)))])
        (loop))))
  (define (sift n g)
    (filter (lambda (x) (not (divides? n x))) g))
  (define (sieve g)
    (define (loop g)
      (define first (g))
      (yield first)
      (loop (sift first g)))
    (generator () (loop g)))
  (define primes
    (begin (nats) (sieve nats)))

  (define (take n g)
    (if (zero? n) '() (cons (g) (take (sub1 n) g))))

  (take 10 primes)
  ----------------------------------------------------------------------


-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!



Posted on the dev mailing list.