# Toplevel name variables

**URL:** <https://swi-prolog.discourse.group/t/toplevel-name-variables/4333>\
**Category:** Request For Comments\
**Created:** [August 24, 2021, 1:21pm UTC](https://swi-prolog.discourse.group/t/toplevel-name-variables/4333 "2021-08-24T13:21:20Z")\
**Posts on this page:** 9\
**Page:** 1

<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:** [August 24, 2021, 1:21pm UTC](https://swi-prolog.discourse.group/t/toplevel-name-variables/4333/1 "2021-08-24T13:21:20Z")

</div>

I’ve pushed a patch that causes the toplevel to give names to variables other than the variables that appear in the query. These variables are, copying SICStus, names \_A, \_B, … Unlike SICStus though, variables that appear only once in the answer are written as `_`. I think that significantly speeds up understanding an answer as you do not have to scan the answer for the same variable. Naming is controlled by a new flag `toplevel_name_variables`. So, we get e.g.:

```prolog
?- length(L, 5).
L = [_, _, _, _, _].

```

The downside is that queries that return huge terms with lots of variables print significantly slower.

Comments?

---

<div class="post-metadata">

**Author:** ![ridgeworks](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ridgeworks/32/886_2.png) [@ridgeworks](https://swi-prolog.discourse.group/u/ridgeworks)\
**Post date:** [August 24, 2021, 3:16pm UTC](https://swi-prolog.discourse.group/t/toplevel-name-variables/4333/2 "2021-08-24T15:16:40Z")

</div>

+1 from me.

Will this also be supported for the output predicates in general?

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [August 24, 2021, 4:29pm UTC](https://swi-prolog.discourse.group/t/toplevel-name-variables/4333/3 "2021-08-24T16:29:18Z")

</div>

+1 … this will also make comparing top level outputs easier … would there also be a similar option print/1 and tracing?

---

<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:** [August 24, 2021, 6:05pm UTC](https://swi-prolog.discourse.group/t/toplevel-name-variables/4333/4 "2021-08-24T18:05:11Z")

</div>

I’m not sure whether this is easily expanded to other output predicates. You do need to do the analysis on the entire term before going into the print/portray/… details. The toplevel can easily do this. The other output predicates are commonly called on partial terms though. This too is dangerous. Printing a variable using its location on the stack (the \_NNN vars) is subject to garbage collections that change the numbers ☹

The debugger could do so as it has the entire goal. The disadvantage is that subsequent goals are now printed using mostly (if there is no GC) consistent variable names. With this you get \_A, etc. in each goal, but the \_A in one goal is not related to the \_A in the next.

Note that there is numbervars/4 using the `singletons(true)` option that will bind all variables to `'$VAR'(N)` and the singletons to `'$VAR'('_')`.

---

<div class="post-metadata">

**Author:** ![ridgeworks](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ridgeworks/32/886_2.png) [@ridgeworks](https://swi-prolog.discourse.group/u/ridgeworks)\
**Post date:** [August 24, 2021, 7:24pm UTC](https://swi-prolog.discourse.group/t/toplevel-name-variables/4333/5 "2021-08-24T19:24:49Z")

</div>

> [@jan](#):
>
> Note that there is [numbervars/4](https://www.swi-prolog.org/pldoc/doc_for?object=numbervars/4) using the `singletons(true)` option that will bind all variables to `'$VAR'(N)` and the singletons to `'$VAR'('_')` .

I think this provides the necessary flexibility when using the other output predicates.

Not sure what to do about the debugger. Nothing’s more confusing (to me anyway) than to have your \_NNN variable names change in the middle of a debug session due to GC, but having the same name mean different variables (in different calls) takes it to another level.

---

<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:** [August 24, 2021, 8:20pm UTC](https://swi-prolog.discourse.group/t/toplevel-name-variables/4333/6 "2021-08-24T20:20:58Z")

</div>

Note that @dmchurch has created a PR that creates consistent names for variables during a query. This is probably the right direction, but in its current implementation it doesn’t scale good enough. We are discussing other options to make it work.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [August 26, 2021, 9:31pm UTC](https://swi-prolog.discourse.group/t/toplevel-name-variables/4333/7 "2021-08-26T21:31:52Z")

</div>

An option for a consistent renaming of variables in trace output would be helpful, instead of the current, seemingly random, assignment of numbers. (e.g., `A`, `B`, etc. or `_1`, `_2`, etc.)

My use case is when using non-graphic trace under Emacs – I’ve often found myself wanting to compare two trace outputs after making a change, or sometimes wanting to be able to search an earlier trace output for something I’m seeing in the current trace output.

---

<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:** [August 27, 2021, 9:16am UTC](https://swi-prolog.discourse.group/t/toplevel-name-variables/4333/8 "2021-08-27T09:16:06Z")

</div>

If I need to compare the behavior of two programs I typically use trace/1,2 to trace particular predicates and then use the meld utility where I tell it to ignore differences in `_[0-9]+`. I surely agree consistent naming would be nice to have. Doing this in a scalable way is hard though ☹

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [August 27, 2021, 3:58pm UTC](https://swi-prolog.discourse.group/t/toplevel-name-variables/4333/9 "2021-08-27T15:58:07Z")

</div>

> [@jan](#):
>
> use the meld utility where I tell it to ignore differences in `_[0-9]+`

TIL. Thanks!
