Just adding the following text seems to upset some people:
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
It's like they don't want to be pinned down to an exact meaning in design documents! And don't even think about trying to "force" people to use a style guide like RFC 7322, or even an authoritative list of initialisms, acronyms, and abbreviations.
Is it too much to ask to have people use the same term to refer to a project, environment, component, etc? It saves so much time when you don't have to spend effort tracking down what someone means when they say "stage is broken".
This has already gotten too rant-y but it burns my butt so much! So much wasted effort!
Words have meaning, and because language is vague, we help it a little by pinning down the meaning of certain words: this is for clarity, it's not a constraint.
Well it is if you're being judged on compliance to the standard. Have you never worked in government? But hey if you don't like the standard then just make your own: the great thing about standards is there are so many to choose from!
I would agree, except the field of programming seems to have a very large number of pedants. Unfortunately, earlier in my career I was in the room many times where the lead or programmers told the PM or stakeholder "well it didn't say that exactly."
It's been a few years but at least when I worked as a NASA subcontractor those standards were (IMHO) to both ensure compliance to process and frankly spread around the blame if something failed despite compliance. Since none of us are writing code to fly on the Space Shuttle I'll agree with you most of the time pedantry for the sake of it is a waste of time. Still, if someone wants to be a pedant about writing code for an automated teller machine or a voting machine then I'd say it's time well spent.
Even so back in the day ICL managed to ignore a counter MUST start from Zero in implementing an X.400 stack - and you wonder why the uk No longer has a mainframe supplier.
For the ones with minimal English it's often clearer to use phrasing that a native speaker would say is obviously wrong, but matches their native language patterns. Or use simpler but not-quite-appropriate words.
And for the native speakers, the awareness (or self-regulation) to eliminate idioms and less common vocabulary is nigh-impossible for some people.
Why invite such ambiguity? It leads to problems, when the designer writes "shall" and the implementer takes it as a suggestion, or the designer writes "should" and the implementer sinks months trying to satisfy what turns out to be a requirement the implementer intended as optional in light of unknowns.
Clarifying terms eases communication. RFC 2119 isn't about defining basic words of the English language for imbeciles. It's about selecting words to indicate precise levels of compliance. They could have equally named the levels P0, P1, and P2. Instead they chose MUST, SHOULD, and MAY to indicate the same, while reading more easily as part of a sentence.
If 'absolute requirement' is clear enough as plain English in a normal sentence, without having to capitalise it, then why isn't 'must' clear enough?
Let me rephrase: would you have a problem with RFC 2119 if it defined the terms P0, P1, and P2? If so, why? (That would be a bizarre stance to me.) If not, why do you see it as problematic that they chose the words MUST, SHOULD, and MAY, instead of P0, P1, and P2? After all, there's no logical fault in choosing more memorable names.
I see this problem in code often too. Some people think it's sufficient to give functions and variables English names with "obvious" meanings. Yet however "obvious" the meaning is to you, it can be interpreted differently by different people because English is ambiguous. Such symbol names without comments ascribing them a meaning plain English might as well just be "xyzzy", "qwert", and "l33t". English-named symbols are mnemonic devices, nothing more.
Example: the code base I work on as two commonly-used functions, "findObject" and "getObject". One returns a reference to an object only if already cached; the other fetches it from disk if necessary. Which does which? Does "find" mean to go out and actively "find" the object? Or is it referring to the fact that it only returns the object if it is "found" in cache? After all "get" is a pretty active verb. I guarantee you, whoever named these (and didn't document them!) thought like you, that the meanings were "obvious" and "unambiguous". And I bet they were, to that person, at that time, in that context.
I for one, can never remember whether SHALL is mandatory or not, or whether SHOULD indicates nice-to-have-but-not-mandatory, or purely optional. They're terrible English words to use in a formal specification. But the mere fact that RFC 2119 disambiguates them as formal terms in the context of specifications makes them eminently usable for that purpose.
These words already have definitions. You can look them up in a dictionary. Or almost all speakers know them anyway.
Why do we need an RFC, and to write them in capital letters?
What does the RFC add to anything? If you removed the capitalisation and the reference to the RFC then your text means exactly the same thing, as the words already had the same meanings.
> English is ambiguous
Well then how does the RFC solve that problem? Their definitions of these terms are using other English words which are also ambiguous.
> I for one, can never remember whether SHALL is mandatory or not
What do you think 'shall' means in a normal conversation? How could it mean anything except mandatory? In what normal English context does 'shall' mean optional?
If a normal person tells you that you must submit your expenses before the end of the month do you get confused about whether it's required or not? If they write it in capitals and refer you to the RFC do you suddenly understand now?
The same way that a dictionary definition clarifies the meaning of a single English word. By using complete sentences to rule out grey areas.
I see no point in furthering this discussion. Your defeatist assertions like the above "there's no possible way to disambiguate English", your refusal to admit that apparent synonyms such as "must" and "shall" might not be perfect synonyms to people other than yourself, and your repeated sarcasm and snark, suggest to me that you do not see the opposite viewpoint as legitimate, and therefore are not amenable to changing your viewpoint.
Right, so use the dictionary we already have! Why do we need the RFC?
> "there's no possible way to disambiguate English"
This quote isn't from me. I didn't say that - I don't know where you've got it from.
> your repeated sarcasm and snark
Sarcasm and snark? I don't use those rhetorical devices if I can avoid it. I don't think I've used them in this thread at all! I don't know where you've got the idea that I'm not arguing seriously from. I'm sorry I gave that impression.
My legitimate argument is that nobody is honestly confused by words like must - nobody. The RFC is over-the-top formalism where it's not needed.
To me it seems that there could easily be confusion between these two interpretations.
> RFC 2119 defines a standard set of key words for describing requirements of a specification. Many IETF documents have found that these words cannot accurately capture the nuanced requirements of their specification. This document defines additional key words that can be used to address alternative requirements scenarios. Authors who follow these guidelines should incorporate this phrase near the beginning of their document:
> The key words "MUST (BUT WE KNOW YOU WON'T)", "SHOULD CONSIDER", "REALLY SHOULD NOT", "OUGHT TO", "WOULD PROBABLY", "MAY WISH TO", "COULD", "POSSIBLE", and "MIGHT" in this document are to be interpreted as described in RFC 6919.
(Spoiler: this is an April 1st RFC. That said, I have wanted to use or used "OUGHT TO" so many times…)
Are you writing standards for networking, where there could be multiple implementers and you want to be clear to everyone what their implementation has to do? What value do the definitions add? Do people ask questions or have disagreements without the rigorous definitions?
You can pull up ASCE standards, the IBC OR CBC, Caltrans Highway Design Manual or Specs, Greenbook, Any city design manual, etc. etc. They’ll get the idea.
And no, not every design document is intended for professionally-licensed engineers, safety-critical applications, or to be used in legal courts. Even when safety is not at stake, writing remains important.
If you find yourself relying on technical and prescriptive descriptions of language use, isn't it perhaps a good idea to think about what exactly you're trying to convey?
Also it's basically "what that word means in English".
I don't think it takes that long to study.
What is the problem you're actually trying to solve? People not implementing to spec? That's seldom solved by changes to language, and more often solved by an engineer getting asked to fix an incorrect implementation.
It's the same phenomenon of "rubber duck" software engineering, or when you start composing the very rigorous email asking a question of another programmer, then find you've answered your own question before you complete it.
Also, the same general skill for editing text is the same general skill involved in refactoring. You're trying to capture the same semantics, but with a cleaner, more easily digestible structure.
the same could be said for using static types to express the thoughts and formal reasoning rather than english though.
I mention this purely in the interest of pedantry.
I think the ideas are related.
It's layered on top of a quote of Guindon he uses in a book about TLA+ in order to make a point for using math to formally specify systems
The link has changed: http://www.petermichaud.com/essays/the-secret-about-writing-...
Until you put something into words, one way or another, then it's just a fuzzy blob of assumptions and halfway articulated thoughts. The better someone is at writing, the better they're able to articulate their thoughts, even if it's just to themselves.
While we are on this topic, how does one design things? I am very new to this and would love some references. Mostly I implement other’s design in code but I have never designed anything myself.
I am always fascinated by the idea of writing an RFC like document but even that seems a little too far fetched for me as of now.
After many years in the industry, I've actually found that it's better to quickly prototype the various "big pieces" of whatever it is you are designing and learn the constraints of the space you are in first. (You're never going to get everything right with that first attempt at a design.) You can write documents up front explaining what you think your code is going to do, but I would actually not recommend going into too much detail because you only really learn about the problem space you are in by doing.
In terms of a document, keep the initial design light and explain your assumptions, what the technical constraints you face are and how you plan to mitigate them. This is mostly to share out with other people to see if they have concerns about the approach and if they have ideas to help with the process.
That being said, documenting in horrendous detail your actual requirements and your assumptions about the state of the world is more useful than either of the above. When your PM says they want something in "real time" do they mean like RTOS, seconds delayed, or "twice daily" (since the old system was a monthly batch!)? Is it ok to assume the system is 99% correct instead of 100%? Is it ok if a user sometimes gets a duplicated notification?
These types of requirements and assumptions can affect the complexity of a project 10x if they are not handled properly.
I don't know if this is a common technique but I actually like to do a "big bang" type of prototyping where I build out the major pieces all at once to see what the general look and feel of the system is. From there I can make a way more informed decision on what I need to do versus something superficially high level.
For me, the most important thing from early designs is answering the question "what are the unknowns and what are the risks of this project?" and figuring out the right path to remove the unknowns and reduce the risks.
You can certainly fool yourself in code, and think you have the solution, or part of it, when, in fact, you do not. If this was not the case, prototyping would be meaningless, as you could only write correct solutions.
I would advise abhishekjha to try thinking one or two steps ahead before starting to write the corresponding code, and to pay particular attention to where it does not work out as expected, because without practice, one is unlikely to advance beyond trial-and-error programming.
You should also write a reference implementation, because actually implementing something will expose a lot of problems in your assumptions, and it will give other implementers something to test against.
Generally, it's 3-6 months from inception to release of a smaller spec if you want it to be solid.
Actually, you could follow along with a couple of specs I wrote since I have a git history of them:
https://github.com/kstenerud/streamux/commits/master?after=7...
https://github.com/kstenerud/concise-encoding/commits/master...
Sometimes you can get away with documenting a design based on prior art, but without creating your own prototypes.
For the most part, rather than the first, good design documents are the the second or later expression of a design.
Added: I think this ties into what jsty is saying. Good designs tend not to be the first iteration of an idea, regardless whether the iterations were intentional design, or refactoring.
IIRC, Joe Armstrong (RIP) was a firm believer in the "write it once, then throw it out and rewrite it at least once" pattern of development. I think that whether you're writing a design document or a new version of some portion of code, you are refining a design, and that tends to help.
Then figure out what the requirements are that help you meet your goal and write those down.
Once you have a goal and a set of requirements the design is usually pretty easy.
I agree with your point and I also think English is imprecise. It's great for socializing and flushing out ideas but it can also give one a false sense of confidence.
Writing a couple of pages of design docs or an Amazon-style 6 pager or whatever might take a few days of work, but can save weeks or more of wasted implementation time when you realise your system design was flawed or it doesn't address any real user needs.