Here are some realistic, non-contrived examples where I use macros like thread-through [called build-scene] a lot:
;; Image Number Number -> Image ;; (x0,y0) is where we want to add a branch (define (fork s0 x0 y0) (define xB (x-B x0)) (define yB (y-B y0)) (define xC (x-C x0)) (define yC (y-C y0)) [define A (interior)] [define B (leaf)] [define C (leaf)] (build-scene scene s0 (pin-over scene x0 y0 A) (pin-over scene xB yB B) (pin-over scene xC yC C) (pin-line scene A ct-find B cb-find) (pin-line scene A ct-find C cb-find))) This is an excerpt from HtDP/2e's source code. The function adds a 'fork' to a game tree. I use the function to build sample trees, which then get spliced into the book: ;; -> Image ;; binary trees of n levels (define (3-level-tree) (define height 225) (define y0 (- height 25)) (define xB (x-B 90)) (define yB (y-B y0)) (define xC (x-C xB)) (define yC (y-C yB)) (build-scene s (rectangle (* 2 width) height) (fork s 90 y0) (fork s xB yB) (fork s xC yC))) On Feb 20, 2015, at 11:11 PM, Alexander D. Knauth wrote: > > On Feb 20, 2015, at 10:45 PM, Alexander D. Knauth <alexan...@knauth.org> > wrote: > >> >> On Feb 20, 2015, at 6:56 PM, Don Green <infodeveloper...@gmail.com> wrote: >> >>> I looked in racket documentation and discussion archives for a >>> thread-through function as illustrated below but without success. >>> Any suggestions where I should look? OR please explain that line below only. >>> Looks like it is declaring thread-safe variables x e and any others I care >>> to list. Is that correct? >>> >>> ;Use a macro: >>> (thread-through x e …) >>> == >>> (let* ([x e] …) x) >>> ;—————————— >> >> If you have this macro definition: >> >> (define-simple-macro >> (thread-through x e ...) >> (let* ([x e] ...) x)) > > I probably should start with a simpler example. This: > (thread-through x 1 (add1 x)) > Will evaluate to the same thing as: > (add1 1) > This: > (thread-through x 1 (add1 x) (number->string x)) > Will evaluate to the same thing as: > (number->string (add1 1)) > This: > (thread-through x ‘foo (symbol->string x) (string->list x) (reverse x) > (list->string x)) > Will evaluate to the same thing as: > (list->string (reverse (string->list (symbol->string ‘foo)))) > > And If you wanted to do something like this: > (map first > (sort (map (λ (x) (list x (modulo (expt 11 x) 13))) > '(0 1 2 3 4 5 6 7 8 9 10)) > < #:key second)) > >> >> Then you can do things like this: (contrived example) >> >> (thread-through >> lst '(0 1 2 3 4 5 6 7 8 9 10) >> (map (λ (x) (list x (modulo (expt 11 x) 13))) lst) >> (sort lst < #:key second) >> (map first lst)) ; '(0 7 4 2 3 5 9 8 10 1 6) > > And if you wanted to do something like this: > (let ([tree 0]) > (set! tree (list tree 1 tree)) > (set! tree (list tree 2 tree)) > (set! tree (list tree 3 tree)) > tree) > >> >> And this: (adapted from an example in >> http://docs.racket-lang.org/guide/set_.html#%28part._using-set%21%29) >> >> (thread-through >> tree 0 >> (list tree 1 tree) >> (list tree 2 tree) >> (list tree 3 tree)) ; '(((0 1 0) 2 (0 1 0)) 3 ((0 1 0) 2 (0 1 0))) > > Or if you wanted to do something like this: > (string->bytes/utf-8 (number->string (bytes-length #”foobar”) 16)) > >> >> And this: (adapted from >> http://pkg-build.racket-lang.org/doc/rackjure/index.html#%28part._.Threading_macros%29) >> >> (thread-through >> x #"foobar" >> (bytes-length x) >> (number->string x 16) >> (string->bytes/utf-8 x)) ; #"6" >> >> It has nothing to do with thread-safe variables. >> It is similar in spirit to ~> from rackjure, or -> from clojure, or ~> or >> thrush+ from point-free, if you want to look at those. >> >> >> >> ____________________ >> Racket Users list: >> http://lists.racket-lang.org/users > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users ____________________ Racket Users list: http://lists.racket-lang.org/users