Brackets needed when using infix approach? - scala

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.

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";

CoffeeScript re-arranges method call parenthesis, why?

I have written this in CoffeeScript:
expect (#controllerInstance[fn]).toHaveBeenCalled()
and it's been compiled to this:
return expect(this.controllerInstance[fn].toHaveBeenCalled());
Why has it re-arranged the method call parenthesis? And how would I make it compile to what I want?
what I need to see is:
expect(this.controllerInstance[fn]).toHaveBeenCalled()
Parentheses serve two purposes in CoffeeScript:
Expression grouping, e.g. (6 + 11) * 23 or f (-> 6), (-> 11).
Function calling, e.g. f(), g('pancakes').
Since parentheses are sometimes optional in a function call, there is some ambiguity in:
f (expr)
Are those parentheses being used to call f with expr as its argument or are the parentheses really a part of f's argument? CoffeeScript chooses the latter interpretation.
You'll see similar problems if write:
f (x) + 1
CoffeeScript sees that as:
f((x) + 1)
Similarly, if you write:
f (x, y)
you'll get an unexpected , error; CoffeeScript doesn't have a comma operator so x, y is not a valid expression.
You can remove the ambiguity by removing the whitespace before the opening parenthesis:
expect(#controllerInstance[fn]).toHaveBeenCalled()
Removing the space after expect forces CoffeeScript to view the parentheses around #controllerInstance[fn] to be seen as function-calling parentheses.

Julia: How do I create a macro that returns its argument?

My question is quite similar to this one, but with a difference. I want to create a macro (or whatever) that behaves this way:
julia> #my-macro x + 2
:(x + 2)
(note that x + 2 is not enclosed in quotes). Is there something like that in Julia? And if there is not, how do I do it? (Please, give a detailed explanation about why it works.)
The input expression to the macro needs to be quoted because a macro returns an expression, which are evaluated, while you would like to get the expression itself, hence you need an extra quoting. The quoting can be done as:
macro mymacro(ex)
Expr(:quote,ex) # this creates an expression that looks like :(:(x + 2))
end
e=#mymacro x + 2 #returns :(x + 2)
Another shorter possibility:
macro mymacro(ex)
QuoteNode(ex)
end
e = #mymacro x + 2 #returns :(x + 2)

Syntax of calling a function in 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)

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.