I want to create a Racket macro that includes the functionality of one of the Clojure macros for streaming, but additionally requires an anaphoric argument (for example it), allowing me to specify where each previous value should be inserted in the next function call.
Start with a macro ->>(ported to a circuit or racket), where each call to a new function implicitly inserts the value of the previous function as the last argument:
(define-syntax ->>
(syntax-rules ()
[(_ x) x]
[(_ x (y ...) rest ...)
(->> (y ... x) rest ...)]))
(->> (range 10)
(map add1)
(apply +)
(printf "the sum is: ~a\n"))
; "the sum is: 55"
>> :
, , it
( Clojure ->
).
(define-syntax (>> stx)
(syntax-case stx ()
[(_ x)
[(_ x (y ...) rest ...)
(with-syntax ([it (datum->syntax stx 'it)])
#'(let ([it x])
(>> (y ...) rest ...)))]))
(>> (range 10)
(map add1 it)
(take it 5) ; 'it' is not the last argument
(apply + it))
, 45, 15.
DrRacket , :
(let ([it (range 10)])
(let ([it (map add1 it)])
(let ([it (take it 5)]) (apply + it))))
, it
, (range 10). ,
45 . ?
?
, ,
- :
(require racket/stxparam)
(define-syntax-parameter it
(lambda (stx)
(raise-syntax-error
(define-syntax >>
(syntax-rules ()
[(_ x) x]
[(_ x (y ...) rest ...)
(let ([val x])
(syntax-parameterize ([it (make-rename-transformer
(>> (y ...) rest ...)))]))