This page lists things we consider inappropriate and intolerable, or (sometimes) tolerable to some extent yet strongly discouraged. What's very important here is that this list is in no way an invitation for any dispute, argument or discussion. For each item on the list (with one important exception) we provide some brief explanation here, and for some of the items there may be a separate article. For some other there are no separate articles yet, but we're doing our best to write them; however, now that there's no detailed explanation, please don't ask us for one because you ”really want to understand“. Our resources are not infinite, and if what we have to the moment is not enough to convince you, then you may either wait for us to find some time to write another article, or keep your opinion which disagrees with ours, but please don't bomb us with questions of this kind, we are busy and won't change our schedules.
There's a single exception to all this; we hope there will be no need for more exceptions of this kind.
Once you wrote some code, you're free to decide to keep it private, or publish it openly, or disclose to a limited group of people to perform some further work on it, as long as you take those people as your fellow collaborators, not users.
However, if you decide to give your program to anyone to use, you must first publish its full source code, openly.
Please note giving the sources together with each copy of the program (as, e.g., demanded by GNU GPL) is not sufficient here. Only open publication works.
The No external dependencies! page explains this topic in more detail,
but to be short, external dependencies can be build-time and run-time. So here's the rule:
make
utility (GNU Make or Posix Make, but nothing else)
and — well, to some extent — standard libraries. Okay,
presently this only means plain C standard library.Hence, interpreted execution is not acceptable for general-purpose languages; interpreted model is only suitable for scripting and built-in DSLs, and for them it is the only possible choice as a compiler would become a runtime dependency.
Interpreted languages that have their “ecosystems”, such as Perl, Python, Ruby and so on, have no valid purpose at all, and learning such languages is a waste of time.
All these semi-interpreted languages like Java or C# must not be considered for any task as well, because their “run-time environments”, such as JVM, dot-net, mono etc., are run-time external dependencies, too.
Not only you must use a fully-compiled language. Besides that, you must always make sure your program can be built as a statically-linked binary. It is okay to keep dynamic linking possible, but static linking must be the default, allowing dynamic builds upon explicit request only (if at all).
Your source tree must be self-containing; no external libraries are tolerable, at all; our exception for some parts of the C standard library is temporary. Importing libs must be considered carefully: they must be put into the main source tree of the project, thus becoming another piece of your code. Besides that, all parts of the code within the project, including the libraries, must obey the rules, including this taboo list. Also it is impractical to import huge libraries if you're only going to use a small subset of their capabilities.
Data files 'shipped together' with your program are generally not desirable and must be limited to the data the user is supposed to provide or modify. Data not intended to be supplied or modified by the user, such as icons or other images, must be built into the executable.
Be extremely discriminating with features provided by the so-called “standard library”. It is highly likely we'll get rid of the standard library one day, completely. The less parts of it our program will depend on, the less effort we'll have to spend doing it, and this should be always kept in mind.
See the full No 'Download and Execute' article.
Any program code can be executed on someone's computer or other device only after explicit installation performed by the user, and upon explicitly given user's well-informed consent for each and every single case.
This means, first, no automated software updates may ever be performed; no 'consent' from the user should be asked for a software update automation, as effectively such a consent would change nothing at all: no code must ever be allowed to find its way around the explicit installation procedure performed by the user, actively. Please note any automation of software updates is an obvious security hole in itself, so automated software updates, being implemented, ruin any possible security. This makes all these stories about 'security-critical updates' a nonsense.
The second, but even more important thing, is that no client-side scripting is allowed, starting with the most important case of JavaScript on web-sites. Actually, the World Wide Web in its present state must be demolished, and massively used JavaScript is not the only cause for this, but definitely one of the most important.
Yes, multithreading is not allowed. Furthermore, it is not allowed to create any mutable shared memory (there's no problem with sharing a memory section in case it is read only for all processes; actually, it is exactly what happens with executable code when several processes run the same executable binary).
If you're going to explain how efficient it is to use shared memory, then don't. In reality, nobody bothers with any practical demonstration of the fact multithreading is really needed for efficiency reasons, and in most cases, if not all, from the user's point of view, multithreaded programs freeze every now and then, primarily because of cancellation points.
So no, don't even think about multithreading.
General purpose programming languages that support multithreading either within the language itself, or within mandatory part of the runtime library, are forbidden.
See the full No Recursive Nesting Data Formats article.
The mere fact people tend to come up with markups like ReST, BBcode, wiki languages, Gemtext etc., clearly demonstrates one thing: HTML is a failure. SGML family, including HTML and XML, failed even for the purpose they were intended — namely, to mark up native language documents.
As of using XML for machine-readable data (which is not a native-language text), it is simply a nonsense, and for healthy-minded people it was clear from the very start. But healthy-minded people are a dying-out species nowadays, as clearly shown by the mere fact such an ugly beast as JSON appeared long after it became clear nothing like this has any right nor even a reason to exist.
So here's the rule: data formats with recursive nesting are forbidden. By the way, according to the theory of databases, the 1NF is sufficient for any purpose, and 1NF only demands all values in a table being atomic.
See the full No MIME article.
MIME has no right to exist, not only because it is a recursively nested data format, but generally because it is overcomplicated. Some support for MIME is allowed for compatibility with widely-adopted software such as web browsers, but it must be limited to the absolute minimum.
Non-ASCII characters may only be used in documents and other human-readable texts written in natural languages, intended to be read and edited by end users.
Formal identifiers, such as file names, user/login names, host names, various tags etc., and, generally, any names used by computer programs to identify objects of any kind, physical or virtual, must not contain any non-ASCII chars. Furthermore, they must not contain whitespace chars, and punctuation char usage must be reasonably limited. Well, it is generally not a problem to have underscores, dashes and dots (a.k.a. periods, a.k.a. fullstops) in identifiers unless they are explicitly assigned any special roles, but all other punctuation it troublesome.
All formal languages and their elements must remain ASCII only, as well. In particular, source code of computer programs, written in any of existing programming languages, must not contain any non-ASCII chars, even in comments, not to mention literals (string and character constants). Furthermore, they must remain English only, meaning that neither identifiers nor comments may ever include any non-english words, even if they don't contain non-ASCII chars.
Unlike programming languages, markup languages, being formal, are often used for representing formatted documents in natural languages, so it is impractical to demand all texts in markup languages to be limited by the ASCII table. However, all markup elements (such as tags, names, attributes, labels, anchors etc.) must remain ASCII only. Besides that, markup must always be parsed as a sequence of bytes. This means that, should a text containing markup is represented in utf8, all markup parsing must be done before the conversion of byte sequences into code points, on the level of bytes not utf8 characters, so that no overlongs (and, generally, no bytes that are not ASCII codes) may ever be interpreted by the parser as a part of markup.
And one more thing: no support for “internationalized domain names” (IDNs)! IDNs are to be considered non-existing, and no specific support for them must ever be provided. It is more or less clear now that this particular nonsense has failed and is being slowly pushed out of everyday use. So, let it just die in peace. Don't invest your effort into making this death longer.
See the full Limitations for Unicode article.
Unicode is another committee-made bastard. It can still be used as a numbered list of all known printable characters, but there are some certain limits.
First of all, no 'utf8 everywhere' assumption! The utf8 encoding is based on Unicode, which is, let's repeat it, a commitee-made bastard. We deliberately don't accept it as the only possible option. Yes, we know about the so-called 'Utf8 everywhere manifesto'. And we disagree.
Other ASCII extensions must gain no less support than utf8. If your program only supports a single character encoding, that encoding must be ASCII. If you decide to provide some support for utf8, then you must support other ASCII extensions as well, such as latin1, koi8-r and the like. Basically you have the following options: to be totally encoding-agnostic; to remain ASCII only, deliberately refusing to consider all bytes greater than 127 to be codes of characters; to provide support for several different ASCII extensions and a clear way to add support for more of them; and to limit all “encoding support” with a single flag that states whether the utf8 multibyte approach is in effect or not, remaining encoding-agnostic in all other aspects.
No byte-order mark (BOM) in utf8, it's a nonsense. It is prohibited to emit BOM as a part of utf8 text, and your program should (although not required to) produce a warning message if BOM is encountered in utf8 input.
No unicode-based encodings other than utf8. Multibyte character encodings other than utf8, such as UCS-4, UTF-16, UTF-32 and their variants, well, don't exist. Period.
No support for Unicode diacritical marks. All the code points from the so-called Combining Diacritical Marks Unicode block must either be ignored, or displayed and/or otherwise handled as completely separate characters, or even produce an error.
Generally, no combining of several codes into a single glyph must ever be performed nor even attempted. Besides the diacritical marks, the 'standard' introduces modifiers, effectively meaning that sometimes sequences of more than one code are to be combined in a single glyph (e.g., the codepoints named VS-1—VS-256). This ruins the only useful property of Unicode, which initially was that each and every possible symbol may have its own code. No 'standard-compliant' handling of such code points must ever be provided; your program should either display (and otherwise handle) all these modifiers as separate codes for which you don't have a glyph, or ignore them.
Unicode emoji no more. These must either be ignored, or filtered off, or rejected, or otherwise refused. All this crap is far beyond all possible limits. In particular, no glyph may contain any information regarding colors, but this is not the only reason to get rid of unicode emoji.
Locales must be avoided with the best possible effort. Once we need an
internationalized program, we should use our own system of replaceable
message sets, created specifically for the task at hands. No matter
whether your program is intended to be internationalized or remain
English-only, its functioning must not be affected anyhow
by any of the locale-related environment variables, and it must not use the
locale 'subsystem' in any other way. Besides that, you should do
your best not to let the locales' support code slip into your binary.
Unfortunately this is not always reasonably possible (e.g., unfortunately,
the printf
function sucks the locales in); however, even
having that damn code in your binary is no excuse for making any use of it.
Generally, cryptography is useful. Unfortunately, people who are good with cryptography, are not always as good with computer programming. Furthermore, they are not always good with information security; sometimes they act (and talk) in an implicit assumption that security is cryptography, which is far from having anything to do with the real world.
Anyway, there are a lot of people who're sure cryptography is the most important thing in the universe. Those people may be seriously harmful to others, and usually they are. Not only they make innocent software overcomplicated and bloated; the worst thing is that corporations tend to use those cryptographic lunatics to achieve their own (corporate) goals towards free software.
Limits enumerated in this section are imposed to reduce this kind of harm and generally return the situation to kinda manageable state.
First of all, SSL/TLS no more. Seriously, we've got enough of these. Jokes like this don't look funny anymore, they rather look disgracing. So, it is strictly prohibited to use SSL/TLS in new protocols, and it is encouraged to get rid of existing protocols where this monster is involved.
Speaking generally, in all new protocols and applications the set of cryptographic algorithms being used must be fixed, once and forever. Letting communicating parties negotiate which algorithms to use, and specially any attempts to make cryptography support generalized so that new algorithms may be added later, adds such a huge amount of complexity that things like this should not ever be considered again.
The next important principle is that no use of global certificate authorities should ever be proposed again. They add absolutely nothing to security; their real main function is to suck money, but even “free” services of this kind are way too harmful to be tolerated.
There may only exist certificate authorities that serve closed groups of people, like computer users within a single organization, provided that, first, the CA belongs to that organization (or a group of other kind), and, second, it doesn't do any attempts to work outside of the closed group of users it is intended to serve. If there's no closed (and well-defined) group of users, there must be nothing like a CA.
Whenever another cryptographic check fails, the user must remain the authority who makes the final decision. Software must provide an easy and clearly visible possibility for the user to proceed anyway, despite any cryptographic failures, if it is physically possible to continue the work.
Unfortunately enough, the HTTPS protocol is way too widespread nowadays to be ignored. However, any 'later versions' such as HTTP 2.0, HTTP 3.0 and SPEEDY, must be kept out of consideration forever; no support for them must ever be provided, anywhere. As of the HTTPS itself, we'd better to say its use is strongly discouraged. It is still acceptable to support HTTPS for the sake of compatibility with the vast majority of web-related software, but some strong reasons must exist behind every single case where HTTPS is used.
In particular, if a web site only contain public information and does not deal with passwords, HTTPS on such site must be considered inappropriate. By the way, lists of single-use passwords allow even sites with user accounts to work more or less safely without HTTPS.
As of electronic mail — that is, SMTP protocol — the well-known STARTTLS extension may be suported, but in no circumstances may any SMTP software refuse to communicate just because either TLS is not available, or something is wrong with the remote certificate. Besides that, no additional conditions must be imposed on the communication partner basing on the fact it can't or doesn't want to communicate using encryption. Generally, no actions must ever be taken to promote or endorse using cryptography with SMTP.
Definitely we need a separate article on this, but it is yet to be written.
First of all, boycott all so-called standards and other commitee-made stuff. Noone can ever have the authority to issue commands to the whole world, and specially not these commitees consisting of more or less random people who assume no responsibility for what they do.
See the article Acceptable Subsets of Plain C and C++ for more on this.
Before moving on, let's note that all use cases for all possible programming languages may be clearly classified into two categories: either we write a stand-alone (a.k.a. self-containing) program, or we create something else, like a script or a program for another build-in interpreter, both in no way self-containing. For both scripting languages and those built-in DSLs, the rule set is pretty short: they must be fully interpreted and must not have anything like an 'ecosystem'; both things are naturally derived from the No external dependencies rule.
Whenever we write a stand-alone program, we need a general-purpose language, and for general-purpose langs our rules are much stricter. Before enumerating them in an explicit list, let's mention the essential thing from which everything else is naturally derived here: a general-purpose language must provide mechanism not policy, otherwise it is no longer general-purpose. Surprisingly enough, this obvious principle remains unclear for IT public around.
It is critical to clearly separate the language itself, with all its features, from any features implemented (provided) by libraries. The language, strictly speaking, is what the compiler knows on its own, without any libraries. The notion of “standard library” is a thing to get rid of, it's a mess. No libraries must ever pretend to be a part of the language in any possible sense.
The language (in contrast to libraries) must know nothing about the operating system. No features included with the language (provided by the compiler) may ever be implemented using the operating system's abilities. Hence, all support for input/output and memory management must reside in libraries not in the language. In particular, no features of the language must rely upon dynamic memory.
By the term runtime library we mean such
a set of object code which is needed for the features of the language to
work. The thinner the runtime library is, the better.
The best possible case is zero runtime, as it is for C as a
language (but, unfortunately, not for its implementations like
gcc
, which introduce their own mandatory runtime libs).
It is always better to have a feature in a library than to have the same thing in the language, and it is always better for the language to provide possibilities to implement features than to provide specific features.
Garbage collection is intolerable in general-purpose languages as it seriously limits the purposes the language can be used for; it is okay for a garbage collector to be provided by an optional (not “standard”) library.
There's no such thing as generic data structures. Neither the language itself, nor any of libraries must provide anything like 'generic containers', and no generic containers must ever be written manually.
Any support for multithreading within the language puts the language out of the consideration. This is clearly derived from the abovementioned rule that no features of the language may rely upon the OS, but it is useful to mention this one more time, explicitly.
The only exception for this rule is the plain C 'standard' library (well, the accepted parts of it).
Unfortunately, this is not always achievable, at least at any acceptable costs. However, the best must always be done towards this direction. Cross-dependencies of libraries make the well-known dependency hell way warmer.
And remember, all the necessary libraries must alway be packed along with the main source code of the program.
The single exception mentioned in the preamble appears to be the Rust language. No explanation will ever be provided on why we deliberately and permanently prohibit this bastard for any possible uses, as well as boycott everybody who make public statements Rust is (or even may be) somehow useful. Rust community is a dangerous sect, and like all sectarians, rusters love to argue. No guys, we won't feed your hunger for arguments, and won't waste our time entertaining you with any discussions. You did too much harm to the civilization already, and you're going to do much more of it. We won't help you.
Nowadays, there are only two programming languages that, with a lot of notices and limitations, can be used as general-purpose languages; they are plain C and C++.
This doesn't mean we like them.
We may even hate the two langs, and we can tell a lot of bad things about them.
Alas, the two are all what we have.
We limit plain C (roughly) to what was in C89 plus the
long long
type, and we seriously limit what can be used
from the standard library. We limit C++ to what was in the language
before the very first standard, because the very first C++
standard, C++98, was way too horrible already, and we fully deny any use
of any parts of the C++ standard library.
See the article Acceptable Subsets of Plain C and C++ for more on this.
This list of taboos doesn't include limitations that more the matter of coding style conventions. Definitely we do have a lot of requirements in this area, too.
See the page devoted to coding style requirements and conventions.
“Modern” computers are overpowered, but it is no excuse for wasting computation power. Almost all computers manufactured in 2013 and later are generally unsafe; as of Intel-based machines, they started to be unsafe as early as in 2008. Hence, for us all the gear manufactured before these cursed dates is of special interest.
In particular, we tend to consider the famous Eee PC 900a, which dates back to late 2007, as a kind of reference machine. You must have really serious reasons for your program not being able to run on it; generally, if what you did is not a video editing program nor a cryptocurrency miner, and it still does demand something more powerful than Eee PC 900a, than writing that program was waste of time.
Eee PC 900a has a single-core 32-bit Intel Atom CPU, running at 667 MHz, and only 1 GB of RAM. Yes, you do need to run on it.
And yes, this text has been written in 2025.
We've got enough of corporations, including those grant-eating 'non-profits'. We've got enough of irresponsible commitees. Having sufficient experience, we prefer to work as free individuals and deny collectivization as long as we can.
Sometimes it is necessary to collaborate, and sometimes it is necessary to work together, forming temporary groups. Generally nothing is wrong with collaboration. It is critical however not to let new commitees and corporations born.
It's always better to work alone, but it's not always possible. However, in any group of people working together, there must always be a clearly seen leader, who makes all decisions on his/her own discretion. All the others may discuss and give advices, but no one may ever demand any decision to be made, or cancelled, or changed. Who dislikes what the leader does, are always free to make a fork of the work and continue on their own.
And yes, it should always be possible to make a fork.
Commitees have different names and different faces. They can appear as an advisory board, as a workgroup, as a panel of directors, as a steering council, whatever. What is essential here, is a group of people who vote. Well, who think they are authorized to make decisions for others, and who make decisions by voting.
Don't let commitees appear.
Never propose anything like that. If someone else proposes 'just to elect some people to make decisions', remind him/her that commitees never do anything useful, they only do harm. If someone invites you to such a group, refuse firmly, and feel free to clearly state that you, personally, will never recognize any of their decisions.
If, despite all the resistance, another commitee appears, boycott them. No matter who are 'on board', and how great their achievments are. Commitees, in any form, should be given no right to exist.
Sometimes we have to form groups of people to work together. It is important not to let groups exist longer than they are needed, and it is specially important not to start thinking of a group as of something having value in itself. Only individuals matter, and if members of a certain group decide one day to go each his own way, nothing is actually lost. Indeed, all the persons are still there, and as of the group itself, it never existed as a thing on its own: for a group, 'to exist' just means some people do something together, and that's all. Nothing real actually comes to existence just because some persons decide to collaborate, and nothing real disapperas when they decide not to continue collaborating.
For a group not to become a fetish, it is crucial not to give it a name. Once something gets named, people around start thinking of it as of a real thing.
In particular, if your software project is named 'FooBar', refrain from using terms like 'FooBar team', 'FooBar crew' etc. Instead, list all involved persons explicitly.
If something is owned, it should be owned by a particular individual. This is specially important for two things: copyrights on code and communication resources such as mailing lists, web forums, group chats and other conferences.
Never assign copyrights to non-individual entities. Instead, let all contributors have their own copyright notices, either right in the source files, or maintain a separate file for this purpose, but always list people explicitly, as individuals, not as members of a collective entity.
If you provide some communication facilities for a group or a community, never let people forget who is the host here.
Free speech is a surprisingly complicated matter, mostly misunderstood by all these humanitarian idiots. However, there's a much simpler thing: everyone is free to dispose of their property on their own discretion.
Whenever a group of individuals communicate through the Internet, either publicly, or in a closed environment, no matter, they always need some technical means to do so. They may be using a mailing list, a web-based forum, a group chat or a conference of any other type, the particular technique doesn't matter. However, there's one important thing: any list, forum, chat or a conference has its owner. As we refuse collective ownership, 'the owner' for us always means a clearly defined individual.
The person who owns a forum is the only authority on the forum. Only the owner (a.k.a. host) may (and perhaps should) impose rules. Only the host may decide if something is inacceptable. The host may moderate the forum on his/her own, delegate the moderation to other persons or leave the forum completely unmoderated (which, by the way, is not recommended, but it's the owner who decides).
Those who think someone else's speech is somehow incorrect or inappropriate, are free to quit the forum at any moment and make their own forums with their own rules. But that's all.
It is perhaps also possible to contact the host privately to discuss if something is okay or not, but only provided that the host agrees to discuss. The host, though, is free to refuse any requests for 'justice'.
All this can be said much shorter: no more of those 'codes of conduct'. Unless, of course, the host decides to establish one, but the host is in no way obliged to do so.
In case no formal rules are published for a given forum, it is mostly safe to expect some implicit limits, such as 'stay on topic' or 'refrain from personal insults', but no political correctness nor other leftist nonsense should be expected, unless explicitly stated in the rules established by the host.
Those things provided by corporations 'for free' too often happen to cost too much.
It is absolutely inappropriate to rely on 'free' web-based repository hostings, like GitHub, GitLab, SourceForge and the like. You may, at your discretion, mirror your repositories on something like that, but it must be clearly stated on the appropriate page that no communication, including pull requests, will ever be accepted there, and there must be a clearly visible reference to the main communication facility, such as the web site of your project.
It's just indecent to post any references to things like Google Docs, Google Drive or any other file sharing websites.
It is even more indecent to publish something on FaceBook or another centralized social media site, and expect everyone to be able to read it.
And the last but not least: do your best to have an email address away from those 'free' email providers like Gmail, Yahoo, Proton, Mail.com etc.
As long as you think you're on the RebuildWorld project, you should never mention any of our taboos in a positive manner, unless it is explicitly allowed by the rules of a particular forum.
Please specially refrain from statements like well, I know STL is banned, but if it wasn't, we could perhaps save some time, or okay, I don't advocate for multithreading, but if we could use it, may be this program could be more efficient. Every taboo is there for a reason; if you don't understand the reasons, read the explanations we have, or wait for more of them to appear. If you still disagree and want to challenge the list of taboos, feel free to do so somewhere else, but not here. Remember, you can have your time, but not the time of the others.
It is better not to mention technical standards at all, specially not to reference them, but sometimes we have to. It is very important in every such case to clearly show you don't consider the standard as anyhow normative, and you don't encourage any respect to it.
Some important technical specifications were not written as standards, but later became standards without their creators' will. There's actually nothing wrong with such specifications; it is still useful however that you reference a particular document as a specification, not as a standard, and the fact someone made it an official standard doesn't add anything to your opinion on the specification's quality.
As of RFCs, there's also a simple rule: the later the worse. E.g., the RFCs with numbers less than 2000 may be referenced without limitations, no matter what standarding status they have. On the other hand, RFCs with numbers over 6000 should be avoided and ignored at the best possible effort.