about the define-match-expansion, there are rare materials and example codes to illustrate the concepts. I am having a hard time to "decode" what the documentation says:
(define-match-expander id proc-expr)
(define-match-expander id proc-expr proc-expr)
Binds id to a match expander.
The first proc-expr subexpression must
evaluate to a transformer that
produces a pat for match. Whenever id
appears as the beginning of a pattern,
this transformer is given, at
expansion time, a syntax object
corresponding to the entire pattern
(including id). The pattern is the
replaced with the result of the
transformer.
A transformer produced by a second
proc-expr subexpression is used when
id is used in an expression context.
Using the second proc-expr, id can be
given meaning both inside and outside
patterns.
Can anyone give some example codes to illustrate the two usages of the define-match-expander here?
The idea behind match-expander is that you can extend the 'match' form to handle new pattern forms of your own design.
So, here's a (somewhat pointless) example that defines an "aba" match form that matches patterns of one thing followed by another thing followed by the first thing again (hence, "aba"):
#lang racket
(define-match-expander aba
(lambda (stx)
(syntax-case stx ()
[(_ a b) #'(list a b a)])))
(match '(3 4 3)
[(aba x y) (printf "x = ~a, y = ~a" x y)])
The second form allows you to add a separate expansion to be used outside of match patterns, like this:
#lang racket
(define-match-expander aba
(lambda (stx)
(syntax-case stx ()
[(_ a b) #'(list a b a)]))
(lambda (stx)
#'(error "please don't use aba outside of patterns.")))
(match '(3 4 3)
[(aba x y) (printf "x = ~a, y = ~a\n" x y)])
(aba x y)
Caveat: whuffo the extra pair of parens around the pattern? Not sure, sorry.
This is a really old question, but I'd like to add the example using "syntax-rules" for the same "aba" pattern:
(define-match-expander aba
(syntax-rules ()
[(aba a b) (list a b a)]))
(match '(3 4 3)
[(aba x y) (printf "x = ~a, y = ~a" x y)])
Left-hand side (aba a b) is the thing going in the match, the right-hand side (list a b a) is the substitution.
(match '(3 4 3)
[(aba x y) (printf "x = ~a, y = ~a" x y)])
is replaced by
(match '(3 4 3)
[(list x y x) (printf "x = ~a, y = ~a" x y)])
The nice part is that the new matcher works for ALL "match-whatever" functions, like:
(match-define (aba x y) (list 1 2 1))
(printf "x = ~a, y = ~a" x y
Related
In some dialects of LISP, there is a distinction between SET and SETQ, the first one evaluates its first argument so that you need to use the (SET (QUOTE …) …) syntax.
Since in Racket, quoting is not needed in definitions, define behaves as SETQ.
Is there a Racket function that behaves like SET? If no, how to write one?
I tried (define (SET a b) (define (eval a) b) b) but it does not seem to work when providing it to an other language with (provide SET).
Here's my quick attempt at this problem:
;; lib.rkt
#lang racket/base
(provide (rename-out [#set set]
[##%top #%top]
[#set! set!]
[#define define]))
(require syntax/parse/define)
(define env (make-hash))
(define (set x v stx)
(unless (hash-has-key? env x)
(raise-syntax-error #f "undefined id" stx))
(hash-set! env x v))
(define-simple-macro (##%top . x)
(hash-ref
env
'x
(λ () (raise-syntax-error #f "unbound id" (quote-syntax x)))))
(define (#set x v)
(set x v x))
(define-simple-macro (#set! x:id v)
(set 'x v (quote-syntax x)))
(define-simple-macro (#define x:id v)
(begin
(when (hash-has-key? env 'x)
(raise-syntax-error #f "id already defined" (quote-syntax x)))
(hash-set! env 'x v)))
#lang racket/base
(require "lib.rkt")
(define x 1)
(set (if #t 'x 'y) 2)
(add1 x) ; 3
(set! x 3)
(add1 x) ; 4
(add1 y) ; y: unbound id in: y
Note that this differs from original Racket in several ways. For example:
unbound ids are now reported at runtime instead of compile-time.
set! now won't work with set!-transformer.
define can't be used to define functions
define can't be used to shadow an identifier.
For (2) and (3), it's possible to get the original behavior back, but I don't want the answer to be too long, so I didn't include the full functionality. For now, I don't know how to solve (4).
Also note that you can only set identifiers defined via define. If you want to set identifiers defined via lambda, let, etc., you need to redefine these constructs too.
I would do it much less verbose and much simpler.
Since all arguments are evaluated, the set or let's say define% can be defined as a function!
(define (define% x y)
(eval `(define ,x ,y)))
One can even define functions using define% when using old-style form using lambda.
(define 'ab (lambda (x y) (+ x y)))
(ab 3 5) ;; 7
It even behaves correctly in terms of scope
(define (foo x)
(define% 'bar (lambda (x) (+ 1 x)))
(bar (bar (bar x))))
foo
;; #<procedure:foo>
bar
; bar: undefined;
; cannot reference undefined identifier
; [,bt for context]
(foo 3)
6
;; after first call however, bar is available in global environment
;; as pointed out by #AlexKnauf
bar
;; #<procedure:bar>
Thus there are some scoping issues ...
(let ((x 0))
(define% 'counter (lambda () (set! x (+ x 1)) x)))
counter
;; #<procedure>
(counter)
;; 1
(counter)
;; 2
(counter)
;; 3
I'm trying to write a macro in Common Lisp that takes any number of expressions and builds a list containing each expression followed by its evaluation in a single line. For example, if I name my macro as
(defmacro list-builder (&rest exp)
...)
and I run
(let ((X 1) (Y 2)) (list-builder (+ X Y) (- Y X) X))
I want it to return:
'((+ X Y) 3 (- Y X) 1 X 1)
The best I've been able to do so far is get a list of the expressions using the code
(defmacro list-builder (&rest exp)
`',#`(',exp ,exp))
INPUT: (let ((X 1) (Y 2)) (list-builder (+ X Y) (+ Y X) X))
'((+ X Y) (+ Y X) X)
Strictly speaking, the macro itself cannot do that; what the macro must do is generate code in which the argument expressions are embedded in such a way that they are evaluated, and also in such a way that they are quoted.
Given (list-builder (+ x y) (+ y x) x) we would like to generate this code: (list '(+ x y) (+ x y) '(+ y x) (+ y x) 'x x).
We can split the macro into an top-level wrapper defined with defmacro and an expander function that does the bulk of the work of producing the list arguments; The macro's body just sticks the list symbol on it and returns it.
Macro helper functions have to be wrapped with a little eval-when dance in Common Lisp to make sure they are available in all conceivable situations that the macro might be processed:
(eval-when (:compile-toplevel :load-toplevel :execute)
(defun list-builder-expander (exprs)
(cond
((null exprs) nil)
((atom exprs) (error "list-builder: dotted syntax unsupported":))
(t (list* `',(car exprs) (car exprs)
(list-builder-expander (cdr exprs)))))))
(defmacro list-builder (&rest exprs)
(cons 'list (list-builder-expander exprs)))
A "slick" implementation, all in one defmacro, inside a single backquote expression, might go like this:
(defmacro list-builder (&rest exprs)
`(list ,#(mapcan (lambda (expr) (list `',expr expr)) exprs)))
The "dotted syntax unsupported" check we implemented before now becomes an error out of mapcan.
The lambda turns each expression E into the list ((quote E) E). mapcan catenates these lists together to form the arguments for list, which are then spliced into the (list ...) form with ,#.
The form `',expr follows from applying the quote shorthand to `(quote ,expr).
Of course, a lisp macro can do that. Since lisp macros provide full control over evaluation of their arguments.
You have to use macro helper functions only in cases in which you want to use recursion. Since macros have problems to call themselves recursively.
But by looping over the &rest rest argument, you can generate variadic macros (macros with arbitrary number of arguments) and still control the evaluation of each of its arguments.
After some trial and error cycles (macro construction is an incremental procedure, since macros are complex structures), I obtained the
"simpler" solution:
(defmacro list-builder (&rest rest)
`(list ,#(loop for x in `,rest
nconcing (list `',x x))))
Test by:
(let ((X 1)
(Y 2))
(list-builder (+ X Y) (- Y X) X))
;; ((+ X Y) 3 (- Y X) 1 X 1)
Sometimes, in loop constructs, instead of collect/collecting, use nconc/nconcing in combination with (list ...) to have more control over how the elements are consed together.
The
(list `',x x)
ensures, that the second x gets evaluated, while the first
`',x
places the content of x into the expression, while its quoting prevents the evluation of the expression placed for x.
The outer list in combination with the splicing of the loop construct into it,
finally captures (prevents) the intrinsic very final evaluation of the macro body.
(defmacro list-builder (&rest args)
`(let ((lst ',args)
(acc nil))
(dolist (v lst)
(push v acc)
(push (eval v) acc))
(nreverse acc)))
We could create the list builder macro to take rest parameters as you did (I simply renamed them as args for pseudo code). I'd create a quoted list (lst) of the expressions within the list, and an empty list (acc) to store the expressions and whatever they evaluate to later. Then we can use dolist to iterate through our list and push each expression to the list, followed by whatever it evaluates to by running eval on the expression. Then we can finally use nreverse to get the correct order for the list.
We can then call it:
(let ((x 1)
(y 2))
(declare (special x))
(declare (special y))
(list-builder (+ x y) (- y x) x))
The result will be:
((+ X Y) 3 (- Y X) 1 X 1)
CL-USER>
As an exercise in learning the Racket macro system, I've been implementing a unit testing framework, based on the C++ catch framework. One of the features of that framework is that if I write a check like this:
CHECK(x == y); // (check x y)
When the check is violated the error message will print out the values of x and y, even though the macro used is completely generic, unlike other test frameworks that require you to use macros like CHECK_EQUALS, CHECK_GREATER, etc. This is possible through some hackery involving expression templates and operator overloading.
It occurs to me that in Racket you should be able to do an even better job. In the C++ version the macro can't see inside subexpressions, so if you write something like:
CHECK(f(x, g(y)) == z); // (check (= (f x (g y)) z))
When the check is violated you only find out the values of the left and right hand side of the equal sign, and not the values of x, y, or g(y). In racket I expect it should be possible to recurse into subexpressions and print a tree showing each step of the evaluation.
Problem is I have no idea what the best way to do this is:
I've gotten fairly familiar with syntax-parse, but this seems beyond its abilities.
I read about customizing #%app which almost seems like what I want, but if for example f is a macro, I don't want to print out every evaluation of the expressions that are in the expansion, just the evaluations of the expressions that were visible when the user invoked the check macro. Also not sure if I can use it without defining a language.
I could use syntax-parameterize to hijack the meaning of the basic operators but that won't help with function calls like g(y).
I could use syntax->datum and manually walk the AST, calling eval on subexpressions myself. This seems tricky.
The trace library almost looks like what it does what I want, but you have to give it a list of functions upfront, and it doesn't appear to give you any control over where the output goes (I only want to print anything if the check fails, not if it succeeds, so I need to save the intermediate values to the side as execution proceeds).
What would be the best or at least idiomatic way to implement this?
Here is something to get you started.
#lang racket
(require (for-syntax syntax/parse racket/list))
(begin-for-syntax
(define (expression->subexpressions stx)
(define expansion (local-expand stx 'expression '()))
(syntax-parse expansion
#:datum-literals (#%app quote)
[x:id (list #'x)]
[b:boolean (list #'b)]
[n:number (list #'n)]
; insert other atoms here
[(quote literal) (list #'literal)]
[(#%app e ...)
(cons stx
(append-map expression->subexpressions (syntax->list #'(e ...))))]
; other forms in fully expanded syntax goes here
[else
(raise-syntax-error 'expression->subexpressions
"implement this construct"
stx)])))
(define-syntax (echo-and-eval stx)
(syntax-parse stx
[(_ expr)
#'(begin
(display "] ") (displayln (syntax->datum #'expr))
(displayln expr))]))
(define-syntax (echo-and-eval-subexpressions stx)
(syntax-parse stx
[(_ expr)
(define subs (expression->subexpressions #'expr))
(with-syntax ([(sub ...) subs])
#'(begin
; sub expressions
(echo-and-eval sub)
...
; original expression
(echo-and-eval expr)))]))
(echo-and-eval-subexpressions (+ 1 2 (* 4 5)))
The output:
] (+ 1 2 (* 4 5))
23
] +
#<procedure:+>
] 1
1
] 2
2
] (#%app * '4 '5)
20
] *
#<procedure:*>
] 4
4
] 5
5
] (+ 1 2 (* 4 5))
23
An alternative to printing everything is to add a marker for stuff that should be shown. Here's a rough simple sketch:
#lang racket
(require racket/stxparam)
(define-syntax-parameter ?
(λ(stx) (raise-syntax-error '? "can only be used in a `test' context")))
(define-syntax-rule (test expr)
(let ([log '()])
(define (log! stuff) (set! log (cons stuff log)))
(syntax-parameterize ([? (syntax-rules ()
[(_ E) (let ([r E]) (log! `(E => ,r)) r)])])
(unless expr
(printf "Test failure: ~s\n" 'expr)
(for ([l (in-list (reverse log))])
(for-each display
`(" " ,#(add-between (map ~s l) " ") "\n")))))))
(define x 11)
(define y 22)
(test (equal? (? (* (? x) 2)) (? y)))
(test (equal? (? (* (? x) 3)) (? y)))
which results in this output:
Test failure: (equal? (? (* (? x) 3)) (? y))
x => 11
(* (? x) 3) => 33
y => 22
I'm currently working on an assigment about racket macros. In one of the questions we`re asked to define a macro my-set! which acts like this:
(define x 3)
(define y 5)
(define z 7)
(my-set! (x (+ x y)))
(my-set! (x (+ x y)) (z 6))
x
13
y
5
z
6
I found this interesting document on syntax-case http://www.cs.indiana.edu/~dyb/pubs/tr356.pdf
Currently my macro works but i'm trying to add a "fender" like on page 10 of the document to fend off errors like if one of the variables arent identifiers or anything else.
Here`s my code:
(define-syntax my-set!
(letrec ((all-ids?
(λ (ls)
(or (null? ls)
(and (identifier? (car ls))
(all-ids? (cdr ls)))))))
(lambda (x)
(syntax-case x ()
((_ (var val) (var2 val2) (var3 val3) ...)
(all-ids? (syntax (var var2 var3 ...)))
(syntax (begin (set! var val) (my-set! (var2 val2) (var3 val3) ...))))
((_ (var val))
(syntax (set! var val)))))))
If I test this exact code without the fender, it works perfectly. But when I run this:
(define a 1)
(define b 1)
(define c 1)
(my-set! (a 3) (b 4) (c 5))
I get this:
car: contract violation expected: pair?
given: syntax:C:\Users\mgiroux\Desktop\define-myset.rkt:40:26 (a b c)
Seems like all-ids? cant (car) of (a b c) cause its not a list? I tried passing it as a list but didnt work either, i seem to have copied exactly the way they do it in the pdf I linked.. What am I missing here?
#'(var var2 var3 ...) is indeed not a list. It's a syntax object that wraps a list. You should use syntax->list to extract out the items into a list, thus your guard should look like:
(all-ids? (syntax->list #'(var var2 var3 ...)))
I am writting a script for GIMP and using let* as it was in a sample I took. But it seems to be just a lambda sugar exactly like let. Why are they different? What is the difference between them?
They are different in the order in which variables are bound. Consider this for example:
> (let ((a 1)(b (+ a 2))) b)
This code will FAIL because b requires a, which has not been defined before. It is defined, in the same let, but Scheme will take all your let definitions as only one statement and not allow them to reference each other. In Gambit Scheme, it raises:
*** ERROR IN ##raise-unbound-global-exception -- Unbound variable: a
Conversely, let* will bind the first variable of the let, then the second, etc... so:
> (let* ((a 1)(b (+ a 2))) b)
3
Works as expected.
A third form which is of interest is letrec which lets not only variables in the let reference other variables, but also let them reference themselves (e.g. for recursion). This lets you write code like:
> (letrec ((f (lambda(n) ;; Takes the binary log2 recursively
(cond
((= n 1) 0)
(else (+ 1 (f (/ n 2))))))))
(f 256)) ;; 2^8 = 256
8
If you try to define a recursive function with let or let*, it will tell you the variable is unbound.
All of this can be achieved via clever rearranging/nesting of the let statements, but let* and letrec can be more convenient and readable in some cases like these.
They are different in the way they bind variables. All variables in one let uses the same lambda-form, so you can do this:
(let ((x 10) (y 20))
(let ((x y) (y x))
(display (list x y)))) ; prints (20 10)
While switch the inner let with a let* and you'll se that the second binds towards what was bound in the first binding and not what was before the let*
(let ((x 10) (y 20))
(let* ((x y) (y x))
(display (list x y)))) ; prints (20 20)
the reason for this is that
(let* ((x y) (y x))
...)
is the same as
(let ((x y))
(let ((y x))
...))
let and let* are used for binding variables and both are syntactic sugar (macro), but let* binds variables one after the other soon (from left to right, or from up to down). The difference is also the different scope. In let the scope of each variable is only the expression, not the bindings. In let* the scope of each variable is the expression and the before bindings.
With let* you do such a thing (b a)
...
(let* ((a 1)
(b a))
...)
...
with let you don't.
Implementation of let:
(define-syntax let
(syntax-rules ()
((_ (( variable value ) ...) body ...)
(( lambda (variable ...) body ...) value ...))))
Implementation of let*:
(define-syntax let*
(syntax-rules ()
; pattern for one binding
((_ ((variable value)) body ...)
((lambda (variable) body ...) value))
; pattern for two or more bindings
((_ ((variable value) . other) body ...)
((lambda (variable) (let* other body ...)) value))))