Syntax of calling a function in scala - scala

Hi I am studying the scala language and have a question. I am reading a book and one of the example says that 0 to 2 is same as (0).to(2). How can I interpret this syntax?? I mean, I can see that to is a function that takes one integer value as its parameter. But what is "(0)." part?? Thanks

In scala any method taking a single parameter can be written with infix syntax.
So for instance if you have
class Foo(x: Int) {
def add(y: Int) = x + y
}
val a = new Foo(42)
then these two method calls are exactly equivalent
a.add(4) // 46
a add 4 // 46
The reason why there's a parenthesis around the 0 is that in older versions of scala the 0. would have been interpreted as a floating point number, due to the ambiguous value of . (which can be both a decimal separator and a method selector). Since scala 2.11 (or 2.10, I don't remember), this has been fixed, so you can now safely type
0.+(2) // Int: 2
and get an Int back, whereas you would have had a Float in the past, as the compiler would have seen it as
0.0 + (2) // Float: 2

I mean, I can see that to is a function that takes one integer value as its parameter.
No, it's not a function, it's a method.
Methods are invoked by sending a message to an object:
foo.bar(baz)
This means "send the message bar with the object referenced by baz as argument to the object referenced by foo. This will in turn cause the method bar in foo's class or one of its ancestors to be invoked.
So, to is the message, 2 is the argument, and 0 is the receiver of the message.
Scala allows you to use either a . or whitespace for message sending:
foo bar(baz)
// is the same as
foo.bar(baz)
Also, when using whitespace for message sending, you can leave off the parentheses of the last argument list if it has only a single argument:
foo bar baz
// is the same as
foo bar(baz)
And lastly, parentheses are not only used for argument lists, they are also used for grouping. (And tuple literals as well.) You can always surround an expression with parentheses to clarify its precedence:
(foo).bar(baz)
// is the same as
foo.bar(baz)

Related

Why it evaluates to string?

I have following expression:
1 + "c"
as the result I've got
1c
I guess, because the compiler convert the expression to:
1.toString + "c"
For me it is not logic at all, I expect an exception, because the first argument of the expression is an Int, it determines the result type.
If it would be reverse like
"c" + 1
Then I agreed, that the value should be a String.
Why does the compiler not throw an exception on the first expression?
It's because scala.Int has member method +(x: String): String
1 + "c" is just a syntax sugar of 1.+("c"), which is calling + member method of 1 with argument "c".
From: http://docs.scala-lang.org/style/method-invocation.html#infix-notation
Scala has a special punctuation-free syntax for invoking methods that
take one argument. Many Scala programmers use this notation for symbolic-named methods
As ymonad wrote, conversion is done by + operator in scala.Int.
Please keep also in mind that such convention is compatible with java where you could write:
String 1c = 1 + "c";

Specman: Why DAC macro interprets the type <some_name'exp> as 'string'?

I'm trying to write a DAC macro that gets as input the name of list of bits and its size, and the name of integer variable. Every element in the list should be constrained to be equal to every bit in the variable (both of the same length), i.e. (for list name list_of_bits and variable name foo and their length is 4) the macro's output should be:
keep list_of_bits[0] == foo[0:0];
keep list_of_bits[1] == foo[1:1];
keep list_of_bits[2] == foo[2:2];
keep list_of_bits[3] == foo[3:3];
My macro's code is:
define <keep_all_bits'exp> "keep_all_bits <list_size'exp> <num'name> <list_name'name>" as computed {
for i from 0 to (<list_size'exp> - 1) do {
result = appendf("%s keep %s[%d] == %s[%d:%d];",result, <list_name'name>, index, <num'name>, index, index);
};
};
The error I get:
*** Error: The type of '<list_size'exp>' is 'string', while expecting a
numeric type
...
for i from 0 to (<list_size'exp> - 1) do {
Why it interprets the <list_size'exp> as string?
Thank you for your help
All macro arguments in DAC macros are considered strings (except repetitions, which are considered lists of strings).
The point is that a macro treats its input purely syntactically, and it has no semantic information about the arguments. For example, in case of an expression (<exp>) the macro is unable to actually evaluate the expression and compute its value at compilation time, or even to figure out its type. This information is figured out at later compilation phases.
In your case, I would assume that the size is always a constant. So, first of all, you can use <num> instead of <exp> for that macro argument, and use as_a() to convert it to the actual number. The difference between <exp> and <num> is that <num> allows only constant numbers and not any expressions; but it's still treated as a string inside the macro.
Another important point: your macro itself should be a <struct_member> macro rather than an <exp> macro, because this construct itself is a struct member (namely, a constraint) and not an expression.
And one more thing: to ensure that the list size will be exactly as needed, add another constraint for the list size.
So, the improved macro can look like this:
define <keep_all_bits'struct_member> "keep_all_bits <list_size'num> <num'name> <list_name'name>" as computed {
result = appendf("keep %s.size() == %s;", <list_name'name>, <list_size'num>);
for i from 0 to (<list_size'num>.as_a(int) - 1) do {
result = appendf("%s keep %s[%d] == %s[%d:%d];",result, <list_name'name>, i, <num'name>, i, i);
};
};
Why not write is without macro?
keep for each in list_of_bits {
it == foo[index:index];
};
This should do the same, but look more readable and easier to debug; also the generation engine might take some advantage of more concise constraint.

Brackets needed when using infix approach?

Really simple Scala question.
How come the infix approach to 1 + 2 does not need brackets?
scala>1 + 2
res7: Int = 3
But the dot approach does?
scala>1 .+(2)
res8: Int = 3
scala> 1 .+2
<console>:1: error: ';' expected but integer literal found.
1 .+2
^
Everything in Scala is an object so 1 .+(2) means to call method + on object 1 with parameter 2. And of course if you call a method like this, you need to enclose parameters in brackets, just like in regular obj.somemethod(someparam,foo,bar).
Infix notation (1 + 2) actually means the same thing (it is syntactic sugar to call method with one parameter).
And the space before dot is needed so that dot is interpreted as method invocation and not as decimal separator. Otherwise 1.+(2) or 1.+2 will be interpreted as 1.0 + 2.
I think it's to do with language definition:
A left-associative binary operation e1 op e2 is interpreted as e1.op(e2).
http://www.scala-lang.org/docu/files/ScalaReference.pdf
The form 1 .+ 2 is not specified anywhere so my guess is that the compiler is looking for either 1 + 2 or 1.+(2). In fact the compiler converts 1+2 into 1.+(2) normally. When using the . it expects a function and not the infix syntax.
Bottom line: you can use either but not something half way there.
PD: someone commented that calling a method you need to use it like this: obj.somemethod(someparam,foo,bar) but on that case you can also do this: obj somemethod (someparam,foo,bar) and you have to leave the spaces for it to work.

Scala closures on wikipedia

Found the following snippet on the Closure page on wikipedia
//# Return a list of all books with at least 'threshold' copies sold.
def bestSellingBooks(threshold: Int) = bookList.filter(book => book.sales >= threshold)
//# or
def bestSellingBooks(threshold: Int) = bookList.filter(_.sales >= threshold)
Correct me if I'm wrong, but this isn't a closure? It is a function literal, an anynomous function, a lambda function, but not a closure?
Well... if you want to be technical, this is a function literal which is translated at runtime into a closure, closing the open terms (binding them to a val/var in the scope of the function literal). Also, in the context of this function literal (_.sales >= threshold), threshold is a free variable, as the function literal itself doesn't give it any meaning. By itself, _.sales >= threshold is an open term At runtime, it is bound to the local variable of the function, each time the function is called.
Take this function for example, generating closures:
def makeIncrementer(inc: Int): (Int => Int) = (x: Int) => x + inc
At runtime, the following code produces 3 closures. It's also interesting to note that b and c are not the same closure (b == c gives false).
val a = makeIncrementer(10)
val b = makeIncrementer(20)
val c = makeIncrementer(20)
I still think the example given on wikipedia is a good one, albeit not quite covering the whole story. It's quite hard giving an example of actual closures by the strictest definition without actually a memory dump of a program running. It's the same with the class-object relation. You usually give an example of an object by defining a class Foo { ... and then instantiating it with val f = new Foo, saying that f is the object.
-- Flaviu Cipcigan
Notes:
Reference: Programming in Scala, Martin Odersky, Lex Spoon, Bill Venners
Code compiled with Scala version 2.7.5.final running on Java 1.6.0_14.
I'm not entirely sure, but I think you're right. Doesn't a closure require state (I guess free variables...)?
Or maybe the bookList is the free variable?
As far as I understand, this is a closure that contains a formal parameter, threshold and context variable, bookList, from the enclosing scope. So the return value(List[Any]) of the function may change while applying the filter predicate function. It is varying based on the elements of List(bookList) variable from the context.

Why does Scala's semicolon inference fail here?

On compiling the following code with Scala 2.7.3,
package spoj
object Prime1 {
def main(args: Array[String]) {
def isPrime(n: Int) = (n != 1) && (2 to n/2 forall (n % _ != 0))
val read = new java.util.Scanner(System.in)
var nTests = read nextInt // [*]
while(nTests > 0) {
val (start, end) = (read nextInt, read nextInt)
start to end filter(isPrime(_)) foreach println
println
nTests -= 1
}
}
}
I get the following compile time error :
PRIME1.scala:8: error: illegal start of simple expression
while(nTests > 0) {
^
PRIME1.scala:14: error: block must end in result expression, not in definition
}
^
two errors found
When I add a semicolon at the end of the line commented as [*], the program compiles fine. Can anyone please explain why does Scala's semicolon inference fail to work on that particular line?
Is it because scala is assuming that you are using the syntax a foo b (equivalent to a.foo(b)) in your call to readInt. That is, it assumes that the while loop is the argument to readInt (recall that every expression has a type) and hence the last statement is a declaration:
var ntests = read nextInt x
wherex is your while block.
I must say that, as a point of preference, I've now returned to using the usual a.foo(b) syntax over a foo b unless specifically working with a DSL which was designed with that use in mind (like actors' a ! b). It makes things much clearer in general and you don't get bitten by weird stuff like this!
Additional comment to the answer by oxbow_lakes...
var ntests = read nextInt()
Should fix things for you as an alternative to the semicolon
To add a little more about the semicolon inference, Scala actually does this in two stages. First it infers a special token called nl by the language spec. The parser allows nl to be used as a statement separator, as well as semicolons. However, nl is also permitted in a few other places by the grammar. In particular, a single nl is allowed after infix operators when the first token on the next line can start an expression -- and while can start an expression, which is why it interprets it that way. Unfortunately, although while can start a expression, a while statement cannot be used in an infix expression, hence the error. Personally, it seems a rather quirky way for the parser to work, but there's quite plausibly a sane rationale behind it for all I know!
As yet another option to the others suggested, putting a blank newline between your [*] line and the while line will also fix the problem, because only a single nl is permitted after infix operators, so multiple nls forces a different interpretation by the parser.