Win a copy of Programmer's Guide to Java SE 8 Oracle Certified Associate (OCA) this week in the OCAJP forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Unfamiliar Scala syntax

 
Garrett Rowe
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Someone posted this on the Scala mailing list, and I thought it was a pretty cool use of the Scala type system to implement the builder pattern. I'm not sure if its totally useful or not, but I probably wouldn't have imagined this particular use.

http://blog.rafaelferreira.net/2008/07/type-safe-builder-pattern-in-scala.html

After reading through the blog post, I came across this unfamiliar bit of syntax. Can anyone tell me what exactly is going on in this interpreter session. It seems to be just an anonymous subclass of java.lang.Object (why not AnyRef), that has a single method exposed.

[ July 09, 2008: Message edited by: Garrett Rowe ]
 
Marc Peabody
pie sneak
Sheriff
Posts: 4727
Mac Ruby VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That looks like the love child of an anonymous inner class and a closure.

Well, the following snippet:


produces: cool.Crazy$$anon$2@b162d5
and a similar thing happens when you create an actor
scala> val intActor = actor { react {
| case x: Int =>
| // I only want Ints
| println("Got an Int: "+x)
| } }
intActor: scala.actors.Actor =
scala.actors.Actor$$anon$1@34ba6b

(taken rom Artima's Programming in Scala book)

though I think in the actor example, actor is a static method on the Actor class that happens to return one of these weird anonymous things.

And the anonymous returned behaves just like a normal Actor:

scala.actors.Actor$$anon$3@1e4cbc4
hi, Peabody

The notation in your example is the same as:
def foo(arg: String) = new Object{ def printIt = println(arg) }
but I agree that AnyRef should be the more likely candidate since leaving "extends" off of a class definition implicitly extends AnyRef, not Object. The Artima book (page 221) says the two can be used "interchangeably in Scala programs on the Java Platform" but the "recommended style is to use AnyRef everywhere." The footnote points out: "The reason the AnyRef alias exists, instead of just using the name java.lang.Object, is because Scala was originally designed to work on both the Java and .NET platforms. On .NET, AnyRef is an alias for System.Object."
[ July 10, 2008: Message edited by: Marc Peabody ]
 
Garrett Rowe
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So I spent some time today trying to use this "trick" to encode a ternary operator in Scala, it works but for some reason I just can't seem to ge the types right.

Notice the ^:^ function returns an Any instead of an A, if I try to declare that it returns an A I get this:

Any ideas?
 
Marc Peabody
pie sneak
Sheriff
Posts: 4727
Mac Ruby VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I believe the two defs have different 'A's.

The ^:^ can return either the ^?^/ifTrue version of A or the ^:^/ifFalse version of A. If you type the response, the type will use the ^:^/ifFalse, which is not compatible with the other arbitrary type.
 
Garrett Rowe
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This works and the types are as I expect. (I changed the method names because ^?^ was weird and difficult to type)
 
Garrett Rowe
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
After more experimenting and research, I figured out how to do what I was initially trying to do.
 
Garrett Rowe
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Actually, I don't even need the type parameter at the initial implicit conversion. That makes it even simpler.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic