19

Is there any way to make simple reader macros in Racket. I mean a generalization like this:

(define-reader-syntax "'" quote)
; finds expressions that start with "'" and wraps them in `(quote ...)`
'(foo) ; => (quote (foo))
'foo ; => (quote foo)

I used a built in syntax to make clear what I mean. One of the things I'd like to use this for is replicating clojure's shorthand lambda (#(+ 1 %) 5) ; => 6

It seems like it would be very easy to just define a "shorthand-lambda" macro and map the "#" prefix to that.

adrusi
  • 835
  • 1
  • 7
  • 14
  • 1
    You might be interested in looking at the code for [afl](https://github.com/AlexKnauth/afl) or [curly-fn](https://github.com/lexi-lambda/racket-curly-fn), both of which define full implementations of reader extensions for shorthand lambda expressions. – Alex Knauth Jan 10 '16 at 05:48

2 Answers2

17

Here's how to implement your shorthand lambda:

#lang racket

(define rt (make-readtable #f #\# 'non-terminating-macro
                           (λ (c in . _)
                             (define body (read in))
                             `(lambda (%) ,body))))
(parameterize ([current-readtable rt]
               [current-namespace (make-base-namespace)])
  (eval (read (open-input-string "(#(+ 1 %) 5)")))) ;; => 6

Here's how to implement your simpler example, making & be equivalent to ':

(define rt2 (make-readtable #f #\& #\' #f))

(parameterize ([current-readtable rt2]
               [current-namespace (make-base-namespace)])
  (eval (read (open-input-string "&(3 4 5)")))) ;; => '(3 4 5)
Sam Tobin-Hochstadt
  • 4,983
  • 1
  • 21
  • 43
  • In `(λ (c in . _)` from the first example, what is `c`? – adrusi Nov 29 '11 at 23:30
  • 1
    It's the character that triggered the reader macro, in this case always `#\#`. See the documentation for [`make-readtable`](http://pre.racket-lang.org/docs/html/reference/readtables.html#%28def._%28%28quote._~23~25kernel%29._make-readtable%29%29). – Sam Tobin-Hochstadt Nov 30 '11 at 00:01
7

Look at the guide entry on readtables and reader extensions to see how to do this. This reference section is useful too. Readtable extensions are a bit more complicated than your example, but they are very powerful.

For your specific problem, SRFI-26 provides a similar syntax for Scheme and Sam Tobin-Hochstadt wrote a fancy app Racket macro that implements Scala's take on this.

Alexis King
  • 43,109
  • 15
  • 131
  • 205
Asumu Takikawa
  • 8,447
  • 1
  • 28
  • 43