Scala map isDefinedAt() vs contains() method - scala

Below is my HashMap:
val params1 = collection.mutable.HashMap[String, Any]()
params1 += "forCourseId" -> "2"
println(params1.isDefinedAt("forCourseId"))
println(params1.contains("forCourseId"))
What is difference between isDefinedAt() & contains() method?
I need to check whether key is present or not
main concern is , it will not throw null pointer exception.

You can check the Scala source code. In MapLike.scala you'll see that isDefinedAt is actually just calling contains, meaning that they are truly identical:
def isDefinedAt(key: A) = contains(key)
The only real difference is that contains is specific to the Map interface (specifically it's declared on GenMapLike), while isDefinedAt is found on all PartialFunction classes.
val m: Map[Int,Int] = Map(1 -> 2)
val pf: PartialFunction[Int,Int] = { case 1 => 1 }
m.isDefinedAt(1) // ok
m.contains(1) // ok
pf.isDefinedAt(1) // ok
pf.contains(1) // doesn't compile

According to the Scala Doc isDefinedAt is equivalent to contains.
This method, which implements an abstract method of trait PartialFunction, is equivalent to contains.
http://www.scala-lang.org/api/current/#scala.collection.mutable.HashMap

Related

Is method semantically equivalent to function in Scala 3?

In Scala 2 as explained here we had a Function Type that was implementing trait FunctionX and Method Type that was a non-value type. We could transform a method to Method Value which was an instance of Function Type like this:
class Sample {
def method(x:Int) = x+1
val methodValue = method _
}
Now in Scala 3, we can leave the underscore so it looks more like this:
class Sample:
def method(x:Int) = x+1
val methodValue = method
Isn't the equality sign suggesting semantic equivalence of method and function value in val methodValue = method? Also in Scala 2 I couldn't use any methods (at least in Scastie with Scala version 2.13.5) on created method like apply but in Scala 3 I can do that suggesting that methods in Scala 3 are regular objects:
scala> val s = Sample()
val s: Sample = Sample#793c2cde
scala> s.method
val res13: Int => Int = Lambda$1530/856511870#ab595e8
scala> s.methodValue
val res14: Int => Int = Sample$$Lambda$1422/1191732945#1bbbede1
scala> s.method.
!= andThen compose finalize isInstanceOf notifyAll →
## apply ensuring formatted ne synchronized
-> asInstanceOf eq getClass nn toString
== clone equals hashCode notify wait
So is Scala 3 functions and methods the same or very similar objects or at least the difference has been significantly reduced?
Isn't the equality sign suggesting semantic equivalence of method and
function value in val methodValue = method?
The key concept to understand is eta expansion which converts methods into functions. Scala 3 has automated this process so
The syntax m _ is no longer needed and will be deprecated in the
future.
Hence methods and functions are not the same, however Scala 3 tries to transparently convert between them so programmers do not have to worry about the distinction.

What do -> and ! mean in Scala

I am reading some Scala code. What does the -> mean in the following context?
var queries = { "Select apple from farm" -> None, "Select orange from fram" -> None, "Select blueberry from anotherFarm" -> Some( #randomStuff ) }
It looks like a list of lambda functions but I thought it should be => in that case instead of ->.
Also,
what does this single line code mean?
def onConnection(id) = { application ! turnOnApplication(id) }
Specifically, I am confused with the use of !. It doesn't seem to be a "NOT" as it is in most languages
The -> symbol is one way to define a tuple in Scala. The below are all equivalent:
val apples1 = "Select apple from farm" -> None
val apples2 = ("Select apple from farm" -> None)
val apples3 = ("Select apple from farm", None)
As for the !:
def onConnection(id) = { application ! turnOnApplication(id) }
! in Scala can be the negation operator, but ! in the above code snippet looks like tell from Akka (Akka is the main actor library for Scala). This pattern is used to send a message to an actor. So if application is a reference to an actor, the code snippet sends the result of turnOnApplication(id) to the application actor. From the linked documentation:
"!" means “fire-and-forget”, e.g. send a message asynchronously and return immediately. Also known as tell.
The thin arrow -> is Tuple syntax. It's just a different way of writing Tuples. I.e.
val x: (Int, String) = 3 -> "abc"
Is the same as writing:
val x: (Int, String) = (3, "abc")
The arrow syntax is done by providing an implicit class ArrowAssoc which defines a method def ->[B](y: B): (A, B). ArrowAssoc is part of Predef which is inserted into every Scala source file. You can find the docs here.
The bracket syntax meanwhile is syntactic sugar done by the compiler.
You can form tuple using two syntaxes
1) Using comma
val tuple = (1, 2)
2) Using -> (arrow)
val tuple = 1 -> 2
Scala repl
scala> val tuple = (1, 2)
tuple: (Int, Int) = (1,2)
scala> val tuple = 1 -> 2
tuple: (Int, Int) = (1,2)
Finding-symbols defines -> as Method provided by implicit conversion. Just look at the methods tagged with implicit that receive, as parameter, an object of type that is receiving the method. For example:
"a" -> 1 // Look for an implicit from String, AnyRef, Any or type parameter
In the above case, -> is defined in the class ArrowAssoc through the method any2ArrowAssoc that takes an object of type A, where A is an unbounded type parameter to the same method.
tutorialPoint definde ! as It is called Logical NOT Operator. Use to reverses the logical state of its operand. If a condition is true then Logical NOT operator will make false.

where is scala get() method been defined

def twoSum(param1: List[Int], param2: Int) = {
val gb = ((param1 combinations 2 toList) find (_.sum == param2) get)
val gb2 = gb map (param1.indexOf(_)) sorted
val index1 = gb2(0)+1
val index2 = gb2(1)+1
println(s" index1 = ${index1}, index2 = ${index2}")
}
In this code, it's using get at second line. my question is where is scala get() method been defined.
Thanks
find returns an Option.
You are therefore calling the get method of the Option class.
find returns an Option, so the get method being called here is defined in the Option class. Specifically it is defined as abstract in Option and the concrete definitions are given in its subclass Some and its "subobject" None.

Why we need implicit parameters in scala?

I am new to scala, and today when I came across this akka source code I was puzzled:
def traverse[A, B](in: JIterable[A], fn: JFunc[A, Future[B]],
executor: ExecutionContext): Future[JIterable[B]] = {
implicit val d = executor
scala.collection.JavaConversions.iterableAsScalaIterable(in).foldLeft(
Future(new JLinkedList[B]())) { (fr, a) ⇒
val fb = fn(a)
for (r ← fr; b ← fb) yield { r add b; r }
}
}
Why the code is written using implicit parameters intentionally? Why can't it be written as:
scala.collection.JavaConversions.iterableAsScalaIterable(in).foldLeft(
Future(new JLinkedList[B](),executor))
without decalaring a new implicit variable d? Is there any advantage of doing this? For now I only find implicits increase the ambiguity of the code.
I can give you 3 reasons.
1) It hides boilerplate code.
Lets sort some lists:
import math.Ordering
List(1, 2, 3).sorted(Ordering.Int) // Fine. I can tell compiler how to sort ints
List("a", "b", "c").sorted(Ordering.String) // .. and strings.
List(1 -> "a", 2 -> "b", 3 -> "c").sorted(Ordering.Tuple2(Ordering.Int, Ordering.String)) // Not so fine...
With implicit parameters:
List(1, 2, 3).sorted // Compiller knows how to sort ints
List(1 -> "a", 2 -> "b", 3 -> "c").sorted // ... and some other types
2) It alows you to create API with generic methods:
scala> (70 to 75).map{ _.toChar }
res0: scala.collection.immutable.IndexedSeq[Char] = Vector(F, G, H, I, J, K)
scala> (70 to 75).map{ _.toChar }(collection.breakOut): String // You can change default behaviour.
res1: String = FGHIJK
3) It allows you to focus on what really matters:
Future(new JLinkedList[B]())(executor) // meters: what to do - `new JLinkedList[B]()`. don't: how to do - `executor`
It's not so bad, but what if you need 2 futures:
val f1 = Future(1)(executor)
val f2 = Future(2)(executor) // You have to specify the same executor every time.
Implicit creates "context" for all actions:
implicit val d = executor // All `Future` in this scope will be created with this executor.
val f1 = Future(1)
val f2 = Future(2)
3.5) Implicit parameters allows type-level programming . See shapeless.
About "ambiguity of the code":
You don't have to use implicits, alternatively you can specify all parameters explicitly. It looks ugly sometimes (see sorted example), but you can do it.
If you can't find which implicit variables are used as parameters you can ask compiler:
>echo object Test { List( (1, "a") ).sorted } > test.scala
>scalac -Xprint:typer test.scala
You'll find math.this.Ordering.Tuple2[Int, java.lang.String](math.this.Ordering.Int, math.this.Ordering.String) in output.
In the code from Akka you linked, it is true that executor could be just passed explicitly. But if there was more than one Future used throughout this method, declaring implicit parameter would definitely make sense to avoid passing it around many times.
So I would say that in the code you linked, implicit parameter was used just to follow some code style. It would be ugly to make an exception from it.
Your question intrigued me, so I searched a bit on the net. Here's what I found on this blog: http://daily-scala.blogspot.in/2010/04/implicit-parameters.html
What is an implicit parameter?
An implicit parameter is a parameter to method or constructor that is marked as implicit. This means that if a parameter value is not supplied then the compiler will search for an "implicit" value defined within scope (according to resolution rules.)
Why use an implicit parameter?
Implicit parameters are very nice for simplifying APIs. For example the collections use implicit parameters to supply CanBuildFrom objects for many of the collection methods. This is because normally the user does not need to be concerned with those parameters. Another example is supplying an encoding to an IO library so the encoding is defined once (perhaps in a package object) and all methods can use the same encoding without having to define it for every method call.

Can I overload parenthesis in Scala?

Trying to figure out out how to overload parenthesis on a class.
I have this code:
class App(values: Map[String,String])
{
// do stuff
}
I would like to be able to access the values Map this way:
var a = new App(Map("1" -> "2"))
a("1") // same as a.values("1")
Is this possible?
You need to define an apply method.
class App(values: Map[String,String]) {
def apply(x:String) = values(x)
// ...
}
For completeness, it should be said that your "apply" can take multiple values, and that "update" works as the dual of "apply", allowing "parentheses overloading" on the left-hand-side of assignments
Class PairMap[A, B, C]{
val contents: mutable.Map[(A,B), C] = new mutable.Map[(A, B), C]();
def apply(a:A, b:B):C = contents.get((a, b))
def update(a:A, b:B, c:C):Unit = contents.put((a, b), c)
}
val foo = new PairMap[String, Int, Int]()
foo("bar", 42) = 6
println(foo("bar", 42)) // prints 6
The primary value of all this is that it keeps people from suggesting extra syntax for things that had to be special-cased in earlier C-family languages (e.g. array element assignment and fetch). It's also handy for factory methods on companion objects. Other than that, care should be taken, as it's one of those things that can easily make your code too compact to actually be readable.
As others have already noted, you want to overload apply:
class App(values: Map[String,String]) {
def apply(s: String) = values(s)
}
While you're at it, you might want to overload the companion object apply also:
object App {
def apply(m: Map[String,String]) = new App(m)
}
Then you can:
scala> App(Map("1" -> "2")) // Didn't need to call new!
res0: App = App#5c66b06b
scala> res0("1")
res1: String = 2
though whether this is a benefit or a confusion will depend on what you're trying to do.
I think it works using apply : How does Scala's apply() method magic work?