What is this Scala syntax called: new C { i = 5 } // there's a block after the new - scala

I encountered this syntax in someone else's Scala code, and don't remember reading about it:
val c = new C { i = 5 }
It appears that the block after the new C is equivalent to:
val c = new C
c.i = 5
assuming a class definition like:
class C {
var ii = 1
def i_=(v: Int) { ii = v }
def i = ii
}
What is this syntax called in Scala? I want to read more about it, but I can't find it described in Programming in Scala or elsewhere.

You are instantiating an anonymous subclass of C.
It is not equivalent to the code you've shown — try calling getClass on the two instances called c in your snippets.

Related

How to change a base class attribute of a case class

Take the following code:
class A(val i: Int)
case class B(str: String) extends A(1)
val b = B("test")
In my scenario I am restricted by the definition of B which cannot be changed. I also wish to avoid reconstructing B as I have many such objects with a lot more attributes than in this example.
Is there any way I can create a new copy of b (using reflection or otherwise) with a new value for i?
Something that would be the equivalent of:
val b2 = b.copy(i = 2)
NOTE: The question is can it be done? Not what the best programming practice is.
You can do it using reflection with something like this:
val b = B("foo")
val c = b.copy()
println(b.i) // prints 1
val field = classOf[A].getDeclaredFields.head
field.setAccessible(true)
field.setInt(c, 2)
println(c.i) // prints 2
But beware, this is not just "bad programming practice", but rather complete breakage of the contract.
Your declaration case class B(s: Sting) extends A(1) promises that all instances of B will always have i equal to 1, which is a lie.
Not to mention, fun facts like b == c being true or c.copy.i being 1 etc.
Don't do this.
Not if you define B that way. But this code works for me:
class A(val i: Int)
case class B(str: String, override val i:Int=1) extends A(i)
val b = B("test")
val b2 = b.copy(i = 2)
P.S. well technically you can just copy with no modifications and then edit i using reflection but this is not a great idea IMHO.
You can do this:
val b2 = new B(b.str) { override val i = 2 }
The downside is that you have to re-construct B from the parameters which may be cumbersome if there are a lot of them.

Scala currying and type inference

I'm trying to figure out how to use currying in Scala.
In the following snippet:
object Foo {
def foo(a:Int)(b:Int)(c:Int) : Int = a + b + c
def main(a:Array[String]) {
val f = foo(1)(2) _
def g : Int => Int = foo(1)(2)
// def h = foo(1)(2)
println(f(3))
println(g(3))
// println(h(3))
}
}
the definitions for f and g work, the one for h does not:
/home/vlad/Desktop/b.scala:9: error: missing arguments for method foo in object Main;
follow this method with `_' if you want to treat it as a partially applied function
def h = foo(1)(2)
What's the reasoning behind this being illegal? It seems to me that Scala should be able to figure out that after calling foo(1)(2) you'd be left with an Int => Int.
This is intended. If it were allowed (some languages really allow that), that would make it work when you forget to put an argument, and instead of compile-time error you would expect. This happens so often that scala authors decide to trade-off here and disallow this notation.
Martin told about that in his book, see "Why the trailing underscore?" http://www.artima.com/pins1ed/functions-and-closures.html#8.7

Member-wise assignment in scala?

Does scala support memberwise assignment?
Given:
case class C(var x:Int, var y:Int)
val c = C(1,2)
val d = C(3,4)
is there an operator to assign each member of d to c.
In C/C++ you would have:
struct C{ int x, int y)
C c = {1,2}
C d = {3,4}
c = d
edit1
One of the great benefits of member-wise assignment is that its automatic, in
Both
c() = d
and
c.copyFrom( d )
both suffer from a maintenance problem - if new members are added members to C its easy to overlook adding the member to the user-created function. What's really desired is automated way to copy these values.
edit2
Another use case for this behavior:
val props:ThirdPartyType = ThirdPartyLibrary.getProperties()
val myprops:ThirdPartyType = MyLibrary.loadPropertiesFromFile()
props #= myprops // magic member-wise assignment
Here we may find:
We're stuck with ThirdPartyLibrary and ThirdPartyType (can't change it)
The library doesn't provide the ability to reassign the property object.
The library does provide the ability to assign the property's values. It behaves as a JavaBean POJO with public members.
I can do:
props.a = myprops.a
props.b = myprops.b
...
but this pattern break when we update to V2 of the ThirdParty library. ThirdPartyType has gained new members that we didn't not copy.
Can't this be solved through reflection?
The enhancement is easy:
scala> :pa
// Entering paste mode (ctrl-D to finish)
case class C(var x:Int, var y:Int)
val c = C(1,2)
val d = C(3,4)
// Exiting paste mode, now interpreting.
defined class C
c: C = C(1,2)
d: C = C(3,4)
scala> implicit class CUpdater(val c: C) { def update(d: C) = { c.x=d.x ; c.y=d.y } }
defined class CUpdater
scala> c() = d
scala> c
res1: C = C(3,4)
Usual caveats around mutability apply. And you didn't hear it from me.
This will get you a separate object with all case class constructor arguments copied over, although it will not change the original object that d pointed to:
d = c.copy()
If you really want to modify the original object that d points to (perhaps because you have a reference to it somewhere else - think of pointers to structs in the C programming language), then I think you would have to do something fancy with metaprogramming (i.e. reflection or macros) to get a general solution for this.
But I recommend programming with immutable vals, almost always! If you can live with that, copy is fine.

How are "Closures" such a powerful abstraction that object systems and fundamental control structures are implemented using it?

Here is a quote from programming scala chapter 1:
Closures are such a powerful abstraction that object systems and fundamental control structures are often implemented using them
Apparently the statement is not specifically about Scala but Closures in general but I can not
make much sense from it. Perhaps it is some pearl of wisdom only meant for those mighty compiler writers!
So who uses Closures to implement fundamental control structures and why?
Edit: I remember reading something about custom control structures in groovy "using the closure as the last parameter of method call" syntax and making the structure available to your code using meta-classes or use keyword with Categories. Could it be something related?
Edit: I found the following reference of the groovy custom control structures syntax here (slide 38):
Custom control structures
Thanks to closures
When closures are last, they can be put “out” of the parentheses
surrounding parameters
unless(account.balance > 100.euros, { account.debit 100.euros })
unless(account.balance > 100.euros) { account.debit 100.euros }
Signature def unless(boolean b, Closure c)
Apparently what groovy is offering is a syntactic sugar for making the Closure based custom control structures appear like first-class control structures offered by the language itself.
I commented on the case of control structures. Let me comment on closures as objects. Consider what happens when you call a method on an object; it has access not only to the argument list, but also the fields of the object. That is, the method/function closes over the fields. This isn't that different from a "bare" function (i.e., not an object method) that closes over variables in scope. However, the object syntax provides a nice abstraction and modularity mechanism.
For example, I could write
case class Welcome(message: String) {
def greet(name: String) = println(message + ", " + name)
}
val w = Welcome("Hello")
w.greet("Dean")
vs.
val message = "Hello"
val greet = (name: String) => println(message + ", " + name)
greet("Dean")
Actually, in this example, I could remove the "case" keyword from Welcome, so that message doesn't become a field, but the value is still in scope:
class Welcome2(message: String) { // removed "case"
def greet(name: String) = println(message + ", " + name)
}
val w = new Welcome2("Hello") // added "new"
w.greet("Dean")
It still works! Now greet closes over the value of the input parameter, not a field.
var welcome = "Hello"
val w2 = new Welcome2(welcome)
w2.greet("Dean") // => "Hello, Dean"
welcome = "Guten tag"
w2.greet("Dean") // => "Hello, Dean" (even though "welcome" changed)
But if the class refers to a variable in the outer scope directly,
class Welcome3 { // removed "message"
def greet(name: String) = println(welcome + ", " + name) // reference "welcome"
}
val w3 = new Welcome3
w3.greet("Dean") // => "Guten tag, Dean"
welcome = "Buon giorno"
w3.greet("Dean") // => "Buon giorno, Dean"
Make sense?
There are three fundamental control structures:
Sequence
a = 1
b = 2
c = a + b
Conditions
if (a != b) {
c = a + b
} else {
c = a - b
}
Iterations/loops
for (a <- array) {
println(a)
}
So, I guess they mean that internally many languages use closures for control structures (you can look the last two structures).
As an example:
if (a < b) {
for (i = a; a < b; a++) {
println(i)
c = i * i
}
} else {
c = a - b
}
So for is a closure inside the if closure, and else is a closure too. That's how I understand it. They create a closure for the first if if the condition is true, create the closure inside the braces, call it. Then create a closure for the for loop and call it while the condition is true.
And I guess there is no list of languages which use closures internally.
Update:
Just as an example, this is how you can implement your own for loop in Scala (o is cyrillic, so it will compile):
def fоr(start: Unit, condition: => Boolean, increment: => Unit)(body: => Unit): Unit = {
if (condition) {
body
increment
fоr(0, condition, increment)(body)
}
}
var i = 0
fоr (i = 0, i < 1000, i += 1) {
print(i + " ")
}
So actually this is how it can be implemented in other languages on the inner level.
I would say that "closures are such a powerful abstraction..." because unlike standard methods, you have a reference to the calling object, regardless of the scope in which the closure has been called.
In Groovy, for example, you can add a new method, "capitalize" to String type:
String.metaClass.capitalize = {
delegate[0].upper() + delegate[1..-1].lower()
}
"hello".capitalize() // "Hello"
Or, you can do something more complex, like create a domain specific language (DSL) using closures.
class ClosureProps {
Map props = [:]
ClosureProps(Closure c) {
c.delegate = this // pass closure scope to "this"
c.each{"$it"()} // iterate through closure, triggering missingMethod()
}
def methodMissing(String name, args) {
props[name] = args.collect{it} // collect extracted closure properties
}
def propertyMissing(String name) {
name
}
}
Example
class Team {
// the closure
static schema = {
table team
id teamID
roster column:playerID, cascade:[update,delete]
}
}
def c = new ClosureProps(Team.schema)
println c.props.id // prints "teamID"
a) Please try at least googling topics before asking questions.
b) Once you have done that, please ask specific questions.
c) Lexical closures are functions that have access to a lexical environment not available where they are invoked. As such, their parameters can be used to select messages, and pass parameters with those messages. For general control structures, they are not sufficient, unless they can affect the call stack, in the manner of continuations.

Is this Scala code correct?

Why does this code crash the Scala 2.8.1 compiler?
val a = new Array[{ var x = 1 }](3)
Is it a compiler bug?
Anyway is it a legal Scala code? (I want an array of objects with anonymous class type)
Update:
What I want is something like:
class X { var x = 1}
val a = new Array[X](3)
but without having to define standalone X
Compiler crashes are always bugs. But why are you trying to set x equal to 1 in the type declaration?
Your probably want one of these:
val a = new Array[{var x: Int}](3)
val a = Array.fill(3)(new { var x = 1 })
(and the compiler is happy with either of these).
It doesn't crash for me (Scala 2.8), so it is likely a bug.