Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rule proposal: Prevent abbreviations #169

Closed
sindresorhus opened this issue Apr 2, 2018 · 81 comments

Comments

Projects
None yet
@sindresorhus
Copy link
Owner

commented Apr 2, 2018

Issuehunt badges

Using complete words result in more readable code. Not everyone knows all your abbreviations. You only write code once, but it's read many times.

For a start, we could go with these:

  • err => error
  • cb => callback
  • opts => options
  • str => string
  • obj => object
  • num => number
  • val => value
  • e => event/error
  • evt => event
  • el => element
  • req => request
  • res => response/result
  • btn => button
  • msg => message
  • len => length
  • env => environment
  • dev => development
  • prod => production
  • tmp => temporary
  • arg => argument
  • args => arguments
  • tbl => table
  • db => database
  • ctx => context
  • mod => module

Also i => index, but I have a feeling, that it's going to be too controversial.

Suggestions welcome for additional ones. Also looking for people's thoughts on this rule.

futpib earned $160.00 by resolving this issue!

@lukechilds

This comment has been minimized.

Copy link

commented Apr 2, 2018

Honestly, I think they're all quite controversial.

I agree with you that that in general abbreviations are not good variable names, but I personally prefer the shorter version of most of these and I think they're pretty widely understood. I'd say err is probably even more common than error. It's in all the official Node.js docs.

Also, how reliable will this be? What if cb is an abbreviation for circuit breaker. Obviously that's a bad variable name but it shouldn't be automatically changed to callback.

@sindresorhus

This comment has been minimized.

Copy link
Owner Author

commented Apr 2, 2018

But is it really worth sacrificing readability over saving a few characters? Swift has taught me a lot about writing readable code. Some would say it's too verbose, but I also think JS is generally too concise.

I know we have conventions and all that, but should we maybe stop and question those? I feel like everyone just does it because everyone else does it, without actually considering whether it's worth the downsides.

I'd say err is probably even more common than error. It's in all the official Node.js docs.

Neither the Node.js API nor docs are known for their approachability or user-friendliness, though.

Also, how reliable will this be? What if cb is an abbreviation for circuit breaker. Obviously that's a bad variable name but it shouldn't be automatically changed to callback.

I didn't intend for it to have auto-fixing, but if it did, it could only fix the non-ambiguous cases.

@jamesmosier

This comment has been minimized.

Copy link

commented Apr 3, 2018

arr => array

I've also seen elem => element but I see you have el above (which is more popular).

@FezVrasta

This comment has been minimized.

Copy link

commented Apr 3, 2018

event is also seen as evt quite often

@frontend-3

This comment has been minimized.

Copy link

commented Apr 3, 2018

btn -> button
msg -> message

@TGC79

This comment has been minimized.

Copy link

commented Apr 3, 2018

len -> length

@savetheclocktower

This comment has been minimized.

Copy link

commented Apr 3, 2018

Abbreviations like obj and str, though arguably slightly less readable than object and string, are at least unambiguous. If this rule were to exist, it seems like it would be more useful if it targeted ambiguous abbreviations. For example: I've seen e used for both event and error, and it's made me more likely to write out event and error as a result just for clarity.

Hence, I have no problem with cb, evt, or req — I don't think I've ever come across one of those and not known what it was meant to stand for. I think val is a poor thing to name a variable, but value is just as bad — the problem there is the vagueness in the name, not the abbreviation.

@sindresorhus

This comment has been minimized.

Copy link
Owner Author

commented Apr 3, 2018

Abbreviations like obj and str, though arguably slightly less readable than object and string, are at least unambiguous.

Are they though? Only if you know that str always means string, which it usually does, but that's just a convention. It could just as easily be short for strength.

I think val is a poor thing to name a variable, but value is just as bad — the problem there is the vagueness in the name, not the abbreviation.

I agree, value is not a good name, but what would you call a variable that could be any value? You could call it any, but I don't think that's clearer.

@sindresorhus

This comment has been minimized.

Copy link
Owner Author

commented Apr 3, 2018

If you, for example, disagree with err=>error, I'm curious about why? It's only two extra characters and it improves readability. "Because archaic conventions" is not a great argument.

@savetheclocktower

This comment has been minimized.

Copy link

commented Apr 3, 2018

Are they though? Only if you know that str always means string, which it usually does, but that's just a convention. It could just as easily be short for strength.

It could, if you're building an RPG. In the general case I think that those abbreviations are common enough that (e.g.) str presumptively means string, and if you need strength then you should just type strength.

I agree, value is not a good name, but what would you call a variable that could be any value? You could call it any, but I don't think that's clearer.

This is the one caveat I should've added to my original comment, but I was growing tired of typing. :)

@mantoni

This comment has been minimized.

Copy link

commented Apr 3, 2018

I personally also base naming decisions on scope size. While having a catch(e) with a single line might be easy to read, a long function with short names becomes unreadable very quickly.

So as a rule of thumb, I’d say the larger the scope the more descriptive the variable names should be.

@mischah

This comment has been minimized.

Copy link

commented Apr 3, 2018

The following ones came to my mind spontaneously:

  • env => environment
  • dev => development
  • prod => production
  • t => test
@abdullahtariq1171

This comment has been minimized.

Copy link

commented Apr 3, 2018

tmp => temporary
ans => answer

@therealklanni

This comment has been minimized.

Copy link

commented Apr 3, 2018

Are we also considering shorthands like a/b/x => any, fn => function?

const curry = fn => a => b => fn(a, b)

I see this a lot more in more academic uses, though it does happen in the real world as well.

@praveenv4k

This comment has been minimized.

Copy link

commented Apr 3, 2018

arg => argument
args => arguments
rec => record
tbl => table
db => database

@therealklanni

This comment has been minimized.

Copy link

commented Apr 3, 2018

args => arguments is almost necessary, since arguments is reserved.

@felixfbecker

This comment has been minimized.

Copy link

commented Apr 3, 2018

I agree with avoiding abbreviations in general, but I think the problem with this rule is that it will forbid all the abbreviations that are okay because they are widely understood (e.g. err) while allowing all the abbreviations that are not common/context-dependent. It's hard to come up with concrete examples for this, but if I read most Go codebases they have 1-3 letter variable names everywhere, that are not only non-descriptive, they also make reading the code influent.

So I think a rule like this instead of blacklisting abbreviations, should for example check variable names against an English dictionary and/or enforce a minimum character length.

@sindresorhus

This comment has been minimized.

Copy link
Owner Author

commented Apr 3, 2018

Are we also considering shorthands like a/b/x -> any, fn -> function?

I think x and a & b are usually fine in inline arrow functions if it's clear from the context what they refer to.

@sindresorhus

This comment has been minimized.

Copy link
Owner Author

commented Apr 3, 2018

args => arguments is almost necessary, since arguments is reserved.

Not in arrow functions, which I personally use most of the time.

@sindresorhus

This comment has been minimized.

Copy link
Owner Author

commented Apr 3, 2018

I agree the main focus should be to reduce ambiguity, the other cases could potentially be opt-in.

@therealklanni

This comment has been minimized.

Copy link

commented Apr 3, 2018

Not in arrow functions, which I personally use most of the time.

That's fair, but then you have to ask yourself if you want consistency, too.

@sindresorhus

This comment has been minimized.

Copy link
Owner Author

commented Apr 3, 2018

@therealklanni If I had to choose, I would pick readability over consistency.

@savetheclocktower

This comment has been minimized.

Copy link

commented Apr 3, 2018

I think this has the potential to be the worst of all possible bikesheds, and you'll hear from three groups of people:

  1. people who would like this rule and would use it to help them stick to new conventions;
  2. people who already don't abbreviate these things and want to make their collaborators abide by the same rules; and
  3. people who have opinions about abbreviations in code, generally speaking, but wouldn't use this rule.

If the goal is to ship this rule with a recommended set of abbreviations to avoid, my guess is that you won't find a consensus for more than a tiny handful of identifiers.

@sindresorhus

This comment has been minimized.

Copy link
Owner Author

commented Apr 3, 2018

@savetheclocktower This is just exploratory right now. I'm happy to hear all opinions. The main focus is the ambiguity aspect, which I don't think many would object to. I've personally been using the non-abbreviations in my code for a while now. I'm liking it so far, but it takes some getting used to.

@hugmanrique

This comment has been minimized.

Copy link

commented Apr 3, 2018

ctx => context
mod => module

@kalisjoshua

This comment has been minimized.

Copy link

commented Apr 3, 2018

I use these pretty often:

_ => when I don't actually care about it - usually in an arguments list - but need it to take up the position
indx => index because index is a reserved word in JS
attrs => attributes because I'm super laz

@therealklanni

This comment has been minimized.

Copy link

commented Apr 3, 2018

index is not a reserved word.

@loilo

This comment has been minimized.

Copy link

commented Apr 3, 2018

If you, for example, disagree with err=>error, I'm curious about why?

I'm not sure why I feel uncomfortable with those expanded terms replacing all those rather well-known abbrevations, but I think I've come up with a possible explanation.

  1. I, personally, as a user of these abbrevations, find them clearer than the long names. That's however only learned behaviour and could certainly be retrained.

  2. What I'm not sure about: I think it makes me uncomfortable because it bloats the code, just in pure character count.

    I feel like my chances of getting the hang of a snippet by taking a quick glimpse are greater for

    let spread = (arr, cb) => cb(...arr)

    than they are for

    let spread = (array, callback) => callback(...array)

    I'd mainly attribute that to the shorter line length, I can register more code at once in the same field of view — but I can't say that for sure. It could as well just be because of 1.

@therealklanni

This comment has been minimized.

Copy link

commented Apr 3, 2018

  1. What I'm not sure about: I think it makes me uncomfortable because it bloats the code, just in pure character count.

That's what minifiers are for (and character count is largely irrelevant for server-side)

@andrepolischuk

This comment has been minimized.

Copy link

commented Apr 3, 2018

I see the following sometimes:

ns -> namespace
prop -> property
ref -> reference
dt -> date
cmd -> command

@felixfbecker

This comment has been minimized.

Copy link

commented Jan 28, 2019

I mean, how would the rule be implemented? I assume it would use some kind of dictionary/wordlist to check that all terms are actual words, and error on any term not found in the dictionary? So if the abbreviation is common enough that it would appear in the dictionary, like HTML, then that would be allowed, but msg, obj, val, etc certainly all would not be.

@sonicdoe

This comment has been minimized.

Copy link

commented Jan 28, 2019

As a rough guideline, I also feel like acronyms are usually okay whereas abbreviations are not.

For example, acronyms such as HTML, API, or URL are arguably more well-known and therefore result in more readable code. If I would be talking about a uniform resource locator, you’d probably have to do a double-take to actually understand what I’m referring to.

On the other hand, abbreviations such as env or msg are arguably not as easily understood as their counterparts “environment” and “message”. You would also never use such abbreviations in spoken language.

@CrossEye

This comment has been minimized.

Copy link

commented Jan 28, 2019

@sonicdoe: Note that all of those are considered abbreviations.

Two common types of abbreviations are acronyms and initialisms. HTML, API and URL are all initialisms, and not acronyms. (You pronounce them as individual letters.) . Things like NATO or SCUBA are acronyms. (You pronounce them as words.) . Other abbreviations such as env and msg are neither of these, and you don't pronounce them directly, although I personally always pronounce "msg" as "message".

My problem is that it's really hard to find a consensus on the allowable alternative. You probably don't want to write

const point = new PointOnTheCartesianPlane(horizontalAxisValue, verticalAxisValue)

when you could simply write

const point = new Point(x, y)

But what privileges x and y here?

@sonicdoe

This comment has been minimized.

Copy link

commented Jan 28, 2019

I don’t want to derail too much so I’m just going to link to the Nomenclature section of the Acronym article from Wikipedia. In short, one may draw a line between initialisms and acronyms but it’s not a clear-cut thing. In any case, I think the meaning behind my argument was clear.

@loilo

This comment has been minimized.

Copy link

commented Jan 28, 2019

But what privileges x and y here?

I'd say what privileges x and y is general knowledge, they're not at all tied to the software development world. However I agree that this can be hard to categorize, it would probably be easy to find examples where it's not that easily decided.

There's probably no hard and fast rule — I'd say, if you have two choices, you'll go with the one that appears more comprehensible for a decently tech-savvy non-programmer. However this seems incredibly hard to decide for an algorithm/linter...

@CrossEye

This comment has been minimized.

Copy link

commented Jan 28, 2019

@sonicdoe: sorry, I try not to let pedantry slip in; I failed there. Still, my main point is simply "How do we draw the lines?" If we're working on a calendaring application, event can be awfully confusing when it applies to both the business logic (calendar events) and UI primitives (HTML event.) . I would choose to use evt -- possibly even e -- for the UI event here, reserving event for the business object. And there are many such cases, which makes it seem extremely difficult to maintain a reasonable list.

@loilo: that difficulty for an algorithm is what concerns me here.

@loilo

This comment has been minimized.

Copy link

commented Jan 28, 2019

Understandable. However, a non-exhaustive whitelist blacklist of the most common words could at least help the cause.

@loilo

This comment has been minimized.

Copy link

commented Jan 28, 2019

I think we can all agree that this problem is not fully machine-solvable with current technology, so a curated blacklist is probably the only viable approach.

That said, we should discuss way less about whether individual terms should be blacklisted, but rather try to agree on a deciding question to "ask" for those terms — roughly like this, but probably still more precise:

Assuming usage in a reasonable context, is the abbreviation more comprehensible and clear for a tech-savvy non-programmer than any alternative long word?

This still omits aspects like proportionality (we probably should not use a comprehensible 100 character word for an identifier even if it's more comprehensible than a 5 character term) etc., but I guess we just cannot leave out common sense from this whole topic.

That said, if the declared question is not clearly and easily answered, then we got to the point where we'd have to draw a line.

So, I think your concerns are valid @CrossEye, but if we can find a reasonable, standardized approach to blacklisting terms, those concerncs should very much be the exception rather than the rule.

@sindresorhus

This comment has been minimized.

Copy link
Owner Author

commented Jan 30, 2019

Just to be clear, the point is not to enforce this for all acronyms/abbreviations. The rule should only enforce this list: #169 (comment) Additional entries can be discussion in new issues later on.

Everything in that list will be enabled by default and people can disable individual words if they want, like:

{
	words: {
		err: false
	}
}

It should also be possible to set your own words and replacements.

It should be possible to choose, both for the built-in and custom words, on individual words, whether the word should be auto-fixable or not.

If there are multiple replacements, auto-fix will not run, and the error message will include all the possible words, for example, e could be event or error.

If the user tries to enable auto-fix for a word with multiple replacements, it should be an error.


The list of words should be added directly to this plugin and not be in a separate module for now, so we can iterate faster.

@futpib

This comment has been minimized.

Copy link
Collaborator

commented Jan 30, 2019

I'd like to implement this rule (even though I'll probably end up disabling it).

What should the rule do if the preferred identifier is already taken?

@sindresorhus

This comment has been minimized.

Copy link
Owner Author

commented Jan 31, 2019

What should the rule do if the preferred identifier is already taken?

Report the error but don't auto-fix. Unless, you can think of something smarter?

@sindresorhus

This comment has been minimized.

Copy link
Owner Author

commented Jan 31, 2019

I would also like to see an additional option that let's users disable all the built-in words by default (builtInWordsEnabledByDefault: true or something shorter). This can be useful for companies/projects that want to supply their own totally custom list of words.

@futpib

This comment has been minimized.

Copy link
Collaborator

commented Jan 31, 2019

Report the error but don't auto-fix. Unless, you can think of something smarter?

The only other options I have in mind are

  • Do not even report it
  • Do what catch-error-name does (error1, error2, etc.)
@sindresorhus

This comment has been minimized.

Copy link
Owner Author

commented Jan 31, 2019

Do what catch-error-name does (error1, error2, etc.)

This would actually be nice. The less I have to fix manually the better.

I doubt it will come up that much anyway. Why would anyone use both an acronym and its long-form in the same scope for different variables? Could happen, but I can't imagine it's that common.

@futpib

This comment has been minimized.

Copy link
Collaborator

commented Feb 1, 2019

While coming up with tests, some expected awkward interactions between built-in arguments special and our args => arguments renaming surfaced.

Currently my plan is to make the rule prevent the collision with the special arguments by renaming to arguments2 (just like when colliding with common variables).

@sindresorhus please take a look at the WIP tests, maybe we should instead allow the args abbreviation, at least when colliding with arguments special (or when in a class method, or allow args altogether). Fixing every super(...args) into super(...arguments2) seems unreasonable.

image

@sindresorhus

This comment has been minimized.

Copy link
Owner Author

commented Feb 3, 2019

maybe we should instead allow the args abbreviation, at least when colliding with arguments special (or when in a class method, or allow args altogether). Fixing every super(...args) into super(...arguments2) seems unreasonable.

Yeah, I don't see a good way around this. Let's allow args when it collides with arguments.

@stroncium

This comment has been minimized.

Copy link
Contributor

commented Feb 7, 2019

I took a freedom to rethink the concept a bit to make the rule more general and usable by more people. It should also help testing various rules before finalizing default rule sets.

Initial rules implemented in default rule set, community suggestions implemented in extended rule set, but it is also fully configurable for highly specific and differently opinionated use cases.

I also used the name prefer-better-name as it seems to suit the rule better.
However, if needed the rule can be reverted to original specification in #169 by changing a couple of names.

@sindresorhus

This comment has been minimized.

Copy link
Owner Author

commented Feb 7, 2019

@stroncium There's already an open PR for this => #237

@stroncium

This comment has been minimized.

Copy link
Contributor

commented Feb 7, 2019

@sindresorhus Well, it wasn't put in submitted, and by the time I realized there was a PR, I've had it done already. Anyhow, perhaps you will find my version more useful. If not than so shall it be.

sindresorhus added a commit that referenced this issue Mar 13, 2019

Add `prevent-abbreviations` rule (#237)
Fixes #169


Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
@IssueHuntBot

This comment has been minimized.

Copy link

commented Mar 13, 2019

@sindresorhus has rewarded $144.00 to @futpib. See it on IssueHunt

  • 💰 Total deposit: $160.00
  • 🎉 Repository reward(0%): $0.00
  • 🔧 Service fee(10%): $16.00
@sindresorhus

This comment has been minimized.

@gajus

This comment has been minimized.

Copy link

commented Apr 26, 2019

@sindresorhus

Not in arrow functions, which I personally use most of the time.

It is a problem with ES6 classes, though.

constructor (...args) {
  super(...args);

  this.protocol = 'http:';
  this.defaultPort = 80;
}

is raising a "unicorn/prevent-abbreviations" warning.

@sindresorhus

This comment has been minimized.

Copy link
Owner Author

commented Apr 29, 2019

constructor (...arguments_) {
  super(...arguments_);

  this.protocol = 'http:';
  this.defaultPort = 80;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.