Some of the naming conventions we use at Sails for nouns like variables, parameters, property names, config settings, database attributes/columns/fields, and so on.
Naming is hard. And naming conventions usually end up being wrong, or incomplete at best.
This may be an unpopular opinion, but in my experience, coming up with new methodologies for variables and such doesn't usually create a lot of value for an individual developer. So why bother?
Aside from the nerd-appeal, the promise of naming conventions for nouns is pretty enticing. From personal experience, I can say for certain that it reduces the amount of time you spend sitting there thinking about what to name something. And it helps debugging as you go along, since you know at a glance what kind of data you're dealing with.
All too often, the trouble is that it's easy to get carried away. Much like a directory structure, you never know whether a naming convention is actually any good until you actually use it. And not just once-- at least a few times.
That means you have to be able to remember it. So simple, easy-to-remember naming conventions tend to be best.
That's hard enough, really, but not only that: once you remember and apply a naming convention, is has to actually be worth it; it must save you time, or help you avoid bugs. It must keep your code consistent in the future as more developers get their hands in the code base.
Or at the very least, a decent naming convention should save you a few seconds of cognitive dissonance.
Over time, we learned that standardizing with suffixes resulted in conventions being actually used more often. I'm not sure why that is exactly, but I can say with certainty that suffixes feel less restrictive than coding with more heavy-handed alternatives. And that means they tend to be more flexible, so you don't need as many. Plus, suffixes are shorter.
It's easier to establish one convention (a suffix called "…At") than it is to establish conventions for "lastActive". I think it might have something to do with the flexibility.
Consider the simple convention many JavaScript developers active in the aughts are probably already aware of: in front-end code using jQuery, variables prefixed with
$
represent a jQuery element set. (I know that's technically a prefix and not a suffix, but hopefully you see my point.)
As far as the words we landed on, it's honestly hard to say why they've worked so well for us. But they have. For me, suitability comes down to what looks and feels right once it's actually written into the code. That said, there are a few guiding priorities we've tried our best to consider. Conventions for naming conventions, if you will.
Here they are, in descending order of priority:
- Above all: explicit and unambiguous
- Short, concise, easy to type, easy to remember
- Familiar English word(s), phrase(s), or abbreviation(s) that devs will likely recognize (even devs who might not be all that familiar with the English language)
Well-established conventions we use every day, and have used for years on customer projects:
- suffix
- a JS timestamp, i.e. a number indicating the number of milliseconds since the unix epoch at 12:00 AM the morning of Jan 1, 1970 (GMT) in Greenwitch, England.
- fun fact: JS timestamps formatted dates sort correctly ASC/DESC as normal strings
- this represents a precise instant in time; but it contains NO INFORMATION about any particular timezone
- this is an absolute metric, like a coordinate -- it refers to a specific timestamp -- a specific moment in time. (In other words, it never refers to a duration. It would never refer to the number of milliseconds between two events, for example.)
- JS timestamps are beautiful because they are truly absolute. It stinks that they aren't more human-readable, but the twin advantages of simplicity and precision more than make up for that, at least for our team.
- e.g.
createdAt
,updatedAt
,lastActiveAt
,disbursedAt
,at
- suffix
- an ISO calendar date, i.e. a string formatted like "YYYY-MM-DD"
- fun fact: YYYY-MM-DD calendar date strings sort chronologically using normal alphabetical string sort, both ASC/DESC (at least in JavaScript and in most databases. Probably in any environment that uses a normal alphabetical string sort algorithm)
- this represents a calendar date; no particular time of day OR timezone, per se
- this is a somewhat absolute metric, like a coordinate -- it refers to a specific calendar date. It does NOT, however, give us enough information to derive a truly absolute timestamp, because (A) we don't know, just from this data anyway, what time of day we're talking about and (B) we don't know, just from this data anyway, in which timezone this calendar date should be understood.
- this is nice because, despite being a little unconventional-looking at first, it is easily human-readable after initial exposure
- finally (and this probably goes without saying) but to be clear: This never refers to a duration. It would never refer to the number of days between two events, for example.)
- e.g.
createdOn
,updatedOn
,disbursedOn
,on
- singular noun
- the result from invoking any kind of function/logic where that result is a dictionary where keys represent abstract concepts about the invocation: its performance, its outcome, its side effects, its errors, and so forth
- this scenario often presents itself when describing the return value of logic that is more of a "doer" than a "finder", but it can arise almost anywhere. For example, consider a
searchTweets
API endpoint. It might indeed respond with an array of tweets, but those tweets might be nestled within a "report"-style response body that also contains additional metadata for pagination. Or consider an HTTP response: a very common kind of report that contains "body", "headers", and "statusCode".
The following are definitely still in a "draft" state, but the Sails team and I are using them actively in all new code we write (and some of the code we refactor) across several real-world projects. That said, new conventions are a big deal. These need more experimentation before we can be reasonably confident that they are good, expressive, simple conventions that are worth sticking with, much less recommending to others. Feedback/ideas are more than welcome!
- suffix
- a tzdb timezone, i.e. a string like "America/Los Angeles" (or any timezone string from tz db: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) that uniquely identifies a particular timezone, with any/all of its UTC offset, daylight savings almanac, its leap year edge cases, and/or any other jurisdictional/cultural traditions that come along with it
- we need this kind of timezone data because UTC offset alone is not enough
- so, should it be …Tz or …Timezone? We've tried it both ways on numerous projects and there are pros and cons. "…Timezone" is great; the only issue with it is that it can lead to bugs caused by developers inconsistently capitalizing the "z" in "zone". That's why this is currently "…Tz" and not "…Timezone"
- e.g.
disbursementTz
,disbursedAtTz
,disbursedOnTz
,tz
- suffix
- a TTL, expressed as a number of milliseconds
- this is a relative metric, like a distance -- it refers to a quantity of milliseconds. (In other words, it never refers to a precise moment in time. It would never refer to the number of milliseconds between the unix epoch and a given event, for example, unless it happened to be understood as the ttl of something cached on Jan 1, 1970 in Greenwitch that happened to be set up to expire by that particular time, purely by coincidence.)
- e.g.
accessTokenExpiresIn
,expiresIn
- suffix
- an iso 24-hour time, i.e. a string formatted like "HH:mm:ss" (Specifically this is an iso 24-hour time expressed in the extended format explained in https://en.wikipedia.org/wiki/ISO_8601#Times)
- this does not refer to a specific moment in time-- for one thing, there is no calendar date information, and no timezone information baked in
- instead, this refers to a particular hour, minute, and second
- it also refers specifically to the BEGINNING of that hour/minute/second. Not necessarily the exact millisecond when the hour/minute/second began, but roughly the beginning. e.g. "at the top of the hour"
- e.g.
createdAtTopOf
,updatedAtTopOf
,disbursedAtTopOf
,atTopOf
- suffix
- a Readable Node.js stream instance
- e.g.
downloading
,uploading
,transloading
,pdfDownloading
,spooling
,reticulating
Things that would benefit from conventions, but for which conventions do not yet exist:
in descending order of perceived importance:
- a way of indicating an array of ISO calendar dates (e.g.
['2020-05-29', '2020-05-30', '2020-07-04']
). Maybe something like "…OnDates"? - something that would elegantly and unambiguously indicate a human-readable/human-friendly day of the week -- e.g. data like "Monday" or "Friday". (This is harder than it sounds-- it would be nice if there was a simple, short word that people already used to unambiguously, cleanly describe this concept, but there kinda isn't. Some examples of what I mean: 1, 2, 3)
- something like "…ExpiresIn", but generic enough to represent any span of milliseconds (not just for TTLs, and not just future-oriented)
- maybe "…During" or "…DuringSecond"? i.e. something like "…AtTopOf", but that doesn't come with the connotation of being at the beginning of the hour/minute/second indicated
- maybe "…DuringMinute"? i.e. something like "…During", but just for hours/minutes (no seconds)
- maybe "…DuringHour"? i.e. something like "…During", but just for hours (no minutes, no seconds)
- e.g. if not for the conflict with the "…ing" / gerund rule above, "finding(s)" would be perfect
- singular noun, plural noun
- the result of submitting a query, sending a request, or invoking any other kind of function/logic whose primary responsibility it is to fetch some kind of data
- the function need not be nullipotent; if the result from that function is a "finding", it just means that the originating function is (philosophically speaking) more of a "finder" than a "doer" (and usually much more of a "finder" than a "doer")
- especially tentative: if such a function returns an array of results (like
.find()
in Waterline), then we might prefer to refer to the return value as "findings" rather than a "finding"