list_connections(Place) :-
connect(Place, X),
tab(2),
write(X),
nl,
fail.
list_connections(_).
In my eyes, this predicate mixes the computation of connections with
their display.
I see a few other ideal setups:
- one could get the connections in a producer predicate and stream
them to a display predicate. This would be optimal over space
- one could get all the connections and then display them all. This
would be optimal over time.
The current situation seems less than ideal, because one might have
numerous desired display methods. For instance, what if you wanted to
turn this into a gaming engine which could be used from the console or
via a webpage,, or even a web service that returns XML?
Right now, the intermingling of computation and the results of
computation make flexibly extending the app with various display
choices onerous.
Your general arguments might be sound, but I don't quite see your
point.
The predicate list_connections/1 is _just_ a display method: the
computation
of the connections is perfectly well encapsulated and isolated in
connect/2
(which might actually be a database of precomputed facts, for all we
know).
The main difference with respect to what you propose is that this
version
is much more efficient in Prolog. One might also argue that it is
more
declarative and easier to read.
If you want to display it differently, just do so. If your display
method
does not allow backtracking, get the solutions onto a list by writing
... findall( X, connect( Place, X ), Xs ) ...
The cost, of course, is that you might need more memory. You might
also have
to wait longer before seeing the first answer; in fact, quite a bit
longer if
the set of answers is infinite. :-)
Just a comment.
-- Feliks
> Your general arguments might be sound, but I don't quite see your
> point.
> The predicate list_connections/1 is _just_ a display method: the
> computation
> of the connections is perfectly well encapsulated and isolated in
> connect/2
yes, currently this code is similar to the producer-consumer I
mentioned earlier.
and if we wanted different display formats, there's nothing with
writing a list_connections/2 method which takes an output format as an
argument.
> ... findall( X, connect( Place, X ), Xs ) ...
another cool predicate. thanks!
> The cost, of course, is that you might need more memory. You might
> also have
> to wait longer before seeing the first answer; in fact, quite a bit
> longer if
> the set of answers is infinite. :-)
lol
I think you suffer from design-patternitis. Forget design patterns,
embrace implicit database-querying and metaprogramming.
> Right now, the intermingling of computation and the results of
> computation make flexibly extending the app with various display
> choices onerous.
Before making such claims count the number of lines needed to be
changed/added. As Prolog is a pretty close to a scripting language,
Agile methods (i.e. frequent refactoring, prototyping) suit it better.