The major, major problem of pseudo-code is semantics. If you describe something (say, an algorithm) with a certain notation (say, pseudo-code, or flow-charts, or whatever), then you need semantics. What does if error code is valid then dostuff mean? Of course, by semantics of the english language, this means: There is a condition hidden here, and whenever the condition is true, execute dostuff. In a recent lecture, this resulted in horrible misunderstandings, because the semantics of return appeared to be output the value after the return and continue execution after this. The result was a horrible misunderstanding with regard to the algorithm.
The usual way to obtain a semantic for this pseudo-code is by mimicing an existing language and using the english language semantics. However, given this, I second Jeff: It makes no sense to use pseudo-code, because pseudo-code will always look like an existing programming language, and well-factored code in a high level language (say, prolog, haskell, python/ruby) will look like pseudo-code. In fact, whenever someone asks me for pseudo-code, I write down a program in one of these languages (maybe with a bit of syntactic convienience, but usually, those could be eliminated with a simple preprocessor).
However, the deeper question is: Is there a need to have a better representation of complex code to reason about? I say yes, and yes, sometimes it is necessary. For certain compiler operations, for example, it is hilariously helpful to just draw two tree diagrams (before transformation, after transformation) instead of writing several pages of text about it. In other areas, a simple block diagram with a little statemachine next to it can help a lot. In other areas, a simple dataflow diagram will help a lot. The important thing to notice about all these representations however is: They are not trivially isomorphic to code. Take most pseudo-code, and it is fairly easy to write down the code for this line of pseudo-code. This is bad. This is very, very bad, because it means: pseudo-code is a very, very thin layer of abstraction, and thin layers of abstractions are just an obstacle. Given a dataflow diagram, or two trees and an arrow from one to the other, it is certainly not trivial to actually program this. This is a good thing, because apparently, the abstraction is big.
So, dont use pseudo-code, because it is a weak abstraction, use a good (ad-hoc) diagram to explain this. If you need the diagram more often, write down a little formal explanation of it and be happy 