# Detecting anonymous variable

**URL:** <https://swi-prolog.discourse.group/t/detecting-anonymous-variable/2279>\
**Category:** General\
**Created:** [May 5, 2020, 5:23pm UTC](https://swi-prolog.discourse.group/t/detecting-anonymous-variable/2279 "2020-05-05T17:23:33Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![esad](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/esad/32/884_2.png) [@esad](https://swi-prolog.discourse.group/u/esad)\
**Post date:** [May 5, 2020, 5:23pm UTC](https://swi-prolog.discourse.group/t/detecting-anonymous-variable/2279/1 "2020-05-05T17:23:34Z")

</div>

Is there a way to check if a predicate argument has been explicitly bound to `_` by the caller? The idea is to detect when my predicate gets called with (output) variable bound to `_` and skip the expensive calculation altogether. It wouldn’t have to handle complex cases like later binding, e.g. `foo(X, Y), Y = _`, just `foo(X, _)`.

---

<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:** [May 5, 2020, 5:46pm UTC](https://swi-prolog.discourse.group/t/detecting-anonymous-variable/2279/2 "2020-05-05T17:46:15Z")

</div>

Do you mean an uninstantiated variable in general or one that’s specifically “\_” in a query.

For the former: [var/1](https://www.swi-prolog.org/pldoc/man?predicate=var/1) or `nonvar/1`.

For the latter: [read\_term/2](https://www.swi-prolog.org/pldoc/man?predicate=read_term/2) has options such as `singletons` and `variable_names` and `write_term/2` has options to allow displaying those variable names (see also `numbervars` and related predicates).

---

<div class="post-metadata">

**Author:** ![dtonhofer](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/dtonhofer/32/902_2.png) [@dtonhofer](https://swi-prolog.discourse.group/u/dtonhofer)\
**Post date:** [May 7, 2020, 4:05pm UTC](https://swi-prolog.discourse.group/t/detecting-anonymous-variable/2279/3 "2020-05-07T16:05:46Z")

</div>

…read\_term/2, yes, but not at use/call time (the compiler will have removed the names in any case).

The alternative is of course to have a few predicates for the various use cases. As the programmer writes `_`, the programmer definitely knows that he/she won’t use any term that got depsited into `_`. Might as well use another predicate.

---

<div class="post-metadata">

**Author:** ![esad](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/esad/32/884_2.png) [@esad](https://swi-prolog.discourse.group/u/esad)\
**Post date:** [May 13, 2020, 12:09pm UTC](https://swi-prolog.discourse.group/t/detecting-anonymous-variable/2279/4 "2020-05-13T12:09:45Z")

</div>

`var/1` won’t tell me if the variable is called `_` in the calling predicate, so I have no way of differentiating if the result is going to be used or not. I’m thinking some kind of term expansion that attributes the variable before passing it, then check for that attribute in the predicate that wants to skip work might work? But as @dtonhofer pointed out, separate predicate might be cleaner solution after all 🙂

---

<div class="post-metadata">

**Author:** ![dtonhofer](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/dtonhofer/32/902_2.png) [@dtonhofer](https://swi-prolog.discourse.group/u/dtonhofer)\
**Post date:** [May 13, 2020, 12:19pm UTC](https://swi-prolog.discourse.group/t/detecting-anonymous-variable/2279/5 "2020-05-13T12:19:03Z")

</div>

I have found that there is [Conditional compilation and program transformation](https://eu.swi-prolog.org/pldoc/man?section=progtransform) which can certainly be used to transform a program at load time so that usage of `_` gives rise to a specific predicate call … but I have no idea how to use that practically.

---

<div class="post-metadata">

**Author:** ![emacstheviking](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/emacstheviking/32/228_2.png) [@emacstheviking](https://swi-prolog.discourse.group/u/emacstheviking)\
**Post date:** [May 13, 2020, 12:56pm UTC](https://swi-prolog.discourse.group/t/detecting-anonymous-variable/2279/6 "2020-05-13T12:56:33Z")

</div>

Agreed. For me, I’d have two versions, that way the code is explicit at the cost of not much extra code. Plus, you don’t have to wonder what the other variable is actually for!

---

<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 13, 2020, 1:10pm UTC](https://swi-prolog.discourse.group/t/detecting-anonymous-variable/2279/7 "2020-05-13T13:10:26Z")

</div>

Close. Actually something rudimentary was implemented. Thought let us complete it. So, using the latest GIT you can do (for example):

```prolog
user:goal_expansion(append(V, End, List), last(List, Last)) :-
    var_property(V, singleton(true)),
    is_list(End),
    End = [Last].

t(List, Last) :-
    append(_, [Last], List).

```

After loading you get

```prolog
108 ?- listing(t).
t(List, Last) :-
    last(List, Last).

```

Ideally we would have properties that verify that some variable only appears in the context of the current goal being expanded and a property that checks that this is the last goal in which the variable appears. The first can be used for scope warnings, while the latter can be used to avoid computing results that are not used. Might have a look at that.
