cat program in Prolog In order to learn Prolog, I have implemented the cat command in Prolog. I want to know if the code is idiomatic and what could be improved.

File args.pl:

:- module(args, [withFilesOrUserInput/2]).

withFilesOrUserInput(StreamFunction, []) :-
    call(StreamFunction, user_input).

withFilesOrUserInput(StreamFunction, [Filename]) :-
    withFile(StreamFunction, Filename).

withFilesOrUserInput(StreamFunction, [Head|Tail]) :-
    withFile(StreamFunction, Head),
    withFilesOrUserInput(StreamFunction, Tail).

withFile(StreamFunction, Filename) :-
    open(Filename, read, StreamIn),
    call(StreamFunction, StreamIn),
    close(StreamIn).


File cat.pl:

:- use_module(args).

main(Argv) :-
    prompt(_, ''),
    withFilesOrUserInput(catStream, Argv).

catStream(Stream) :-
    copy_stream_data(Stream, user_output),
    flush_output(user_output).


Note: I'm using SWI-Prolog.
+1, good question.

The Prolog convention is to use underscores for readability. Why? because_it_is_easy_to_read_even_long_names_with_underscores, butItIsExtremelyHardToReadEvenShorterNamesWithMixedCaps!

A good naming convention is to use one noun per argument, declaratively describing what the argument stands for.

In SWI-Prolog, check out library(pio): The pure way to do what you want is to use a DCG to describe a list, and then to use phrase_from_file/2 to apply the DCG to a file.

The advantage is clear: You can then readily test your predicates on the toplevel alone, without even requiring a file, just by stating the input as a regular Prolog term.

This helps a lot also when writing test cases.

EDIT: I give you one example how DCGs can help you here. It is not yet completely pure, because this DCG contains output itself. However, it is much simpler than your code, and you can test this predicate without even needing a file, and then transparently apply the same code to a file too:

:- use_module(library(pio)).
:- set_prolog_flag(double_quotes, codes).

cat --&gt; [].
cat --&gt; [C], { put_char(C) }, cat.


This DCG describes a list of character codes, and outputs each code. 

Sample use:

?- phrase(cat, "test").
test
true.


Now, with phrase_from_file/2 from Ulrich Neumerkel's library(pio), we can transparently apply the same DCG to a file too:


?- once(phrase_from_file(cat, 'cat.pl')).


With output:

:- use_module(library(pio)).
:- set_prolog_flag(double_quotes, codes).

cat --&gt; [].
cat --&gt; [C], { put_char(C) }, cat.


i.e., the same program as above, which I had saved it cat.pl.

I am using once/1 to commit to the first solution found (there is no further solution, but a choice-point left).