[plt-scheme] Re: Continuations memory accumulation problem

From: Ciprian Dorin, Craciun (ciprian.craciun at gmail.com)
Date: Mon Mar 15 18:10:00 EDT 2010

    Hey! Only now it struck me what the following code is doing (I
initially thought it's some kind of twisted syntax trickery)... :)

~~~~
(define ((do-when pred? action) s)
    (if (pred? s) (action s) s))
~~~~
    it's equivalent with
~~~~
(define (do-when pred? action)
    (define (__anonymous__ state)
        (if (pred? state) (action state) state))
    __anonymous__)
~~~~

    I have to admit that (PLT) Scheme is very powerful! (I don't
actually thing that this is possible (out of the box) in Common
Lisp...) :)

    And if we are at this chapter, I also want to praise the ones that
have introduced the `for` family of iterations, which (especially
for/list) actually covers most `map` use cases.

    It seems that I never finish learning.

    Ciprian.


On Mon, Mar 15, 2010 at 10:37 PM, Anthony Cowley <acowley at seas.upenn.edu> wrote:
> [... a lot of snip, snip ... ]
>
> Anthony
>
> [... some snip, snip ...]
>
> --------------
>
> #lang scheme
>
> ;; 2D position
> (define-struct pos (x y) #:transparent)
>
> ;; A robot has a position, a heading, and a list of transient actions.
> (define-struct (robot pos) (θ action) #:transparent)
>
> ;; Add a transient action to a robot's state.
> (define ((add-action a) r)
>  (struct-copy robot r (action (cons a (robot-action r)))))
>
> ;; Move a robot straight ahead at unit velocity.
> (define (move-ahead r)
>  (make-robot (+ (pos-x r) (cos (robot-θ r)))
>              (+ (pos-y r) (sin (robot-θ r)))
>              (robot-θ r)
>              (robot-action r)))
>
> ;; Choose a random new heading for a robot.
> (define (assume-random-heading r)
>  (struct-copy robot r (θ (* (random) 2 pi))))
>
> ;; The simulation world has an enemy and a food item.
> (define enemy (make-pos 2 3))
> (define food (make-pos 6 7))
>
> ;; Proximity predicate.
> (define ((near? item dist) robot)
>  (let ((dx (- (pos-x item) (pos-x robot)))
>        (dy (- (pos-y item) (pos-y robot))))
>    (< (sqrt (+ (* dx dx) (* dy dy))) dist)))
>
> (define near-enemy? (near? enemy 5))
> (define near-food? (near? food 2))
>
> ;; If the predicate evaluates to true when applied to a state value,
> ;; return the result of applying the action to that state value.
> ;; Otherwise, return the state value unchanged.
> (define ((do-when pred? action) s) (if (pred? s) (action s) s))
>
> ;; If-then-else combinator for state modification.
> (define ((do-if pred? then else) s) (if (pred? s) (then s) (else s)))
>
> ;; Zap a nearby enemy.
> (define zap (do-when near-enemy? (add-action 'zap)))
>
> ;; Grab a nearby food item.
> (define grab (do-when near-food? (add-action 'grab)))
>
> ;; Move ahead if otherwise unoccupied, but periodically pick a
> ;; random new heading.
> (define wander (do-when (compose null? robot-action)
>                        (do-if (λ (_) (= (random 10) 0))
>                               assume-random-heading
>                               move-ahead)))
>
> ;; Execute the behavior stack. A robot will zap a nearby enemy,
> ;; grab a nearby food item, or just wander around.
> (define (simulate-robot r)
>  (foldl (λ(f r) (f r)) r (list zap grab wander)))
>
> ;; Reset the robot's transient state.
> (define (reset-action r) (struct-copy robot r (action '())))
>
> ;; Draw a robot, and reset its transient actions.
> (define (viz r) (printf "~a~n" r) (reset-action r))
>
> ;; Run a simulation iteration.
> (define (run-simulation robots)
>  (map (compose viz simulate-robot) robots))
>
> (define (test)
>  (let ((robots (list (make-robot 3 3 pi '())
>                      (make-robot 5 6 0 '())
>                      (make-robot 12 11 (* pi 0.5) '()))))
>    (run-simulation robots)))


Posted on the users mailing list.