Take the 2-minute tour ×

I'm trying to define a macro that generates an anonymous function taking one argument named it, for succinctness, so that instead of

(λ (it) body)
I can write
(λλ body)

(In other words, (λλ body) transforms to (λ (it) body))

(define-syntax-parameter it #f)
(define-syntax λλ
  (syntax-rules ()
    ((_ body)
     (λ (x) (syntax-parameterize ((it x)) body)))))
(λλ (< it 0)) ; For testing

I get operators.rkt:13:28: ?: literal data is not allowed; no #%datum syntax transformer is bound in the transformer environment in: #f at (define-syntax-parameter if #f), but as far as I can tell, this is exactly like the example given in racket's doc for how to use define-syntax-parameter. I can suppress the error by replacing #f with a function (I used member, but not for any real reason), but after doing that, I get operators.rkt:17:38: x: identifier used out of context in: x. What am I doing wrong?

share|improve this question
add comment

2 Answers

You left out the syntax-id-rules part in the example. It's the part that specifies that it should expand to x. Alternatively, you can use make-rename-transformer:

#lang racket
(require racket/stxparam)

(define-syntax-parameter it #f)
(define-syntax λλ
  (syntax-rules ()
    ((_ body)
     (λ (x) (syntax-parameterize ([it (make-rename-transformer #'x)]) body)))))
((λλ (< it 0)) 5)
((λλ (< it 0)) -5)


share|improve this answer
To clarify this further, the thing that the syntax parameter is "bound to" lives at the syntax world -- so you don't want to use x since that's a runtime thing, instead you want to use #'x. But you really want to create a kind of a macro that expands to #'x, and therefore the syntax-id-rules or the more convenient make-rename-transformer shorthand. –  Eli Barzilay Sep 20 '13 at 2:07
add comment

Syntax parameters are not the only way to implement the macro you have in mind. A simpler (IMO) way is to just use datum->syntax to inject the identifier it:

(define-syntax (λλ stx)
  (syntax-case stx ()
    ((_ body ...)
     (with-syntax ((it (datum->syntax stx 'it)))
       #'(λ (it) body ...)))))

To use your example:

(define my-negative? (λλ (< it 0)))
(my-negative? -1)   ;; => #t
share|improve this answer
Actually, I believe this is a fine use of syntax-parameterize. See Barzilay et al.'s "Keeping it Clean" paper. –  stchang Sep 19 '13 at 17:42
Fair enough, I'll soften my wording a bit. I still think it's overkill when datum->syntax will do, but your answer is good (+1). –  Chris Jester-Young Sep 19 '13 at 17:47
I think the key is that you can get non-hygiene in syntax-rules and not have to switch to the heavier syntax-case. –  stchang Sep 19 '13 at 17:48
@stchang That is actually a very good point, and I'll remember that next time before I start telling people "no, you can't break hygiene in syntax-rules". :-P –  Chris Jester-Young Sep 19 '13 at 17:54
argh. ...sorry, but as someone who invested so much effort on explaining why it's a bad idea, it looks like I'm morally obliged to downvote you on this one (for the first time...). The main real (and highlevel) problem with datum->syntax is that it looks like it works, only it can bite you later horribly. It's especially effective at getting bugs that are bad enough to make people go back to the "simple world of defmacro". –  Eli Barzilay Sep 20 '13 at 2:03
show 1 more comment

Your Answer


