Why does one of these statements compile in Scala but not the other? - syntax

(Note: I'm using Scala 2.7.7 here, not 2.8).
I'm doing something pretty simple -- creating a map based on the values in a simple, 2-column CSV file -- and I've completed it easily enough, but I'm perplexed at why my first attempt didn't compile. Here's the code:
// Returns Iterator[String]
private def getLines = Source.fromFile(csvFilePath).getLines
// This doesn't compile:
def mapping: Map[String,String] = {
Map(getLines map { line: String =>
val pairArr = line.split(",")
pairArr(0) -> pairArr(1).trim()
}.toList:_*)
}
// This DOES compile
def mapping: Map[String,String] = {
def strPair(line: String): (String,String) = {
val pairArr = line.split(",")
pairArr(0) -> pairArr(1).trim()
}
Map(getLines.map( strPair(_) ).toList:_*)
}
The compiler error is
CsvReader.scala:16:
error: value toList is not a member of
(St ring) => (java.lang.String,
java.lang.String) [scalac] possible
cause: maybe a semicolon is missing
before `value toList'? [scalac]
}.toList:_*) [scalac] ^
[scalac] one error found
So what gives? They seem like they should be equivalent to me, apart from the explicit function definition (vs. anonymous in the nonworking example) and () vs. {}. If I replace the curly braces with parentheses in the nonworking example, the error is "';' expected, but 'val' found." But if I remove the local variable definition and split the string twice AND use parens instead of curly braces, it compiles. Can someone explain this difference to me, preferably with a link to Scala docs explaining the difference between parens and curly braces when used to surround method arguments?

Looks like the difference is because you are using the operator notation in the first example. If you add an extra set of parentheses it works:
def mapping: Map[String,String] = {
Map((getLines map { line: String =>
val pairArr = line.split(",")
pairArr(0) -> pairArr(1).trim()
}).toList:_*)
}
or if you don't use the operator syntax it works
def mapping: Map[String,String] = {
Map(getLines.map({ line: String =>
val pairArr = line.split(",")
pairArr(0) -> pairArr(1).trim()
}).toList:_*)
}
I think the problem is that using the normal method invocation syntax has higher precedence than the operator syntax for method calls. This meant that the .toList was being applied to the anonymous function rather than to the result of the map method call.

If you don't use operator syntax, it compiles fine:
//Compiles
def mapping: Map[String,String] = {
Map(getLines.map { line: String =>
val pairArr = line.split(",")
pairArr(0) -> pairArr(1).trim()
}.toList:_*)
}
There is not a problem with how you use the anonymous function, but as Ben mentioned, the syntax of calls map without the . is not equivalent to the typical Java-style method call.

Related

Is there some syntactic sugar for matching on deeply nested Option and Result chains?

I am issuing calls that return an Option that contains a Result which contains another Option that contains custom variants.
I am only ever interested in a specific chain of variant results like this:
if let Some(Ok(Some(CustomVariant(Some(value))))) = expr {
// handle value case
}
This is getting quite verbose and not really helpful, since I actually treat it as a single Result in all of my code. Can I somehow alias this code so that instead of writing the entire chain of Options and Results I can do something similar to:
alias TheCase(value) = Some(Ok(Some(CustomVariant(Some(value))));
if let TheCase(value) = expr {
//handle value
}
You don't need such an alias, just use a function to retrieve the one case you want:
fn oneCaseICareAbout(value: &Option<Result<Option<Foo>, Bar>>) -> Option<&Foo> {
if let Some(Ok(Some(CustomVariant(Some(value)))) = value {
Some(value)
} else {
None
}
}
if let Some(value) = oneCaseICareAbout(expr) {
//handle value
}
I would however consider refactoring your code not to use such a type. Option<Result<_, _>> is already a red flag, but Some(Ok(Some(CustomVariant(Some(…)))) is just on the edge of insanity!

Pattern matching over borrowed HashMap containing enums

I'm trying to learn Rust, so bear with me if I'm way off :-)
I have a program that inserts enums into a HashMap, and uses Strings as keys. I'm trying to match over the content of the HashMap. Problem is that I can't figure out how to get the correct borrowings, references and types in the eval_output function. How should the eval_output function look to properly handle a reference to a HashMap? Is there any good document that I can read to learn more about this particular subject?
use std::prelude::*;
use std::collections::HashMap;
enum Op {
Not(String),
Value(u16),
}
fn eval_output(output: &str, outputs: &HashMap<String, Op>) -> u16 {
match outputs.get(output) {
Some(&op) => {
match op {
Op::Not(input) => return eval_output(input.as_str(), outputs),
Op::Value(value) => return value,
}
}
None => panic!("Did not find input for wire {}", output),
}
}
fn main() {
let mut outputs = HashMap::new();
outputs.insert(String::from("x"), Op::Value(17));
outputs.insert(String::from("a"), Op::Not(String::from("x")));
println!("Calculated output is {}", eval_output("a", &outputs));
}
Review what the compiler error message is:
error: cannot move out of borrowed content [E0507]
Some(&op) => {
^~~
note: attempting to move value to here
Some(&op) => {
^~
help: to prevent the move, use `ref op` or `ref mut op` to capture value by reference
While technically correct, using Some(ref op) would be a bit silly, as the type of op would then be a double-reference (&&Op). Instead, we simply remove the & and have Some(op).
This is a common mistake that bites people, because to get it right you have to be familiar with both pattern matching and references, plus Rust's strict borrow checker. When you have Some(&op), that says
Match an Option that is the variant Some. The Some must contain a reference to a value. The referred-to thing should be moved out of where it is and placed into op.
When pattern matching, the two keywords ref and mut can come into play. These are not pattern-matched, but instead they control how the value is bound to the variable name. They are analogs of & and mut.
This leads us to the next error:
error: mismatched types:
expected `&Op`,
found `Op`
Op::Not(input) => return eval_output(input.as_str(), outputs),
^~~~~~~~~~~~~~
It's preferred to do match *some_reference, when possible, but in this case you cannot. So we need to update the pattern to match a reference to an Op — &Op. Look at what error comes next...
error: cannot move out of borrowed content [E0507]
&Op::Not(input) => return eval_output(input.as_str(), outputs),
^~~~~~~~~~~~~~~
It's our friend from earlier. This time, we will follow the compilers advice, and change it to ref input. A bit more changes and we have it:
use std::collections::HashMap;
enum Op {
Not(String),
Value(u16),
}
fn eval_output(output: &str, outputs: &HashMap<String, Op>) -> u16 {
match outputs.get(output) {
Some(op) => {
match op {
&Op::Not(ref input) => eval_output(input, outputs),
&Op::Value(value) => value,
}
}
None => panic!("Did not find input for wire {}", output),
}
}
fn main() {
let mut outputs = HashMap::new();
outputs.insert("x".into(), Op::Value(17));
outputs.insert("a".into(), Op::Not("x".into()));
println!("Calculated output is {}", eval_output("a", &outputs));
}
There's no need to use std::prelude::*; — the compiler inserts that automatically.
as_str doesn't exist in stable Rust. A reference to a String (&String) can use deref coercions to act like a string slice (&str).
I used into instead of String::from as it's a bit shorter. No real better reason.

Clean exception handling in Scala

In Ruby I often like to handle null values from collections with the following function:
def nilstuff(a,stuff="")
if(a.nil?)
return stuff
else
return a
end
end
In Scala there is an annoyance that empty values in collections throw exceptions, not nil:
val myMap = Map[String, String]()
myMap += ("Apple" -> "Plant")
myMap += ("Walrus" -> "Animal")
println(myMap("Elephant"))
//Exception in thread "main" java.lang.ExceptionInInitializerError
// at MyProgram.main(MyProgram.scala)
//Caused by: java.util.NoSuchElementException: key not found: Elephant
Is there a way to make a similar function in Scala that handles exceptions and returns the "stuff" instead?
println(missing_stuff(myMap("Elephant"),"Unknown"))
You can add a default value to your Map:
scala> import scala.collection.mutable.Map
import scala.collection.mutable.Map
scala> val myMap = Map[String, String]().withDefaultValue("Unknown")
myMap: scala.collection.mutable.Map[String,String] = Map()
scala> myMap("foo")
res0: String = Unknown
Another option is the getOrElse method of Map.
Or apply a pattern match to the result of get:
myMap.get("foo") match {
case Some(value) => useAsDesired(value)
case None => useAsDesired("Unknown")
}
The last might be the most general solution to what your title calls "Clean exception handling."
There are several ways built in.
(1) Don't get the value, get an option.
myMap.get("Elephant")
Now that you have an Option, you can do all sorts of things with it (including get either its contents or a default value if there is none):
myMap.get("Elephant").getOrElse("")
(2) Get the value, or a default value if it's not there
myMap.getOrElse("Elephant", "")
(3) Create the map with a default value (warning--this will not survive filtering, mapping, or any other handy collections operations). Immutably you'd add this after you were done building the map:
val defaultMap = myMap.withDefault(_ => "")
defaultMap("Elephant")
With a mutable map, you might add it at the beginning:
val myMap = new collection.mutable.HashMap[String,String].withDefaultValue("")
(4) Add the item that you're missing when you find it not there (mutable maps only):
myMap.getOrElseUpdate("Elephant", "Dumbo")
Probably not what you want in this particular case, but often useful.

Expression.Block method gives different errors in c#

Let us have the following:
Func<string, int> counterOfChar = (myString) => {
Console.WriteLine("Here is my parameter "+myString);
return myString.Count();
};
I want to bring all expressions involved here , by defining them so:
Expression<Action<string>> first = (param) => Console.WriteLine("Here is my parameter "+param);
Expression<Func<string, int>> second = (param) => param.Count();
And then call Expression.Block(first, second); as an example .
I am struggling for a week now and I don't want to tell you how diverse are the errors received until this moment.
Can someone write the corresponding Block and lambda expression for the delegate, but not going deep into ex: Method.Call ? Just stick to expressions !?
Thank you!
Expression<Action<string>> first = (param) => Console.WriteLine("Here is my parameter " + param);
Expression<Func<string, int>> second = (param) => param.Length; // .Count() is useless here!
Expression<Func<string, int>> third =
Expression.Lambda<Func<string, int>>(
Expression.Block(first.Body,
Expression.Invoke(second, first.Parameters[0])),
first.Parameters[0]);
var f = third.Compile();
var r1 = f("Hello");
"merging" two Expressions is always a little complex, because the two param of the two expressions are "different". They aren't the same param (it's like one is param1 and the other is param2). Here we resolve it by reusing the first parameter of the first expression as the parameter of the "new" expression and Expression.Invoke the other expression.
Without cheating, we could have
var par = Expression.Parameter(typeof(string));
Expression<Func<string, int>> third =
Expression.Lambda<Func<string, int>>(
Expression.Block(
Expression.Invoke(first, par),
Expression.Invoke(second, par)),
par);
var f = third.Compile();
var r1 = f("Hello");
where we introduce a new parameter par and we Expression.Invoke the other two expressions.
Note that Entity Framework doesn't support Expression.Invoke. In this case you can use a parameter rewriter (something like this.)

A list of predefined groovy variables

I'm new to groovy and I'm wondering where can I find a full list of predefined
groovy variables like it and delegate?
The particular thing that I'm interested in is if there are predefined keyword for
the reference to the object from where the current method was invoked, for example:
5.times { print 5 - it}
with the use of such keyword it should be something like:
5.times { print *keyword* - it }
so the question is what's the keyword should be used there?
P.S.: another example:
MyObject myObject = new myObject();
myObject.getField(); // MyObject has method named getField
myObject.doJob ({
...
((MyObject)*keyword*).getField(); // instead of myObject.getField();
...
})
For a good list of all actual keywords (which are fewer than you'd think) and object-level properties that are like keywords, this article is really good: http://marxsoftware.blogspot.com/2011/09/groovys-special-words.html
If you have control over the doJob method in your example, then you should set the delegate of the closure:
def doJob(Closure closure) {
closure.delegate = this
closure.resolveStrategy = Closure.DELEGATE_FIRST
// loop or whatever
closure()
}
Now, in your closure, you can reference any properties on the parent object directly, like so:
myObject.doJob ({
...
getField()
...
})
Groovy Closures - Implicit Variables.
Are you asking for this?
int number = 5
number.times { print number - it }
Hope this will help you

Resources