[Bese-devel] Bug in UCW Examples: Add some numbers?
Marco Baringer
mb at bese.it
Fri Aug 26 08:12:04 UTC 2005
"Marco Baringer" <mb at bese.it> writes:
> the only way to fix is to use recursion (which gets 'undone' when
> stepping back to a previous continuation):
>
> (defaction start ((s sum))
> (let ((how-many (call 'read-a-number
> :label "How many numbers should we read?")))
> (labels ((sum-numbers (how-many sum)
> (if (zerop how-many)
> ;; all done
> (call 'info-message
> :message (format nil "The sum is: ~D." sum))
> ;; more to go
> (sum-numbers (1- how-many)
> (+ sum (call 'read-a-number))))))
> (sum-numbers how-many 0))))
this is another way to fix the problem. we're using ucw's backtracking
mechanism to work around the fact that continuations don't undo side
effects.
(defaction start ((s sum))
(loop
for how-many = (call 'read-a-number :label "How many numbers should we read?")
initially (backtrack (ucw::context.current-frame *context*) (make-place how-many))
do (loop
for count below how-many
initially (backtrack (ucw::context.current-frame *context*)
(make-place count))
sum (call 'read-a-number) into total
finally (call 'info-message
:message (format nil "The sum is: ~D." total)))))
now that i think about it may be worth the effort, since we've already
got the neccessary infrastructure, to have an action automatically
backtrack all local variables. though this will help in a lot of casse
it will still leave weird edge cases sucha s this one:
(let ((a (cons 1 2)))
(setf (car a) 'foo)
;; the modification to the car of a is not backtracked
)
the only way to fix this would be to use deep copying of all
backtracked places, this sounds like a _horrible_ idea.
--
-Marco
Ring the bells that still can ring.
Forget the perfect offering.
There is a crack in everything.
That's how the light gets in.
-Leonard Cohen
More information about the bese-devel
mailing list