It tempts you to write things that look logically correct, but
that won't run.
The obvious way to write a predicate is unlikely to be efficient.
You must know when a predicate needs to be optimised.
Because it lacks functional notation, predicates can become
cumbersome.
f( N, F ) :-
N1 is N - 1,
f( N1, F1 ),
F is N * F1.
It would be much nicer to write
f( N ) = N * f(N-1).
Input and output is not always easy.
There are some features which have not been standardised, and
differ between implementations. For example: formatted input and output,
file-handling, sorting predicates.
You can't re-assign to parts of data structures. This makes it
impossible to implement arrays. However, functional programmers have
developed a number of fast-access data structures which do almost as
good a job.