Passing function arguments by Name Scala - scala

I have the following scala code. In this code, I am passing a (global) string name to a function and want to change the string depending on the first argument as shown below:
def retVal(x: (String,String), y: => String) = {if (x._1 != "") {y = x._1;x} else (y,x._2)}
But when I run this code, I get the following error:
y = x._1
^
reassignment to a val
How can I modify the code, so that I get the global string variable get updated when I call this function?

Function arguments are by default immutable in Scala. You cannot assign the a value to the function parameter.
In your case you are trying to assign to a call by name param which is not at all possible.
Also mutating is bad instead return the value and assign it to a new variable.
But still if you want to mutate do something like this
object MutationBox {
var globalString = ""
def retVal(x: (String,String)) = {
if (x._1.nonEmpty) {
globalString = x._1
x
} else (globalString, x._2)
}
}

Related

Scala: Accepting function name as user input

How can we accept function name as user input? Is there any member in standard library ​like readLine, readByte, etc that solves the purpose?
Context: As part of functional programming, I need to pass function name as first argument but instead of hardcoding I want to accept it as user input.
Please suggest.
Here is the sample code:
def square(x:Int):Int = x*x
def sum(f: Int => Int, a:Int, b:Int):Int ={
if(a>b) 0 else f(a) + sum(f,a+1,b)
}
println("Enter the first number:")
var num1 = readInt()
println("Enter the second number:")
var num2 = readInt()
val ressum = sum(square,num1,num2)
User input is a String. Function and method names are not. To go from one to the other you have to test the input content.
val result = usrInput match {
case "foo" => foo()
case "bar" => bar()
case "baz" => baz()
case _ => throw new Error(s"I don't know $usrInput")
}
This assumes that they all have the same return type (and the returned value is of interest). If they return different types then the code gets more convoluted.
if (usrInput == "foo") {
val fooRslt = foo()
// do more "foo" stuff
} else if (usrInput == "bar") {
val barRslt = bar()
// etc. etc.
...
Function and method calls are checked for type safety by the compiler. User input is runtime content. Compile-time, run-time, ne'er the twain shall meet.

What scala expects as a value when it's method accepts '?0' as argument type?

I want to pass a String type argument in a setValue() of vaadin with scala.
Problem :
it shows like def setValue(x$1: ?0): Unit. it means it is expecting some ?0 type of arg.
i don't know how to handle this.
It will be nice if anyone can explain what is this type exactly, what kind of value it accepts and how can I pass String type arg to that method.
Note : setValue(Object newValue) works fine with java.
Here is the code snippet.
def getProcessTreeContainer(): HierarchicalContainer = {
var container = new HierarchicalContainer();
container.addContainerProperty("process", classOf[java.lang.String], null)
val tc = new TableCommon();
var process_menu_data_object_list = tc.getProcessTree();
val size = process_menu_data_object_list.size()
val obj = process_menu_data_object_list.iterator()
while (obj.hasNext()) {
val key = obj.next().id
val parent_key = obj.next().family_id
var name = ""
if (key == parent_key) {
val l = obj.next().name
//println(l.toString()+"...at step 1")
println(("okiiess".asInstanceOf[String]))
var child: Item = container.getItem(container.addItem(key))
child.getItemProperty("process").setValue(l.asInstanceOf)
// arg l.asInstanceOf(), what I am passing in setValue() method, throws NullPointerException.
} else {
container.setParent(key, parent_key)
}
//println("okay...")
}
return container;
}
?0 is not a datatype, it's Scala compiler telling you it doesn't know what the type is. The issue is that child.getItemProperty("process") returns a raw type Property for some reason, which aren't supported in Scala and shouldn't be used in Java either (it should return Property<?> instead). Cast it to Property[String], since you know what its type actually is.

How to mimic Scala's Map/Array assignment syntax in my own class

Following is a simple map entry assignment:
scala> var myl = mutable.Map[String,String]()
myl: scala.collection.mutable.Map[String,String] = Map()
myl("abc") = "123"
I would like to mimic that assignment structure in my own class that works with mutable Tuple's. Now, "getting" a value from a Map is achieved via the "apply" method:
e.g mutable.HashMap:
override def apply(key: A): B = {
val result = findEntry(key)
if (result eq null) default(key)
else result.value
}
I was not however able to find how the map entry is "set" via myMap("myKey") = "myval". A pointer to the Scala source code to do that would be appreciated. Thanks.
The method you want to implement is called update() and takes two parameters, one for the input value passed in parentheses and the other for the assigned value.
class QueryParams {
var params = ""
def update(name: String, value: String) { params += s"$name=$value&" }
}
For example:
val p = new QueryParams()
p("q") = "SFO"
p("start") = "10"
p("rows") = "10"
p.params

Scala: wrong type inference when mapping Strings?

I'm trying to compile simple helloworld in Scala,
and get error "scala: value capitalize is not a member of Char"
Why does compiler think that newW is Char?
val dict = Map(
"hello" -> "olleh",
"world" -> "dlrow"
)
def translate(input: String): String = {
input.split( """\s+""").map(w => dict.getOrElse(w.toLowerCase, w).map(newW =>
(if (w(0).isUpper) newW.capitalize else newW))
).mkString(" ")
}
The second call to map in translate is mapping across the value returned from dict.getOrElse(...), whose type is String, which can be implicitly treated as an Iterable[Char]. Thus, the compiler is correctly inferring that newW is of type Char and complaining when you try to call capitalize on it. You're probably looking for something along the lines of
def translate(input: String): String = {
input.split( """\s+""").map(w => {
val newW = dict.getOrElse(w.toLowerCase, w)
(if (w(0).isUpper) newW.capitalize else newW)
}).mkString(" ")
}
Update: By the way, that will fail at runtime if input is an empty string - it needs at least one more check for safety.
Here's what's happening:
input // is a string
.split( """\s+""") // is an Array[String]
.map(w => // w is a String, for each String in the Array[String]
dict.getOrElse(w.toLowerCase, w) // is a String (returned by dict.getOrElse)
.map(newW => // is a Char, for each Char in the String returned by dict.getOrElse

Can you return an unevaluated function in scala?

Given this code:
def getFunc(funcName:String, param:Int) = match funcName {
case "FooFunc" => FooFunc(param)
[...]
}
def FooFunc(param:Int) = param + SomeObject.SomeVariable
How could I return FooFunc with param applied, without evaluating it? The reason I'd want to do this is because FooFunc, as you can see, relies on an external variable so I'd like to be able to call it with param already applied. What would the return type of getFunc need to be?
Easy:
def getFunc(funcName: String, param: Int) = funcName match {
case "FooFunc" => () => FooFunc(param)
[...]
}
Your method has a good name: getFunc is supposed to return a function, so it will.
The lazyness must be defined at the call site, in Scala. You can do:
lazy val x = getFunc(...) // getFunc only gets evaluated when needed
Or you can change the signature:
def FooFunc(param:Int) = () => param + SomeObject.SomeVariable
...
val x = getFunc(...) // x contains a function from Unit into something
x() // Use x here, causing the evaluation
You could add another void parameter, so the function is only evaluated when it is applied to this parameter.
Though I'd rather use a proper object instead of a function in this case.
I'm sure there's many options, but you can use:
return { Unit => FooFun(param) }