1

The SICStus Prolog manual page on mutable terms states that:

[...] the effect of unifying two mutables is undefined.

Then, why does create_mutable(data,x) fail?

Shouldn't that rather raise an uninstantiation_error?

I cannot think of a situation when above case is not an unintentional programming error (X vs x)... please help!

false
  • 10,264
  • 13
  • 101
  • 209
repeat
  • 18,496
  • 4
  • 54
  • 166

1 Answers1

3

The short answer to "Why does create_mutable/2 not throw an exception when output unification fails?" is just: Because this was how it was done when the feature was added to SICStus Prolog, and no one has made a strong case for changing this.

One important "difference between the stream created by open/4 and the mutable term created by create_mutable/2" is that open/4 has side-effects that are not undone if the output-unification of the call to open/4 fails.

In this sense, create_mutable/2 is somewhat more like is/2 which also just quietly fails if the output argument is some non-numeric non-variable term, e.g. in x is 3+4. This seems to be the common, and traditional, way of handling output arguments in Prolog.

I agree that a non-variable as second argument is most likely a programming error. The next version of the SICStus IDE, SPIDER, will warn for this (as it already does for is/2).

None of this, nor the example in the question, seems directly related to the cited documentation "[...] the effect of unifying two mutables [...]".

Per Mildner
  • 10,469
  • 23
  • 30
  • Thank you! The cited documentation appeared relevant to me. Here's why: if a "type-correct" use of `create_mutable/2` (`?- create_mutable(data,X), create_mutable(datb,X).`) in mode (-,-) does result in undefined behavior, then what good is (silent) failure with type-incorrect uses like `create_mutable(data,x)`? – repeat Aug 12 '19 at 16:22
  • 1
    @repeat Type-checking output arguments is questionable at best. Why should the `X = x, create_mutable(data,X)` goal throw an exception and the `create_mutable(data,X), X = x` goal fail? – Paulo Moura Aug 12 '19 at 17:24
  • 1
    @PauloMoura. Good point! I was focusing on eliminating a nasty error ... OTOH let me turn your question back to you: why should the `S=s, open(...,S)` goal throw an exception and the `open(...,S), S=s` goal fail? Full circle;) – repeat Aug 12 '19 at 19:56
  • @repeat Hum? Per's answer explains it: side effects that are not undone in the case of `open/3-4`. – Paulo Moura Aug 12 '19 at 20:18
  • 1
    @PauloMoura. Hoho. Technically correct! In practice, however, both "uses" are **errors** which fits 8.1.3.5 "predicate has a single mode and template, an argument whose mode is - is always associated with an error" like a glove. – repeat Aug 12 '19 at 21:09
  • 1
    @repeat A way forward would be to distinguish between `-` and `--` arguments with the former allowing a call with the argument bound (and thus a failure when the unification between the passed term and what would be the returned term fails) and the later requiring a call with the argument unbound (and thus an exception when that's not the case). In the presence of side effects not undone by backtracking, `--` would be used in the predicate specification. Otherwise, `-` could be used. That said, type-checking of output arguments is still a bad idea when side effects are not a concern. – Paulo Moura Aug 12 '19 at 21:30