package foo {
object Bar {
def apply(i: Int, j: Int, k: Int) = i + j + k
}
}
object Test {
val x = foo Bar (1, 2, 3)
}
Bar is a perfectly cromulent infix operator.
That feels wrong. It sounds reasonable if infix were limited to cases where the left part of the infix is an expression, and can’t be a package.
It seems that this is also the intention of the spec, which speaks in terms of e0;op1;e1 which seems to imply that the intent is the e's are expressions. But I’m not sure if that’s also the letter.
What are peoples thoughts on this? Is this according to spec? Should it be? And if not, what should be done about it?
A reference to a package takes the form of a qualified identifier. Like all other references, package references are relative. That is, a package reference starting in a name p will be looked up in the closest enclosing scope that defines a member named p.
A designator refers to a named term. It can be a simple name or a selection .
It is a bit ambiguous since in Scala you can’t assign a package (reference) to a val or pass it around to a function, so it feels odd that it can act as a receiver of a method.
Agree with @som-snytt here. What problem is this capability causing? I don’t think syntax should be disallowed for the sake of disallowing it. In cases where there is an actual case that becomes undetectably incorrect then I’d get it. Like adapted args - though I’m a fan, there are a couple of edge cases where it causes a problem (personally I don’t think there ought to be a difference between (A, B) => C and ((A, B)) => C, but everyone else seems to hate it).
So is there a case where foo Bar (1, 2, 3) should mean something else? Or a reason it shouldn’t be allowed?
It’s currently on hold because we’d need some deprecations in the 2.x series to make migration smooth. As a start, the new 2.13 collections have deprecated multi-argument infix operators such as xs += (1, 2, 3). But we’d need to put the deprecations in the compiler so that they can be applied everywhere.
Not even "" + () does what you expect. That is, if you expect to concatenate arbitrary values to a String with String_$plus.
Before someone says it’s fixed in Dotty, there’s a PR for Scala where I noticed usages such as
nextCase APPLY ()
(which will no longer work). In the PR, I rely on the spec language about multi-arg infix to assert that it doesn’t apply to empty args. To me, the eye opener is that these idioms become naturalized.
It also occurs to me that the next iteration of the language should be called neither Scala nor Dotty, but Scotty, after the chief engineer on the Enterprise, and maybe with a nod to kilt-wearers in the community. I think it would go a long way toward advancing Scotty in the enterprise, because it has the aura of folks who get things done. Let’s not forget that the real context of “Beam me up, Scotty!” is that the transporter is malfunctioning and the dilithium crystals are jury-rigged like a Christmas tree.
This also allows expressions like a + b = c , and even if this feature may look useless, I like to know that I can do that (however probably not with package objects)
class Foo {
object + {
def update(arg2: Bar, value: Baz): Baz = {
println(s"assigning: a + b = c: ${Foo.this} + $arg2 = $value")
value
}
}
}
class Bar
class Baz
// this code is correct, prints something like
// assigning: a + b = c: crafts.Foo@33723e30 + crafts.Bar@64f6106c = crafts.Baz@553a3d88
new Foo + new Bar = new Baz
I expected that to concatenate an empty String with a Unit converted to String, giving “()”, and it appears that’s what it does. What else would some one expect?
Two parses I could imagine is that scala parses the () as an empty parameter list, and unit insertion does the rest, and that scala parses the () as unit, and infix notation does the rest.
Only now I realize (timely, I know) that () is not a valid identifier.
Right. It’s inserting a unit into an empty parameter list.
There seem to be two kinds of warnings in Scala: The “this is unlikely to be what you want” warnings and others.
**Welcome to Scala 2.12.4 (OpenJDK 64-Bit Server VM, Java 1.8.0_181).
Type in expressions for evaluation. Or try :help.
“” + ()
:12: warning: Adaptation of argument list by inserting () is deprecated: this is unlikely to be what you want.
signature: String.+(x$1: Any): String
given arguments:
after adaptation: String.+((): Unit)
“” + ()
^
res0: String = ()**