# New undo/1

**URL:** <https://swi-prolog.discourse.group/t/new-undo-1/3932>\
**Category:** General\
**Created:** [May 9, 2021, 2:05am UTC](https://swi-prolog.discourse.group/t/new-undo-1/3932 "2021-05-09T02:05:32Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![swi](https://avatars.discourse-cdn.com/v4/letter/s/51bf81/32.png) [@swi](https://swi-prolog.discourse.group/u/swi)\
**Post date:** [May 9, 2021, 2:05am UTC](https://swi-prolog.discourse.group/t/new-undo-1/3932/1 "2021-05-09T02:05:32Z")

</div>

I think the new undo/1 is a great feature to have! Alllows much cleaner code when we need side-effects. I had a question, in the test code you have:

```prolog
test(error, throws(x)) :-
    ( undo(throw(x)),
        fail
    ; ok % true is a VMI
    ).

```

why does it make a difference to have `ok` vs `true`?

---

<div class="post-metadata">

**Author:** ![logicmoo](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/logicmoo/32/193_2.png) [@logicmoo](https://swi-prolog.discourse.group/u/logicmoo)\
**Post date:** [May 9, 2021, 2:39am UTC](https://swi-prolog.discourse.group/t/new-undo-1/3932/2 "2021-05-09T02:39:43Z")

</div>

Wow!.. Is `undo/1` already available in SWI?  
All I see is `rdf_edit:undo/1`

-D

---

<div class="post-metadata">

**Author:** ![swi](https://avatars.discourse-cdn.com/v4/letter/s/51bf81/32.png) [@swi](https://swi-prolog.discourse.group/u/swi)\
**Post date:** [May 9, 2021, 2:51am UTC](https://swi-prolog.discourse.group/t/new-undo-1/3932/3 "2021-05-09T02:51:01Z")

</div>

See [ADDED: undo/1 to schedule goals to be called on backtracking. · SWI-Prolog/swipl-devel@2c2acdd · GitHub](https://github.com/SWI-Prolog/swipl-devel/commit/2c2acdd29dff4b858317a806452b30f06bd2a97c)

git source for now, i guess it will be in next development release.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [May 9, 2021, 6:54am UTC](https://swi-prolog.discourse.group/t/new-undo-1/3932/4 "2021-05-09T06:54:30Z")

</div>

> [@swi](#):
>
> why does it make a difference to have `ok` vs `true` ?

True doesn’t create a call and goals registered with undo/1 are executed on the next call port. So, the undo happens, but not in the test body context but right after getting back into the test wrapper where the exception is no longer caught.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [May 9, 2021, 12:13pm UTC](https://swi-prolog.discourse.group/t/new-undo-1/3932/5 "2021-05-09T12:13:17Z")

</div>

B.t.w. when I was documenting this I wanted to refer to the SICStus compatibility. It appears SICStus dropped (deprecated?) undo/1 from SICStus 4. Going through some of the comments about using undo/1 in a constraint context it seems SICStus did actually call the goal while unwinding the trail. That is quite different from SWI-Prolog at the moment: the goal is _copied_, scheduling its execution for later. That limits its usability to dealing with otherwise non-backtrackable data such as the clause DB, foreign structures, external databases, etc.

I don’t really see the point why one would want undo/1 to poke around in the already backtrackable constraint store. Maybe it made/makes sense in SICStus. Executing the goal in the middle of the trail rewinding is interesting as it avoids copying. I have little clue on how to implement that though

---

<div class="post-metadata">

**Author:** ![logicmoo](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/logicmoo/32/193_2.png) [@logicmoo](https://swi-prolog.discourse.group/u/logicmoo)\
**Post date:** [May 9, 2021, 1:28pm UTC](https://swi-prolog.discourse.group/t/new-undo-1/3932/10 "2021-05-09T13:28:48Z")

</div>

Just in case, if my posts are not related to this `undo/1` thread… we can remove these posts and move to a new thread?

---

<div class="post-metadata">

**Author:** ![swi](https://avatars.discourse-cdn.com/v4/letter/s/51bf81/32.png) [@swi](https://swi-prolog.discourse.group/u/swi)\
**Post date:** [May 9, 2021, 2:01pm UTC](https://swi-prolog.discourse.group/t/new-undo-1/3932/11 "2021-05-09T14:01:11Z")

</div>

> [@jan](#):
>
> That limits its usability to dealing with otherwise non-backtrackable data such as the clause DB, foreign structures, external databases, etc.

That seems to me the most useful purpose. Like you, I don’t see why would it be used with already backtrackable structures, but I don’t have deep knowledge about these matters…
