following coffeescript code:
{ baz } = #foo.bar?
produces:
var baz;
baz = (this.foo.bar != null).baz;
but I expect:
var ref, baz;
if ((ref = this.foo.bar) != null) {
baz = ref.baz;
}
Is it a bug or an expected behavior?
I think you've confused the unary ? operator with the binary ?. operator.
The right-hand side of this expression:
baz = #foo.bar?.baz
...uses the binary ?. operator. As you know, it returns the value of the subsequent property if it exists and null otherwise (and short-circuits evaluation of further properties).
On the other hand, the RHS of this expression:
{ baz } = #foo.bar?
...uses the unary ? operator. It returns false if its operand (the preceding expression) is null or undefined, and true otherwise.
This is a really easy mistake to make; you can see someone ask the same question in this CoffeeScript issue. Compounding the problem, the CoffeeScript docs don't even give these two operators different names. They call ? the "existential operator" and ?. the "accessor variant of the existential operator."
Related
Consider the following example
def futureFoo() = {
Future.successful(true)
}
def recFoo(x: List[Int]): Unit = {
if (x.isEmpty) return
for {
b <- futureFoo()
v = getNewListOfValues(x.last)
_ = recFoo(v)
} yield b
}
I need to wait for futureFoo to finish and only then call recFoo again. The problem is no matter what I try I get the following error:
discarded non-Unit value
I also tried to convert it into a while loop but because of the future I either get the same error or the while condition doesn't update because it must be updated in a for comprehension or map.
Any ideas on how to prevent that error?
Try this.
def recFoo(x: List[Int]): Unit =
if (x.nonEmpty)
futureFoo().foreach(_ => recFoo(getNewListOfValues(x.last)))
The specific reason that you are getting
discarded non-Unit value
in your error message is that you have an expression after return.
Note that in Scala, the return keyword should almost never be used. Scala is an expression-oriented language; each block (such as a function body) evaluates to the value returned from the last line in the block.
So, for example, consider the following snippet:
val foo = {
import scala.util.Random
if (Random.nextInt() % 2 == 0) {
17
} else {
"bar"
}
}
Everything from if to the closing brace after "bar" is a single expression -- NOT a statement. Scala, in fact, does not have "if-statements" in the way that Java and other languages do. In particular, the compiler needs to infer a type for the name foo, and since foo could concretely be either the Int 17 or the String "bar", that inferred type is the closest common ancestor of both Int and String, which is Any.
In your question, the last expression in the body of recFoo is the following:
for {
b <- futureFoo()
v = getNewListOfValues(x.last)
_ = recFoo(v)
} yield b
What is the type of this expression? In many languages, for introduces a statement, but that's not true of Scala -- this is an expression, not a statement, and like all expressions it will have a value once we evaluate it. That value has type Future[Unit], and like all non-Unit values, the compiler is warning you that you are discarding a value, which is (almost) always a mistake. (Why would you go to the trouble of producing a non-Unit value and then not make use of it?, goes the thinking.)
I noticed there is a type mismatch caused in the line else if(r1 == 0 || divisors.tail.isEmpty || !divisors.tail.contains(r1)){newAcc}. Because there is no else clause to my if ... else if ...
def euclidianDivision(dividend:Int,divisor:Int):(Int,Int)={
val quotient = dividend/divisor
val remainder = dividend%divisor
(quotient,remainder)
}
def firstExpansion(dividend:Int,divisors:List[Int]):List[(Int,Int)]={
def firstExpansionIter(dividend:Int,divisors:List[Int], acc:List[(Int,Int)]):List[(Int,Int)]= {
val div1:Int = divisors.head
val (q1,r1):(Int,Int) = euclidianDivision(dividend,div1)
val newAcc:List[(Int,Int)] = acc:::List((div1,q1))
if (divisors.tail.contains(r1)){
firstExpansionIter(r1,divisors.tail,newAcc)
}else if(r1 == 0 || divisors.tail.isEmpty || !divisors.tail.contains(r1)){newAcc}
}
firstExpansionIter(dividend,divisors,List((0,0))).tail
}
Here's the error code:
Error:(32, 15) type mismatch; found : Unit required: List[(Int,
Int)]
}else if(r1 == 0 || divisors.tail.isEmpty || !divisors.tail.contains(r1)){newAcc}
I can correct this by adding the else clause, but how come if there is no outcome handled by default, the function tries to return a Unit?
N.B : Corrected code :
def firstExpansion(dividend:Int,divisors:List[Int]):List[(Int,Int)]={
def firstExpansionIter(dividend:Int,divisors:List[Int], acc:List[(Int,Int)]):List[(Int,Int)]= {
val div1:Int = divisors.head
val (q1,r1):(Int,Int) = euclidianDivision(dividend,div1)
val newAcc:List[(Int,Int)] = acc:::List((div1,q1))
if (divisors.tail.contains(r1)){
firstExpansionIter(r1,divisors.tail,newAcc)
}else if(r1 == 0 || divisors.tail.isEmpty || !divisors.tail.contains(r1)){newAcc}
else throw new RuntimeException("Something unexpected happened.")
}
firstExpansionIter(dividend,divisors,List((0,0))).tail
}
I can correct this by adding the else clause, but how come if there is no outcome handled by default, the function tries to return a Unit?
In Scala, unlike more "imperative" languages, (almost) everything is an expression (there are very few statements), and every expression evaluates to a value (which also means that every method returns a value).
This means that, for example, the conditional expression if (condition) consequence else differentConsequence is an expression that evaluates to a value.
For example, in this piece of code:
val foo = if (someRandomCondition) 42 else "Hello"
the then part of the expression will evaluate to 42, the else part of the expression will evaluate to "Hello", which means the if expression as a whole will evaluate to either 42 or "Hello".
So, what is the type of foo going to be? Well, in the then case, the value is of type Int and in the else case, the value is of type String. But, this depends on the runtime value of someRandomCondition, which is unknown at compile time. So, the only choice we have as the type for the whole if expression is the lowest common ancestor (technically, the weak least upper bound) of Int and String, which is Any.
In a language with union types, we could give it a more precise type, namely the union type Int | String. (Scala 3 has union types, so we could give the expression this exact type, although Scala 3 will not infer union types.) In Scala 3, we could even annotate it with the even more precise type 42 | "Hello", which is actually the type that TypeScript is going to infer for the equivalent conditional expression:
const foo = someRandomCondition ? 42 : "Hello"
Now, let's move forward towards the code in the question:
val bar = if (someRandomCondition) 42
What is the type of bar going to be? We said above that it is the lowest common ancestor of the types of the then and else branch, but … what is the type of the else branch? What does the else branch evaluate to?
Remember, we said that every expression evaluates to a value, so the else branch must evaluate to some value. It can't just evaluate to "nothing".
This is solved by a so-called unit value of a unit type. The unit value and type are called the "unit" value and type, because the type is designed in such a way that it can only possibly be inhabited by a single value. The unit type has no members, no properties, no fields, no semantics, no nothing. As such, it is impossible to distinguish two values of the unit type from one another, or put another way: there can only be one value of the unit type, because very other value of the unit type must be identical.
In many programming languages, the unit value and type use the same notation as a tuple value and type, and are simply identified with the empty tuple (). An empty tuple and a unit value are the same thing: they have no content, no meaning. In Haskell, for example, both the type and the value are written ().
Scala also has a unit value, and it is also written (). The unit type, however, is scala.Unit.
So, the unit value, which is a useless value, is used to signify a meaningless return value.
A related, but different concept in some imperative languages is the void type (or in some languages, it is more a "pseudo-type").
Note that "returns nothing" is different from "doesn't return", which will become important in the second part of this answer.
So the first half of the puzzle is: the Scala Language Specification says that
if (condition) expression
is equivalent to
if (condition) expression else ()
Which means that in the (implicit) else case, the return type is Unit, which is not compatible with List[(Int, Int)], and therefore, you get a type error.
But why does throwing an exception fix this?
This brings us to the second special type: Nothing. Nothing is a so-called bottom type, which means that it is a subtype of every type. Nothing does not have any value. So, what then, would a return type of Nothing signify?
It signifies an expression that doesn't return. And I repeat what I said above: this is different from returning nothing.
A method that has only a side-effect returns nothing, but it does return. Its return type is Unit and its return value is (). It doesn't have a meaningful return value.
A method that has an infinite loop or throws an exception doesn't return at all. Its return type is Nothing and it doesn't have a return value.
And that is why throwing an exception in the else clause fixes the problem: this means that the type of the else clause is Nothing, and since Nothing is a subtype of every type, it doesn't even matter what the type of the then clause is, the lowest common supertype of the type of the then clause and Nothing will always be the type of the then clause. (Think about it: the lowest common ancestor of a father and any of his children, grandchildren, great-grandchildren, etc. will always be the father himself. The lowest common ancestor of T and any subtype of T will always be T. Since Nothing is a subtype of all types, the lowest common ancestor of T and Nothing will always be T because Nothing is always a subtype of T, no matter what T is.)
I am reading the book functional programming in Scala and encounter following sentence:
If the evaluation of an expression runs forever or throws an error
instead of returning a definite value, we say that the expression does
not terminate, or that it evaluates to bottom. A function f is
strict if the expression f(x) evaluates to bottom for all x that
evaluate to bottom.
What does the sentence mean? Can someone please show me an example?
Strictness means that if an argument to a function is undefined, then the return value of the function is undefined. That's pretty much it.
The opposite is non-strictness, which means that an expression can have a value even if some of their sub-expressions are undefined.
The vast majority of programming languages are strict. However, most programming languages have at least one non-strict construct: boolean operators. For example, in Scala, this will be undefined (throw an exception):
def foo(bar: Boolean, baz: Boolean) = bar
foo(true, { throw new Exception; false })
Because foo is strict, but this won't:
true || { throw new Exception; false }
//=> res0: Boolean = true
Because || is non-strict in its second argument, which means that the return value can be defined even if some of the arguments are undefined.
Note: strict / non-strict is not the same as eager / lazy.
What is the difference between == and .equals() in Scala, and when to use which?
Is the implementation same as in Java?
EDIT: The related question talks about specific cases of AnyVal. The more general case is Any.
You normally use ==, it routes to equals, except that it treats nulls properly. Reference equality (rarely used) is eq.
TL;DR
Override equals method to compare content of each instance. This is the same equals method used in Java
Use == operator to compare, without worrying about null references
Use eq method to check if both arguments are EXACTLY the same reference. Recommended not to use unless you understand how this works and often equals will work for what you need instead. And make sure to only use this with AnyRef arguments, not just Any
NOTE: On the case of equals, just as in Java, it may not return the same result if you switch the arguments eg 1.equals(BigInt(1)) will return false where the inverse will return true. This is because of each implementation checking only specific types. Primitive numbers dont check if the second argument is of Number nor BigInt types but only of other primitive types
Details
The AnyRef.equals(Any) method is the one overridden by subclasses. A method from the Java Specification that has come over to Scala too. If used on an unboxed instance, it is boxed to call this (though hidden in Scala; more obvious in Java with int->Integer). The default implementation merely compares references (as in Java)
The Any.==(Any) method compares two objects and allows either argument to be null (as if calling a static method with two instances). It compares if both are null, then it calls the equals(Any) method on boxed instance.
The AnyRef.eq(AnyRef) method compares only references, that is where the instance is located in memory. There is no implicit boxing for this method.
Examples
1 equals 2 will return false, as it redirects to Integer.equals(...)
1 == 2 will return false, as it redirects to Integer.equals(...)
1 eq 2 will not compile, as it requires both arguments to be of type AnyRef
new ArrayList() equals new ArrayList() will return true, as it checks the content
new ArrayList() == new ArrayList() will return true, as it redirects to equals(...)
new ArrayList() eq new ArrayList() will return false, as both arguments are different instances
foo equals foo will return true, unless foo is null, then will throw a NullPointerException
foo == foo will return true, even if foo is null
foo eq foo will return true, since both arguments link to the same reference
== is a final method, and calls .equals, which is not final.
This is radically different than Java, where == is an operator rather than a method and strictly compares reference equality for objects.
There is an interesting difference between == and equals for Float and Double types: They treat NaN differently:
scala> Double.NaN == Double.NaN
res3: Boolean = false
scala> Double.NaN equals Double.NaN
res4: Boolean = true
Edit: As was pointed out in a comment - "this also happens in Java" - depends on what exactly this is:
public static void main(final String... args) {
final double unboxedNaN = Double.NaN;
final Double boxedNaN = Double.valueOf(Double.NaN);
System.out.println(unboxedNaN == unboxedNaN);
System.out.println(boxedNaN == boxedNaN);
System.out.println(boxedNaN.equals(boxedNaN));
}
This will print
false
true
true
So, the unboxedNan yields false when compared for equality because this is how IEEE floating point numbers define it and this should really happen in every programming language (although it somehow messes with the notion of identity).
The boxed NaN yields true for the comparison using == in Java as we are comparing object references.
I do not have an explanation for the equals case, IMHO it really should behave the same as == on unboxed double values, but it does not.
Translated to Scala the matter is a little more complicated as Scala has unified primitive and object types into Any and translates into the primitive double and the boxed Double as needed. Thus the scala == apparently boils down to a comparison of primitive NaN values but equals uses the one defined on boxed Double values (there is a lot of implicit conversion magic going on and there is stuff pimped onto doubles by RichDouble).
If you really need to find out if something is actually NaN use isNaN:
Java: https://docs.oracle.com/javase/7/docs/api/java/lang/Double.html#isNaN(double)
Scala: http://www.scala-lang.org/files/archive/api/2.11.8/index.html#scala.Double#isNaN():Boolean
In Scala == first check for Null values and then calls equals method on first object
#lucastex posted about the Java Elvis operator, and I tried something in Scala to get the same effect.
I've just converted everything to a new Structural Type with the ?: operator taking an object of the same type as argument. So Say:
implicit def toRockStar[B](v : B) = new {
def ?:(opt: => B) = if (v == null) opt else v}
val name: String = "Paulo" // example
Why name ?: "Lucas" gets "Lucas" and name.?:{"Lucas"} gets Paulo? The new Structural Type is supposed to return the initial value of anything if it is not null, that is, "Paulo" in the above code.
I'm a bit confused. Any explanation?
Your operator ends in :, which means it reads right to left when in infix notation. For example:
scala> 1 :: Nil == Nil.::(1)
res2: Boolean = true
All methods read left to right in dot notation, though. So you are actually applying your method to Lucas in the infix notation, and to name in the dot notation.
By the way, the Elvis operator was not accepted for inclusion in Java 7.
For the record (finding this thread while searching back the following article...), Daniel Spiewak (another famous Daniel in the Scala world...) posted an article about Implementing Groovy’s Elvis Operator in Scala.