The solution is easy: impure(Ls) :- length(Ls, L), write(L).
.
However, this is a very bad idea for several reasons.
A very important one is that things that appear only on your screen cannot be reasoned about within Prolog!
Thus, if you just write some results with write/1
, you cannot really run automatic test cases to see whether your predicate actually behaves as expected. At least writing tests becomes much harder this way.
In contrast, with your original, purer version of the code (which did not use side-effects), you can easily test for example:
?- length([a,b,c], 3).
true.
and also run several such test cases automatically, and use Prolog to see whether they succeed. For example, a batch of 10,000 test cases may look like (searching for counterexamples):
?- between(1, 10_000, L), length(Ls, L), length([_|Ls], L1), L1 =\= L+1.
false.
In contrast, how do you test an impure predicate?
?- between(1, 10_000, L), length(Ls, L), impure([_|Ls]) what now??
As you see, it is really hard to reason about the output of a predicate!
Also, this makes your predicate much less general than your current version! You can no longer use the impure version in other directions. For example, how do you now generate a list of given length? There is no way to supply the length!
Stay pure folks, and use the Prolog toplevel to obtain answers instead of writing them yourselves on the screen!