Discussion:
[racket] thread-through ?
Don Green
2015-02-20 23:56:14 UTC
Permalink
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)
;--------------------
Alexander D. Knauth
2015-02-21 03:45:08 UTC
Permalink
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?
(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))

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 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)))

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.
Alexander D. Knauth
2015-02-21 04:11:33 UTC
Permalink
Post by Alexander D. Knauth
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?
(thread-through x e …)
==
(let* ([x e] …) x)
;——————————
(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))
Post by Alexander D. Knauth
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)
Post by Alexander D. Knauth
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))
Post by Alexander D. Knauth
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.
____________________
http://lists.racket-lang.org/users
____________________
Racket Users li
Matthias Felleisen
2015-02-21 15:17:07 UTC
Permalink
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)))
Post by Alexander D. Knauth
Post by Alexander D. Knauth
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?
(thread-through x e …)
==
(let* ([x e] …) x)
;——————————
(define-simple-macro
(thread-through x e ...)
(let* ([x e] ...) x))
(thread-through x 1 (add1 x))
(add1 1)
(thread-through x 1 (add1 x) (number->string x))
(number->string (add1 1))
(thread-through x ‘foo (symbol->string x) (string->list x) (reverse x) (list->string x))
(list->string (reverse (string->list (symbol->string ‘foo))))
(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))
Post by Alexander D. Knauth
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)
(let ([tree 0])
(set! tree (list tree 1 tree))
(set! tree (list tree 2 tree))
(set! tree (list tree 3 tree))
tree)
Post by Alexander D. Knauth
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)))
(string->bytes/utf-8 (number->string (bytes-length #”foobar”) 16))
Post by Alexander D. Knauth
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.
____________________
http://lists.racket-lang.org/users
____________________
http://lists.racket-lang.org/users
____________________

Loading...