Coffee Existential Operator different compliations [duplicate] - coffeescript

This question already has an answer here:
How does CoffeeScript's existential operator work?
(1 answer)
Closed 8 years ago.
Similar to this topic:
CoffeeScript Existential Operator and this
The coffeescript, I'm having a problem using the elvis operator:
foo = ->
y = foo()
console.log 'y is null' unless y?
console.log 'x is null' unless x?
Compiles to:
var foo, y;
foo = function() {};
y = foo();
if (y == null) {
console.log('y is null');
}
if (typeof x === "undefined" || x === null) {
console.log('x is null');
}
Output:
y is null
x is null
So the problem is that since y is assigned earlier that coffee takes the shortcut and assumes that y cannot be undefined. However, it is valid to return undefined from a function.
Is there a "safer" way to check that y is also not undefined?
UPDATED
Clarified Examples and Explanation:
From the comments, in the first if statement (y == null) is using double equal instead of ( x === null) triple equal, as in the second if statement. Clever.

? operator always checks if the value is neither null nor undefined.
y == null is absolutely correct way to check that the value of y is either null or undefined in JavaScript.
For example, the following CofeeScript code checks only for null values:
do_something() if y is null
which compiles to
if (y === null) do_something();
So, while y? (y == null in JS) checks for both null and undefined, y isnt null (y !== null in JS) checks only for null.
Check this answer for more detailed information.
See this answer for more info about equality checks in JavaScript.

Related

Spark Scala compiler not complaining about double vs. triple equals

I get a compiler error if I try this
df.filter($"foo" == lit(0))
forgetting that I need a triple equals in Spark.
However, if I do this, I get the wrong answer but no error:
df.filter($"foo".between(baz, quux) || $"foo" == lit(0))
Can someone explain why compile-time checks help me in the first case, but not the second?
Because $"foo" == lit(0) is always evaluated as Boolean = false.
So in the first case, you trying to call method filter by passing a Boolean whereas it expects a string expression or column expression. Thus you get an error.
Now in the second, case:
$"foo".between(baz, quux) || $"foo" == lit(0) is evaluated as:
(((foo >= baz) AND (foo <= quux)) OR false)
which is accepted beacause you doing an OR || between a column expression ($"foo".between(baz, quux)) and a literal boolean false.
In other words, it is interpreted as $"foo".between(baz, quux) || lit(false)

Why has !== lower precedence than === in Scala?

Following code does not compile:
implicit class TripleEq(val x: Int) {
def === (y: Int) = x == y
def !== (y: Int) = x != y
}
val a = 0
val b = 1
if (a == a && b === b) {
println("Equal")
}
if (a != b && a !== b) {
println("Not equal")
}
The error is:
type mismatch;
found : Int
required: Boolean
The error goes away when I enclose the a !== b in parentheses.
I thought that operator precedence is defined by its first letter (see Tour of Scala) and therefore the precedence of !== should be the same as of ===, != or ==.
Why are parentheses required in the code above?
The answer is in the language specification of Assignment Operators:
There's one exception to this rule, which concerns assignment operators. The precedence of an assignment operator is the same as the one of simple assignment (=). That is, it is lower than the precedence of any other operator.
6.12.14 Assignment Operators
An assignment operator is an operator symbol (syntax category op in Identifiers) that ends in an equals character “=”, with the exception of operators for which one of the following conditions holds:
the operator also starts with an equals character, or
the operator is one of (<=), (>=), (!=).
Based on these rules !== is considered to be an assignment operator, while === is not.

Triggers, #instances in Z3

My problem comes from a large Boogie file. I'll just explain the relevant parts here.
I declare a new type Msg for messages which have 7 fields tID, stype, bal, acc, mbal, mval, val. These fields are declared as functions in Boogie. Then I declared 72 Msg constants M1, ..., M72 and corresponding values of their fields. You can see the following example:
type Msg;
const unique M1: Msg;
function tID (Msg) returns (int);
function stype (Msg) returns (Str);
function bal (Msg) returns (int);
function acc (Msg) returns (Proc);
function mbal (Msg) returns (int);
function mval (Msg) returns (Val);
function val (Msg) returns (Val);
axiom (tID (M1) == 1);
axiom (stype (M1) == s1a);
axiom (bal (M1) == 1);
axiom (acc (M1) == ProcNull);
axiom (mbal (M1) == -2);
axiom (mval (M1) == ValNull);
axiom (val (M1) == ValNull);
where Proc, Str are some types and s1a, ProcNull, ValNull are some constants. Then I declare an axiom which says that two messages m1, m2 are equal if and only if every field of m1, m2. This axiom uses a trigger MsgComp(m1, m2).
function MsgComp(m1, m2: Msg): bool { true }
axiom (forall m1, m2: Msg :: {MsgComp(m1, m2)}
m1 == m2 <==>
(tID(m1) == tID(m2) && stype(m1) == stype(m2) &&
acc(m1) == acc(m2) && bal(m1) == bal(m2) &&
mbal(m1) == mbal(m2) && mval(m1) == mval(m2) &&
val(m1) == val(m2)));
Then, I declare a new variable m and assign arbitrary values to its fields such that m equals M1 or M2. I don't say explicitly m == M1 || m == M2but we can prove this assertion (line 786) with the above axiom.
assert (MsgComp(cMsg, M1) && MsgComp(cMsg, M2) && (cMsg == M1 || cMsg == M2));
However, if I want to check whether m is one of M1, ..., M72, Boogie shows that the corresponding assertion might not hold.
assert (MsgComp(cMsg, M1) && ... && MsgComp(cMsg, M72) && (cMsg == M1 || ... || cMsg == M72));
And I found that if I check that assertion with at most 32 constants, Boogie can verify it. Why can't Boogie or Z3 verify it with more constants?
On my machine, the check does not succeed even for the case of two constants.
I was able to get both checks to pass by changing them to the following form
assert MsgComp(cMsg, M1) && MsgComp(cMsg, M2) ==> (cMsg == M1 || cMsg == M2);
(Notice that the && in the middle has been changed to ==>.)
This also works for the assertion with the 72 values.
I don't know why this change matters. It looks like the conjuncts are ignored or simplified away before triggering happens.

Block statements in anonymous Scala function

I've created this simple anonymous function
var b = (x : Int) => if(x % 2 == 0) x + 1 else x
and it works great. After that I tried to add another statement after the if and before the x+1 statement.
var b = (x : Int) => if(x % 2 == 0) println(x) x + 1 else x
and a that point I received the following compiler error
Cannot resolve symbol x
Please can anyone let me know why this happen?
The reason this happens is that although Scala does not require the use of semi-colons most of the time (unlike Java), since the compiler is more equipped to infer where statements/expressions end, if you have 2 statements/expressions on 1 line then you need to separate them for the compiler.
Your first anonymous function works since if(x % 2 == 0) x + 1 else x is 1 expression.
The compiler is complaining with the second one though since if(x % 2 == 0) println(x) is considered 1 statement. Hence, the next statement starts and there is now no context for x.
Other posters have given you a solution to break the right-side of the function down into separate statements so I won't duplicate - just adding an explanation of why the compilation error occurs since you said you are learning the language. Google about the use of semi-colons in Scala to find out more.
Use this. You need the braces to indicate these are multiple lines:
var b = (x : Int) => if(x % 2 == 0) {
println(x)
x + 1
} else x
Or you can do this.. you need to put that semi colon to indicate to compiler they are separate statements:
var b = (x : Int) => if(x % 2 == 0) { println(x); x + 1 } else x

Type mismatch with If statement containing bitwise operators

I am new to scala but I am having the problem with the following code:
var c:Int = 0
var j:Int = 0
for( c <- 0 to 100){
for( j <- 0 to 100){
/* Check if jth bit in c is set,
if( (c & (1<<j)) ) // this line is the line where i get the error
xs :+ (ys(j)) // this is copying element j from list ys to list xs
}
}
The error I get is:
type mismatch; found : Int required: Boolean
the code (c & (1<<j)) should be shifting 1 left j bits and then bitwise anding the result to the int in the variable c to get a boolean result.
It is entirely possible that I am doing something wrong.. I have been learning Scala fro 3 days and I am very rusty on my java.
Any help would be appreicated
Bitwise operations in Scala (in fact in any language) return a result of type Int, your if expression requires a type of Boolean. Scala doesn't treat Boolean values like C, where you code would work fine.
You can make your expression return a Boolean by testing explicitly for 1:
if((c & (1 << j)) != 0)
Unlike in C (or C++), Scala's if statement (just like Java) only accepts a Boolean expression, and there is no implicit type promotion from integral types to Boolean. So you need to be explicit about what you want, and replace if( (c & (1<<j)) ) with if( (c & (1<<j)) != 0)