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! _________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev