# Impact of arguments order in maplist

**URL:** <https://swi-prolog.discourse.group/t/impact-of-arguments-order-in-maplist/1247>\
**Category:** Help!\
**Created:** [September 13, 2019, 2:47pm UTC](https://swi-prolog.discourse.group/t/impact-of-arguments-order-in-maplist/1247 "2019-09-13T14:47:20Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![pdprolog](https://avatars.discourse-cdn.com/v4/letter/p/c67d28/32.png) [@pdprolog](https://swi-prolog.discourse.group/u/pdprolog)\
**Post date:** [September 13, 2019, 2:47pm UTC](https://swi-prolog.discourse.group/t/impact-of-arguments-order-in-maplist/1247/1 "2019-09-13T14:47:20Z")

</div>

Hello:

While playing with the implementation of the maplist/2 predicate, I have noticed that the order of the arguments in the predicate may matter. For example:

1. If maplist/2 is implemented with the goal as first argument (using SWISH):

```prolog
map1(_, []).
 map1(Goal, [H|T]) :-
        call(Goal, H),
        map1(Goal,T).

```

Then the query " ?- map1(integer, [])." provides true, makes a redo (?? I do not see why…) and then false.

1. If maplist/2 is implemented with the goal as second argument (using SWISH):

```prolog
map2([], _).
 map2([H|T], Goal) :-
        call(Goal, H),
        map2(T, Goal).

```

then the same query just answers “true” (no redo).

I have also found that this issue is explicitly mentioned in the SWI-Prolog implementation:

_maplist(:Goal, ?List)_  
_True if Goal can successfully be applied on all elements of List. Arguments are reordered to gain performance as well as to make the predicate deterministic under normal circumstances._

_maplist(Goal, List) :-_

- maplist\_(List, Goal). \*  
_maplist\_([], \_)._  
_maplist\_([Elem|Tail], Goal) :-_
- call(Goal, Elem),\*
- maplist\_(Tail, Goal).\*

Could someone tell me:

1. Where does the “redo” in the query " ?- map1(integer, [])." come from?
2. Why the reordering “gains performance” and “makes the predicate deterministic under normal cirscuntance”? What does “normal circunstances” mean?
3. Is there a general rule on arguments ordering, or only for second-order predicates, or …?

Thanks a lot in advance !!

---

<div class="post-metadata">

**Author:** ![Ian](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ian/32/1026_2.png) [@Ian](https://swi-prolog.discourse.group/u/Ian)\
**Post date:** [September 13, 2019, 3:11pm UTC](https://swi-prolog.discourse.group/t/impact-of-arguments-order-in-maplist/1247/2 "2019-09-13T15:11:38Z")

</div>

The retry happens because there is another map1 clause below the initial matched clause which potentially matches. Your map2 version doesnt retry because SWI knows that the second map2 clause won’t match due to special case processing on the first index.  
See [https://www.swi-prolog.org/pldoc/man?section=jitindex](https://www.swi-prolog.org/pldoc/man?section=jitindex) (Special Purpose Code).

---

<div class="post-metadata">

**Author:** ![joeblog](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/joeblog/32/122_2.png) [@joeblog](https://swi-prolog.discourse.group/u/joeblog)\
**Post date:** [September 14, 2019, 8:11am UTC](https://swi-prolog.discourse.group/t/impact-of-arguments-order-in-maplist/1247/3 "2019-09-14T08:11:50Z")

</div>

> [@pdprolog](#):
>
> Is there a general rule on arguments ordering, or only for second-order predicates, or …?

Richard O’Keefe in The Craft of Prolog (p14 in the copy I have) suggested this precedence for argument ordering:

1. _Templates_ (eg as in `findall(+Template, :Goal, -Bag)`) come first.
2. _Meta-arguments_, as in :Goal in `maplist(:Goal, ?List1, ?List2)` and findall/3 above come next.
3. _Streams_, as created by `open(+SrcDest, +Mode, --Stream)` are third. Good style is to place these within setup\_call\_cleanup/3. Since Stream is the output of open/3, it’s not a good example. Whatever predicate uses it (ie the second argument of setup\_call\_cleanup) would follow this convention.
4. _Selectors_ or _indices_ as in `arg(?Idx, +Term, ?Value)`.
5. _Collections_ as in Lists, Dictionaries, and context arguments like context\_name(A,B,C,D,…).
6. _Input arguments_ which the predicate solves or tests for (which could be bidirectional, doubling as outputs).
7. Outputs come last (which in the case of bidirectional predicates may sometimes be inputs. O 'Keefe suggests ordering bidirectional arguments by which is most commonly used input and output).

While many of these are just stylistic, it’s very important for outputs to come last and inputs to come second last for predicates to work as second\_order functions for the _apply family_ of predicates listed in [https://www.swi-prolog.org/pldoc/man?section=apply](https://www.swi-prolog.org/pldoc/man?section=apply) as in maplist/3, include/3, exclude/3 etc.

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [September 16, 2019, 8:05am UTC](https://swi-prolog.discourse.group/t/impact-of-arguments-order-in-maplist/1247/4 "2019-09-16T08:05:44Z")

</div>

An educated guess of what might be meant by “deterministic under normal circumstances”.

Example 1, deterministic, “normal circumstances”?:

```prolog
?- maplist(integer, [1,2,3]).
true.

?- maplist(integer, []).
true.

```

Example 2, non-deterministic, “abnormal circumstances”?:

```prolog
?- length(L, 2), maplist(between(1, 2), L).
L = [1, 1] ;
L = [1, 2] ;
L = [2, 1] ;
L = [2, 2].

```
