How does CoffeeScript's existential operator work? - coffeescript

Coffeescript uses the existential operator to determine when a variable exists, and in the coffeescript documentation it shows that something? would compile to something !== undefined && something !== null however I noticed that my version of coffeescript was only compiling this to something !== null so I wrote a test to see how this would effect my code
taco = undefined
if taco?
console.log "fiesta!"
else
console.log "No taco!"
which compiled to
// Generated by CoffeeScript 1.4.0
(function() {
var taco;
taco = void 0;
if (taco != null) {
console.log("fiesta!");
} else {
console.log("No taco!");
}
}).call(this);
and outputted the somewhat unexpected No taco! so my question is two fold. Why does coffeescript no longer check for the value being undefined and why is this suficiant?

The documentation says this about ?:
CoffeeScript's existential operator ? returns true unless a variable is null or undefined, which makes it analogous to Ruby's nil?
so of course this will say "No taco!":
taco = undefined
if taco?
console.log "fiesta!"
else
console.log "No taco!"
Your taco is explicitly undefined so taco? is false.
CoffeeScript implicitly declares variables so the JavaScript form of ? is context dependent. For example, if you just say only this:
if taco?
console.log "fiesta!"
else
console.log "No taco!"
you'll see that taco? becomes typeof taco !== "undefined" && taco !== null. You still see the "is it null" check (in a tighter form) but there's also the "is there a var taco" check with typeof; note that the typeof taco test also checks for taco = undefined so a stricter !== test can be used to see if taco is null.
You say this:
I noticed that my version of coffeescript was only compiling this to something !== null
but that's not what it is doing, it is actually compiling to something != null; note the use of "sloppy" type converting inequality (!=) versus the strict inequality (!==) that you claim is there. The difference between != and !== is important here since:
Null and Undefined Types are == (but not ===)
So if you know that variable v has been declared (i.e. there is var v somewhere) then v != null is sufficient to check that v is neither null nor undefined. However, if you do not know that v has been declared, then you need a typeof check to avoid a ReferenceError when you try to compare an undeclared variable with null. Consider this JavaScript:
if(taco != null) {
console.log("fiesta!");
} else {
console.log("No taco!");
}
That will throw a ReferenceError in your face since taco does not exist. This:
if(typeof taco !== "undefined" && taco !== null)
console.log("fiesta!");
} else {
console.log("No taco!");
}
on the other hand is fine since the typeof check guards against trying to access something that hasn't been declared. I don't think you can construct the first one in CoffeeScript without embedding JavaScript using backticks.

Related

Why is manual null check required when ? operator is there in Flutter?

String playerName(String? name) {
if (name != null) {
return name;
} else {
return 'Guest';
}
}
? checks whether name is null or not, then why is special if (name != null) { condition required?
The String? name means that the parameter name is nullable as you can see lower in the code the if statement then checks if your parameter is not null.
Dart docs definition:
If you enable null safety, variables can’t contain null unless you say they can. You can make a variable nullable by putting a question mark (?) at the end of its type. For example, a variable of type int? might be an integer, or it might be null. If you know that an expression never evaluates to null but Dart disagrees, you can add ! to assert that it isn’t null (and to throw an exception if it is). An example: int x = nullableButNotNullInt!
Link to docs

dart null checking: why do i have to use a null check operator ('!') after checking already for null ( != null ) [duplicate]

This question already has answers here:
"The operator can’t be unconditionally invoked because the receiver can be null" error after migrating to Dart null-safety
(3 answers)
Closed 1 year ago.
I updated my flutter project to nullsafety and get errors saying:
The function can't be unconditionally invoked because it can be 'null'.
Try adding a null check ('!').
For a variable that I already checked for null. What is the correct way to do this now? I know I can just add ! because i know it can't be null. But I don't see why. If there was more code it could happen, that the null check is deleted and the ! operator stays.
Here is my code example:
final Function? suggestionsCallback;
if (widget.suggestionsCallback != null &&
widget.defaultSearchPattern.isNotEmpty &&
pattern.isEmpty) {
return await widget.suggestionsCallback(widget.defaultSearchPattern); // here is the error
} else {
return widget.suggestionsCallback != null
? await widget.suggestionsCallback(pattern) // here is the error
: [];
}
Take a quick look at my code:
class Hello{
final Function? hello;
Hello(this.hello);
}
class Say{
wow(){
var h1 = Hello(null);
if(h1.hello!=null) h1.hello();
}
}
https://dart.dev/tools/non-promotion-reasons#property-or-this
Note: "Promotion" here means "determine that a nullable is in fact not null at this line of code";
Dart compiler is not smart enough to infer that your function, after the if-statement, is NOTNULL at that position of your code. It can only tell a local variable is not null after certain condition statements.
You know the variable can’t be null because you just checked. The compiler doesn’t. So unfortunately you have to tell it again.
Actually your specific compiler might be clever enough, but not all compilers are. And whether you have compile time errors shouldn’t depend on how clever the compiler is. Therefore the language will require the ! test. It’s quite possible that the compiler produced no actual test for the !

Is there a dart function annotation that makes the type checker do type narrowing or condition assertions

Is there a construct that communicates to the type checker a function's post-condition?
For example, in typescript it is possible to say
function assertIsNumber(value: any): asserts value is number {
if (typeof value !== 'number') {
throw new TypeError();
}
}
I would like to be able to do something like the following in dart:
class SomeClass {
int? value;
_checkPreconditions() {
if(value == null) {
throw MyPreconditionError()
}
// ...
}
somefunc() {
_checkPreconditions();
// here we know `value` is a non-null int.
final sum = value + 5;
}
}
I understand I could coerce the value to non-null sum = value! + 5, but I would prefer to allow the function to inform the type checker if possible.
It looks like the type system of Dart is not so powerful. The only thing that looks (from first glance) possible is to create a custom code analyzer package (or search for one that already exists).
Dart annotations don't actually do anything. They provide hints to tools such as the Dart analyzer (usually so that it can generate additional warnings), but they cannot change program behavior. Even if you could convince the analyzer to treat some variables as different types, you still wouldn't be able to compile and run your code.
Annotations can be used by code generation tools, so one possibility might be to generate a statement such as final value = this.value!; automatically. However, that would be a lot of trouble to go through (and would mean that code then would need to use this.value = 42; for assignments and would prevent your code from being analyzed directly).

Unable to match exception instance in test case

The following piece of code returns an instance of an exception if a configuration is missing
if (host == "" || redirectUrl == "" || successUrlParameter == "" || failUrlParameter == "") {
//checktest-USerTransactionService-finishResetCredentials-return exception if host configuration parameters are present
(Some(MissingConfigurationException()),errorRediectedUrl,None)
} else {...}
I am testing this and am matching it like the following
errorThrown mustBe Some(MissingConfigurationException())
The test case fails even though the values seem to be equal.
Expected :Some(utilities.MissingConfigurationException: Server Error. Missing Configuration)
Actual :Some(utilities.MissingConfigurationException: Server Error. Missing Configuration)
how should I compare the expected vs actual value?
Exceptions are compared by reference not by value. Thus, two identical values will always be different, unless they are the same instance.
So, you have to check for the class of the instance.
However. Scalatest provides a better syntax for checking for class and using options.
errorThrown.value shouldBe a [MissingConfigurationException]
Reference:
https://www.scalatest.org/user_guide/using_matchers#checkingAnObjectsClass
https://www.scalatest.org/user_guide/using_OptionValues

mongodb - mapReduce() scope - Undefined values are converted into null values

If I put a variable with an undefined value into the "scope" parameter of mapReduce(), then the map function will receive the variable with a null value (instead of the undefined value). Is that correct?
For example (javascript skeleton for the "mongo" command):
db.mycol.mapReduce(
f_map,
f_reduce,
{
scope: { myvar: undefined}
}
);
function f_map()
{
print("myvar: " + myvar);
}
That will print "myvar: null" (instead of "myvar: undefined") into the server log (into the replicaset member log). Are undefined values converted automatically to null values when passing through mapReduce()?
Yes undefined values get translated into null values in mongodb's v8 engine.
The reason for this is to keep backwards compatibility with the older Spider Monkey JS engine and not break existing code that relied on that behaviour.