I'd like to know which is considered a best practice when naming predicates in a negative condition.
I'm familiar with the convention of prepending is to the name of a predicate function to express that it returns a true or false value. For example, isGreaterThanFifty(120) clearly expresses the intent of the predicate function, that it will return true if the condition is met. Conversely, should we say !isGreaterThanFifty(120) when we want the negative condition, or would it be better to say isNotGreaterThanFifty(120)?
Should we create a predicate function that expresses:
the positive case (e.g. isValid()) and then use it with the ! (e.g. !isValid()) to negate it when using it
the negative case (e.g isInvalid() or isNotValid()) since that is how we are using it
For example,
if (!isValid(data)) {
return new Error();
}
// do something if it is valid
compared with
if (isNotValid(data)) {
return new Error();
}
// do something if it is valid
I'm looking for code that is more readable and expresses it's intent clearly.
I'm aware that some languages like Ruby allow us to use unless instead of if conditions or even append ? to the end of a function, but most languages do not. So my question is geared towards those languages like JavaScript that do not have such syntax.
There isn't a convention around this that I am aware.
And it should be driven by your actual need, for example are you going to make this call from more than one place (where it actually would benefit the code)? And are you possibly putting a bunch of predicates together, this could affect readability for example: (!isValid()) looks similar to (isValid()) which is why some prefer to use the full condition: (isValid() == false).
Or better yet putting the false on the left which can help prevent accidentally re-assigning a value when attempting to do a condition:
ie: false == isValid vs isValid == false which can be typo-ed or accidentally be replaced by a single = which would be bad news bears.
Use necessity as your driver and also always consider the future you (coming back to the code) and of course, always think of your Teammates.
I find negative names such as isNotValid confusing.
It is OK to use a negative name for a function in a negative context, but if isNotValid() is later used in a positive check, than you get !isNotValid(data). I find double negativity very confusing when reading other peoples code. So, to support future use and positive usage as well I'd go with isValid
Related
I oftentimes see answers using strict comparison (===) instead of normal comparison (==) on status checking, i.e. here:
if(document.readyState === 'complete') ...
I would understand the reason if it were applied on empty string and the obtained value could be also other falsy value with different meaning. But when applied on non-empty string (like 'complete' in the sample), I believe the result is always the same for '==' and '==='. Is that so?
Some people measured that '===' can be faster, but I haven't seen a real world example where it would make any observable difference, so I don't take this micro-optimalization seriously.
On the other hand, anytime I see this operator, I read it as a warning "mind the type here!". But since document.readyState is always string, it annoys me that the original coder made me to study the code what other types there can appear - only to find out that only string.
To me, it is a strong reason to be polite to those who read my code and never use '===' when the type plays no role in the comparison.
Since '===' appears in similar cases in many SO answers and many expert pages, I would like to know if it is just social bandwagon or if there is any good reason why to use it in status checking.
I would recommend always using '===' instead of '==' when strict equality checking is required, which it is in most cases, for this reason: it declares intent. When I see code with '===', I will read it as 'a must be referentially or primitively equal to b'. When I see '==', I will read it as 'a must be coercibly equal to b'. From that, I will judge what kind of goal the code / original programmer is trying to accomplish and how they are passing data around to get the job done. Essentially, it yields insight into the context of the application, the way data is being passed around, and how this function / method / code block fits into the picture.
With that being said, if I see someone do 'a == b' when they are both strings, I'm not going to get on any high horse and make a fuss about it.
It always depends on what you want to achieve, and what you consider to be equal.
== is not always bad, but it often can lead to false assumptions.
If you have something like this:
class TestA {
toString() {
return 'complete'
}
}
class TestB {
valueOf() {
return 'complete'
}
}
let testA = new TestA()
let testB = new TestB()
console.log(testA == 'complete')
console.log(testB == 'complete')
Then testA == 'complete' might be exactly what you want, but because it does an implicit cast, you might do a false assumption about it being a string when it evaluates to true.
So if you later want to call something like substring on it, or passing it to another function that expects an actual string, then it might fail with an unexpected error.
Using === over == is mostly about maintainability, if you start to refactor code or if you look at older code and you see a == you always need to think about if you really want to have an implicit cast at that point or if it this was an accident. So you need to follow the code flow or check if it was documented.
Using an explicitly and === does not prevent you from doing other mistakes, but it keeps the code consistent.
This may border on philosophical, but I thought it would be the right place to ask.
Suppose I have a function that creates a list of IDs. These identifiers are only used internally to the application, so it is acceptable to use ES2015 Symbol() here.
My problem is that, technically, when you ask for a Symbol, I'd imagine the JS runtime creates a unique identifier (random number? memory address? unsure) which, to prevent collisions, would require accessing global state. The reason I'm unsure is because of that word, "technically". I'm not sure (again, from a philosophical standpoint) if this ought to be enough to break the mathematical abstraction that the API presents.
tl;dr: here's an example--
function sentinelToSymbol(x) {
if (x === -1) return Symbol();
return x;
}
Is this function pure?
Not really, no, but it might not actually matter.
On the surface, (foo) => Symbol(foo) appears pure. While the runtime may do some operations with side effects, you will never see them, even if you call Symbol() at the same time with the same parameters. However, calling Symbol with the same arguments will never return the same value, which is one of the main criteria (#2, below).
From the MDN page:
Note that Symbol("foo") does not coerce the string "foo" into a symbol. It creates a new symbol each time:
Symbol("foo") === Symbol("foo"); // false
Looking solely at side effects, (foo) => Symbol(foo) is pure (above the runtime).
However, a pure function must meet more criteria. From Wikipedia:
Purely functional functions (or expressions) have no side effects (memory or I/O). This means that pure functions have several useful properties, many of which can be used to optimize the code:
If the result of a pure expression is not used, it can be removed without affecting other expressions.
If a pure function is called with arguments that cause no side-effects, the result is constant with respect to that argument list (sometimes called referential transparency), i.e. if the pure function is again called with the same arguments, the same result will be returned (this can enable caching optimizations such as memoization).
If there is no data dependency between two pure expressions, then their order can be reversed, or they can be performed in parallel and they cannot interfere with one another (in other terms, the evaluation of any pure expression is thread-safe).
If the entire language does not allow side-effects, then any evaluation strategy can be used; this gives the compiler freedom to reorder or combine the evaluation of expressions in a program (for example, using deforestation).
You could argue the preface to that list rules out everything in JavaScript, since any operation could result in memory being allocated, internal structures updated, etc. In the strictest possible interpretation, JS is never pure. That's not very interesting or useful, so...
This function meets criteria #1. Disregarding the result, (foo) => Symbol(foo) and (foo) => () are identical to any outside observer.
Criteria #2 gives us more trouble. Given bar = (foo) => Symbol(foo), bar('xyz') !== bar('xyz'), so Symbol does not meet that requirement at all. You are guaranteed to get a unique instance back every time you call Symbol.
Moving on, criteria #3 causes no problems. You can call Symbol from different threads without them conflicting (parallel) and it doesn't matter what order they are called in.
Finally, criteria #4 is more of a note than direct requirement, and is easily met (the JS runtimes shuffle everything around as they go).
Therefore:
strictly speaking, nothing in JS can be pure.
Symbol() is definitely not pure, thus the example is not either.
If all you care about is side effects rather than memoization, the example does meet those criteria.
Yes, this function is impure: sentinelToSymbol(-1) !== sentinelToSymbol(-1). We would expect equality here for a pure function.
However, if we use the concept of referential transparency in a language with object identities, we might want to loosen our definition a bit. If you consider function x() { return []; }, is it pure? Obviously x() !== x(), but still the function always returns an empty array regardless of the input, like a constant function. So what we do have to define here is the equality of values in our language. The === operator might not be the best fit here (just consider NaN). Are arrays equal to each other if the contain the same elements? Probably yes, unless they are mutated somewhere.
So you will have to answer the same question for your symbols now. Symbols are immutable, which makes that part easy. Now we could consider them equal by their [[Description]] value (or .toString()), so sentinelToSymbol would be pure by that definition.
But most languages do have functions that allow to break referential transparency - for example see How to print memory address of a list in Haskell. In JavaScript, this would be using === on otherwise equal objects. And it would be using symbols as properties, as that inspects their identity. So if you do not use such operations (or at least without being observable to the outside) in your programs, you can claim purity for your functions and use it for reasoing about your program.
I understand that !! converts anything to a boolean value, but why would you want to do this:
if (!!someObject) { ... }
When you can just do:
if (someObject) { ... }
EDIT:
Just to clarify, I'm simply asking why you would write code like in the first example, rather than that in the second example. Are there any practical differences?
There isn't a significant different between them. So, most likely, it's personal preference or to be explicit about the intent.
Though, it's possibly from an uncertainty/misunderstanding of how or when values are treated as a booleans.
But, both if statements and Logical NOT operators use the internal ToBoolean():
If ToBoolean(GetValue(exprRef)) is true, [...]
Let oldValue be ToBoolean(GetValue(expr))
The operators just add 2 more rounds of ToBoolean() with negation on top of the if statement's own use. But, the result is the same.
I often find that I write IF statements which immediately reference the value of the conditional statement. For example, let's say I need to check to see if a string matches a pattern:
if (mystring.match(/mypattern/) {
var mymatch = mystring.match(/mypattern/)[1];
...
};
I suspect that what I'm looking for doesn't exist, but I've wondered whether you can reference the conditional statement's value within the if block, the way you can reference "arguments" within a function. In many cases, of course, I can rewrite it like this:
var mymatch = mystring.match(/mypattern/)[1];
if (mymatch) { ... };
But that's often not possible if there's a series of methods called. For example:
var mymatch = $('.myclass')[0].text().match(/mypattern/)[1];
... that would throw an exception if there were no item [0] on which to call .text(). Is there some convenient shorthand I'm missing out on? Or a better way to organize things? Just curious, really — I'll go on living if the answer is no.
In cases where relevant you can use the fact that the assignment operator returns a value in JavaScript, so for instance you can write things like:
if (assignedTest = testedValue) {
//value of assignedTest is now available
//and conditional will only be executed if true
This could be used if the RHS was compatible or properly set-up but it's also a huge readability concern since it's very easy to confuse the assignment = with comparison ==/===.
If you were particularly motivated to pursue this you could extract this type of functionality into a function that would behave in a reliable way: such as assigning the result of a closure to a named variable, and you could further tune the behavior to do other things (such as optionally evaluating to a different value within the test). Ultimately it would primarily be making a simple structure more complex though.
I found a way to write the if statement in another way (I think) while searching in the source code of a website.
Instead of:
if(a)b;
or:
a?b:'';
I read:
!a||b;
Is the third way the same as the first two? And if yes, why we would use the third way?
The third way is the same as the previous ones. One argument to use it is saving bytes. A strong argument against using it is readability. You'd better focus on readability in writing code, and use a minimizer (such as Google Closure Compiler) to save bytes.
It can be even shorter:
a && b;
/* !a||b means:
(not a) OR b
which is equivalent to
a AND b
which turns out to be
a && b
*/
Welcome to the concept of short-circuit evaluation. This is well known property of logical operators, employed in different languages. Most often this'll be used as subexpression inside proper if or any other flow control statement, or to express condition short enough so it retains readability in this way, or by automatic transformation to save bytes.
There's even tag for question regarding those: short-circuiting.
The result of the boolean expression sometimes can be evaluated without evaluating all the sub-expressions. If we have A||B, and A is true there's no need to even evaluate B, because the result will be true anyway. This behavior is called "shortcut boolean evaluation" and is defacto standard in most programming languages. It allows to write expressions like if (i < A.length && A[i] == ...) without evaluating the A[i] operand which can lead to an exception if i value is incorrect.
In this particular case, !a||b is the same as if(a)b, yes, but the readability and maintainability of such code is a question though.