Closed sindresorhus closed 5 years ago
As other people already suggested I believe it should be configurable. It is a great idea in general, but there are some tradeoffs.
1) If you are creating this eslint plugin for your own projects then you can set whatever you want;
2) If you are looking to make it a popular feature, then I would go with configurable multiple options. Like { "error": ["e", "err", "error"] }
. Also, you should be able to pass it as a string like { "error": "err" }
.
Every software engineering manager or architect will have their own preference for their project based on their experience and other unknown factors like weather on the day of a project creation.
I know we have conventions and all that,
but that's just a convention.
"Because archaic conventions" is not a great argument
The language you are speaking right now, is in fact a convention as well.
If there are more people calling "newbies" "noobs" than I think "noobs" is defacto standard of modern language, and so does err
is the modern coding defacto standard version of error
For anyone who doesn't remember, err
became popular in JavaScript because at the time, the community had an aversion to names that were simply a camelCase copy of a class. Back then, there were no true classes, no linter rules that could catch mistakes related to capitalization, and this convention made people feel more confident that a variable was definitely an error instance rather than a reference to Error
, perhaps being a typo. These days, those concerns are basically moot. New language features and linter rules have made those problems way less common. We don't pass around classes nearly as often as we used to when there was more ceremony involved in setting up a prototype chain. I think it's about time everyone started using error
instead of err
.
This entire argument is very common and you can find many articles from other languages like C++, Java, Actionscript, etc. Abbreviations and other common-conventions are rarely timeless because they obfuscate the intended meaning and eventually fall out of the common lexicon. While outside the scope of Computer Science, I believe Shorthand in an interesting example of a once ubiquitous and justifiable means to write an abbreviating version of English. Yet, due to advancements in technology, the one ubiquitous skill became obsolete, and as a result, anything authored in Shorthand today would be considered cryptic if not indecipherable by most. To me, it's an example of a collection of abbreviations which did not survive the test of time because the purpose of abbreviating the language was made moot by advancements in technology. In 2019 with lightning fast compilers, excellent IDE's with object-type, code, and templet hinting, there are few good reasons for justifying the using cryptic abbreviations in one's code.
@issuehuntfest has funded $160.00 to this issue. See it on IssueHunt
max
=> maximum
min
=> minimum
How far should we go with this :thinking:
I'd say min
and max
are fine as they are common abbreviations in natural language.
@futpib:
How far should we go with this
Clearly all the way. If it's a good thing, then it's a good thing, so let's make sure to include
json2html
=> javaScriptObjectNotationToHyperTextMarkupLanguage
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.
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.
@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?
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.
But what privileges
x
andy
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...
@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.
Understandable. However, a non-exhaustive ~whitelist~ blacklist of the most common words could at least help the cause.
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.
Just to be clear, the point is not to enforce this for all acronyms/abbreviations. The rule should only enforce this list: https://github.com/sindresorhus/eslint-plugin-unicorn/issues/169#issue-310403396 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.
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?
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?
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.
Report the error but don't auto-fix. Unless, you can think of something smarter?
The only other options I have in mind are
catch-error-name
does (error1
, error2
, etc.)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.
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.
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
.
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.
@stroncium There's already an open PR for this => #237
@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 has rewarded $144.00 to @futpib. See it on IssueHunt
This rule is now available: https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/prevent-abbreviations.md
@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.
constructor (...arguments_) {
super(...arguments_);
this.protocol = 'http:';
this.defaultPort = 80;
}
@sindresorhus It is much more common to use args
, not arguments_
or any other name, in place of arguments
. Here is a couple of examples from popular sites:
I think @sindresorhus suggestion is valid given what this rule is enforcing.
I have just added an exception using whitelist
for props
and args
.
Sorry, you should configure replacements
, not whitelist
, i.e.
"unicorn/prevent-abbreviations": [
2,
{
"replacements": {
"args": false,
"props": false
},
}
]
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.