Is publishing runnable code instead of pseudo code shunned?
Not that I know of, but this probably depends on the specific subculture of the respective field.
In Computer Science is it preferable to describe algorithms using pseudo code rather than real code?
It was (see Owen's answer) and sometimes still can be (see considerations below).
If so, why?
So what are the arguments for pseudo code?
As many of the other answers already state: Other than naive runnable code, pseudo code aims to be easily read and understood without bothering the reader with unimportant (for the presented aspect) details. And it usually succeeds at these goals.
As you yourself state, runnable code also has its benefits. So let me side-step the issue by claiming that
with some effort you can get the benefit of both
(and without actually providing both, pseudo code and separate runnable code, as syn1kk suggests.)
Ideal code in papers (and, if feasible, elsewhere) is pseudo-pseudo code: Code that has all the positive properties of pseudo code, but happens to be runnable (and to actually do what it seemed it would).
It is my firm believe that all sufficiently well-written runnable code is indistinguishable from pseudo code: If anyone can tell that certain (actually runnable) code isn't pseudo code because it isn't as readable and as easily comprehensible as pseudo code, that runnable code isn't structured well enough, yet, and should be refactored.
How to get pseudo pseudo code
How do you achieve runnable code that is as easy to read as pseudo code?
There are several aspects to consider and fulfilling all of them may not always be easy or feasible, or sometimes not even possible. (This can be a valid reason to use actual non-runnable pseudo code instead of runnable pseudo-pseudo code.)
Choose the right language
What language is best suited depends on several things:
- The problem domain
- Your solution approach
- Your audience
- The possibilities the language offers for (re)structuring your code
Note that for some combinations of these, no programming language may (yet or sometimes even ever) exist that allows you to write sufficiently well-written code. For obvious practical reasons, you'll also have to factor in your command of the respective language (how skilled you are in applying it).
Make your code extremely clean: Refactor, refactor, refactor
If there are implementation details that obfuscate the core idea of the algorithm you're describing, extract them (e.g. to constants, variables, methods or functions), so that you can replace their "how" (their implementation) by their "what" (the name of the newly extracted code-thing). If appropriate, choose not to show the extracted implementation or assignment in the in-paper code excerpts. Take extreme care in naming the extracted things, so that their purpose (not necessarily their implementation) is extremely clear and obvious from their name and call signature.
On the other hand, if an algorithm is too scattered between different parts of the code to be readily understood, you may have to selectively inline code instead.
In all of that, aim for a single level of abstraction per code unit (e.g. function) or, at least, the right levels of abstraction to best show and explain the algorithm. Though apply the somewhat related single-responsibility principle only with care: Over-applying it (or interpreting "single responsibility" too narrow) can scatter and thereby obfuscate your algorithm. Note that in that regard, the right balance for code to present in a paper will most probably be different from the right balance for code in a (to-be-)maintained software product.
With any sufficiently optimizing compiler or interpreter, none of these refactorings should too adversely affect performance. But when the focus is on presenting an algorithm rather than implementing it in a production system, this shouldn't be of too much concern, anyway.
Make your code obvious to interpret
The correct interpretation of your pseudo pseudo code shouldn't rely on knowing your chosen programming language, or its version, variant or dialect. Thus be wary of what language features you use.
Each language feature that is common to many programming languages (known to the audience) and that in the chosen language has a similar syntax to many other programming languages could just as well be also a feature of a pseudo code dialect and can thus be used in pseudo pseudo code, unless the chosen programming language has an unusual and non-obvious semantic for it. Even a not-so-common or language-specific feature, or one with a not-so-common syntax, can be used without problem, if its semantics are sufficiently self-evident from its syntax and keywords and their relation to natural language.
Non-obvious language features are best omitted, but can be used when combined with explanations in code comments or in the paper's prose. (Just as it would apply to non-obvious features of a chosen pseudo code dialect.)
The same goes for language specific idioms: Avoid or explain them, if you have to expect them not to be obvious to your audience.
Alternative: Make pseudo-code runnable
The above two sections assume that you start from working runnable code. Of course you can also start from pseudo code and modify it to actually be runnable (and hopefully to do what it seems to do) in a suitable programming language. Note though, that you can end up with very non-idiomatic code for the target language that way, which may not be what you want. Of course, refactoring can usually fix that.
Explain your code
Just like you would have to explain (in prose, code comments or callouts) certain aspects of your code if it was presented in pseudo code, you have to do that if it's written in pseudo pseudo code.
The advantages of pseudo pseudo code
- As readable and comprehensible as pseudo code
- If the used language (incl. version, variant or dialect, if applicable) is specified:
- it is runnable and usable
- it is testable both manually and by automated tests
- it is profilable
Some of these advantages benefit you as the author, as you can for example make sure(r) the algorithm as presented is actually correct. Others benefit your audience who might want to assess your algorithm.
Whether these benefits are worth the significant work that is required to achieve pseudo pseudo code vs. just pseudo code or on the other hand not sufficiently well-written runnable code, is up to you to decide.
Oh, and let's not forget the moral benefit: Whether "it looks amateurish" or not, you can be confident that it isn't, due to all the skill and hard work it requires.