# Careful with forall/2 when it is used for "side-effects"

**URL:** <https://swi-prolog.discourse.group/t/careful-with-forall-2-when-it-is-used-for-side-effects/5469>\
**Category:** Nice to know\
**Tags:** chr\
**Created:** [June 6, 2022, 8:16pm UTC](https://swi-prolog.discourse.group/t/careful-with-forall-2-when-it-is-used-for-side-effects/5469 "2022-06-06T20:16:17Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![chansey97](https://avatars.discourse-cdn.com/v4/letter/c/e480ec/32.png) [@chansey97](https://swi-prolog.discourse.group/u/chansey97)\
**Post date:** [June 6, 2022, 8:16pm UTC](https://swi-prolog.discourse.group/t/careful-with-forall-2-when-it-is-used-for-side-effects/5469/1 "2022-06-06T20:16:17Z")

</div>

SWI-Prolog Manual said that forall/2 can be used for its side-effects.

> The forall/2 control structure can be used for its side-effects. E.g., the following asserts relations in a list into the dynamic database:

But before using it, make sure your side effect is not backtrackable. If it is, the result might not be what you want.

For example,

```prolog
b_add(N, V) :- b_getval(N, V1), V2 is V1 + V, b_setval(N, V2).

?- b_setval(a,0), forall(between(1,3,X), b_add(a,X)), b_getval(a, R).
R = 0.

```

Because the side effect is backtrackable, the assignment doesn’t do anything.

Another example is CHR, which is also backtrackable!

```prolog
:- use_module(library(chr)).
:- chr_constraint a/1.

%% attempt to add three constraints
?- forall(between(1,3,X), a(X)). 
true.

```

Using foreach/2 if you don’t like this behavior.

```prolog
?- b_setval(a,0), foreach(between(1,3,X), b_add(a,X)), b_getval(a, R).
R = 6.

?- foreach(between(1,3,X), a(X)).
a(3),
a(2),
a(1).

```
