[plt-scheme] random walk

From: Ryan Culpepper (ryanc at ccs.neu.edu)
Date: Fri May 29 12:13:25 EDT 2009

Here are a couple comments:

First, there is a difference between a macro and a compile-time 
auxiliary function. If you need to call a function from within a macro 
transformer, then it needs to be defined in the transformer 
(compile-time) environment. For example, your 'step' macro needs the 
*value* returned by 'DIM', so 'DIM' should be a compile-time auxiliary, 
not a macro. In PLT Scheme, you can define compile-time auxiliaries with 
'define-for-syntax':

   (define-for-syntax DIM 2)

or, if you really want it to be a function,

   (define-for-syntax (DIM) 2)

The 'step' transformer also attempts to call 'macro-reduce-map' as if it 
were a function. In that case, you're calling it to get an expression 
that you'll just place in the output. In that case, it makes sense to 
leave 'macro-reduce-map' as a macro, and instead of trying to call it 
like a function, just produce an expression that uses the macro. That 
is, replace this line:

   (macro-reduce-map 0 + #'%step #'d+1&next)

with something like this:

   #'(macro-reduce-map 0 + %step . d+1&next)

--

Second, your code treats syntax-objects-containing-lists as if they were 
the same thing as lists-of-syntax-objects. They are not the same in PLT 
Scheme. Use 'syntax->list' or 'stx->list' to unwrap the outer layer of 
syntaxness before calling, eg, 'map'.

--

Finally, it would probably be easier if you broke the macro into smaller 
parts. If you use 'define-for-syntax' to introduce more auxiliary 
functions, you can test/try them independently (either by writing little 
adapter macros or by writing your tests inside a 'begin-for-syntax' 
block). Each auxiliary function also gives you a place to write down 
exactly what kind of data you've got, and it helps keep track of whether 
you've got a syntax-containing-a-list or a list-of-syntax or whatever.

Ryan



Marijn Schouten (hkBst) wrote:
> Hi,
> 
> I'm trying to write a macro that writes a function that sums the L2-lengths of
> all (random) walks of depth d on a square grid of dimension DIM. In dimension 2
> that function should look like this:
> 
> 
> (define (walk depth)
>   (let step ((d 0) (x 0) (y 0) #;(z 0))
>     (cond ((< d depth)
> 	   (let ((d+1 (+ d 1)))
> 	     (+
> 	      (step d+1 (+ x 1) y)
> 	      (+
> 	       (step d+1 (- x 1) y)
> 	       (+ (step d+1 x (+ y 1))
> 	          (step d+1 x (- y 1))) ))))
> 	  (else
> 	   (+ (* x x) (* y y)) ) )))
> 
> 
> (walk d) starts at the origin, (x,y) = (0,0), and recursively walks a step in
> all 2DIM directions, returning the L2-length when depth d is reached and summing
> all those lengths. It is not hard to prove that (walk depth) is equal to (expt
> (* 2 (DIM)) depth) but this random walk length summer is only the starting point
> for doing more interesting things.
> 
> I'm looking for a macro that will write the `walk' function given the dimension.
> 
> Attached is an attempt that I cannot seem to get working.
> 
> Thanks,
> 
> Marijn
> 
> 
> 
> 
> ------------------------------------------------------------------------
> 
> _________________________________________________
>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme



Posted on the users mailing list.