Porting Java To Scala
Upcoming SlideShare
Loading in...5
×
 

Porting Java To Scala

on

  • 4,837 views

In this talk we contrast and compare the interface of the Java Bindings ...

In this talk we contrast and compare the interface of the Java Bindings
with the development and design of the Scala bindings and interfaces, with
particular reference to the introduction of Scala language specific features
such as the use of Options and the Scala Actors model.

Statistics

Views

Total Views
4,837
Views on SlideShare
4,337
Embed Views
500

Actions

Likes
2
Downloads
39
Comments
1

4 Embeds 500

http://skillsmatter.com 389
http://www.slideshare.net 73
http://smash 37
http://www.docshut.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • Watch the podcast here: http://skillsmatter.com/podcast/java-jee/nigel-warren-channing-walton-scala-fly-object-space/rl-311
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Porting Java To Scala Porting Java To Scala Presentation Transcript

  • > <---- ---------> <---- > DEVELOPING THE SCALA BINDINGS FOR THE FLY OBJECT SPACE Channing Walton Nigel Warren channing.walton@casualmiracles.com nige@zink-digital.com http://www.casualmiracles.com/ CM, Java experience, CRE, UCL Presentation about my experience porting from Java to Scala
  • INTRODUCTION State safe co-ordination and communication between distributed system components. http://www.casualmiracles.com/
  • SPACES Tuple Spaces - Linda (a coordination language) in - put a tuple into a space rd – get a copy of a tuple from the space out – remove tuple from the space Subsequently … Java Spaces - Jini – Java Rinda – Ruby PyLinda – Python etc., etc. http://www.casualmiracles.com/
  • FLY Fly is an ‘Object Space’ Network wide - Object level - Storage and Matching Matching – by Object Templates Object Serialisation – Native to a language or language neutural Leasing – Information and resources have prescribed lifetimes http://www.casualmiracles.com/
  • FLY PRIME INTERFACE public interface FlyPrime { long write(Object entry, long leaseTime); Object read(Object template, long waitTime); Object take(Object template, long waitTime); } http://www.casualmiracles.com/
  • DESIGN DIAMOND Minimise Interface Complexity Minimise Uses http://www.casualmiracles.com/
  • FLY SPACE DESIGN Minimal But Complete Interface Write Read Take Threading Object Locking Distribution Matching Expiring Pthreads Minimal Use of Sockets OS interfaces Malloc - Free http://www.casualmiracles.com/
  • FLY SPACE INTERFACE HIERARCHY Fly MultiFly NotiFly writeMany notifyWrite readMany notifyTake takeMany FlyPrime write read take http://www.casualmiracles.com/
  • FLY SCALA Scala Application Scala Application Client Client Scala Space Scala Space Interface Interface Scala Binding Scala Binding Fly Server http://www.casualmiracles.com/
  • FROM JAVA TO SCALA • Syntactic Conversion • Idiomatic API • Idioms Internally • Actors • Java and Scala Compared • What Next? http://www.casualmiracles.com/
  • SYNTACTIC public interface NotiFly extends FlyPrime { boolean notifyWrite(Object template, NotifyHandler handler, long leaseTime); boolean notifyTake(Object template, NotifyHandler handler, long leaseTime); } trait NotiFly extends FlyPrime { def notifyWrite(template: AnyRef, handler: NotifyHandler, leaseTime: Long): Boolean def notifyTake(template:AnyRef, handler:NotifyHandler, leaseTime:Long):Boolean } http://www.casualmiracles.com/
  • SYNTACTIC public static void main(String[] args) throws Exception { def main(args: Array[String]) { FileInputStream f = new FileInputStream(new File(args[0])); val f = new FileInputStream(new File(args(0))); DataInputStream dis = new DataInputStream(f); val dis = new DataInputStream(f); StatsDecoder decoder = new StatsDecoder(); val decoder = new StatsDecoder(); long time = dis.readLong(); var time = dis.readLong(); while ( true ) { while (true) { int size = dis.readInt(); val size = dis.readInt(); StatsBean [] beans = decoder.getStatsArray(dis); val beans = decoder.getStats(dis); Stats.writeStats(beans); StatsPrinter.writeStats(beans); System.out.println("--------------"); System.out.println("--------------"); long nextTime = dis.readLong(); val nextTime = dis.readLong(); Thread.sleep(nextTime-time); Thread.sleep(nextTime - time); time = nextTime; time = nextTime; } } } } http://www.casualmiracles.com/
  • IDIOMS - OPTION An Option represents an optional value Two subclasses: Some and None Java has … null http://www.casualmiracles.com/ Experiment with Options in Java later
  • IDIOMS - OPTION trait FlyPrime { def read[T <: AnyRef](template: T, waitTime: Long): Option[T] } fly.read(template, 0L) match { case None => { println("No ball in play") serveBall(fly) println("Served Ball - Please start a Pong") } case Some(gameBall) => { println("Received ball - game on!") returnBall(fly, gameBall) } } http://www.casualmiracles.com/ pattern matching - scala can extract values from the matching pattern - Some(ball) no types
  • IDIOMS - OPTION trait FlyPrime { def read[T <: AnyRef](template: T, waitTime: Long): Option[T] } fly.read(template, 0L) match { case None => // do nothing case Some(gameBall) => doSomething(gameBall) } fly.read(template, 0L).map((x:T) => doSomething(x)) fly.read(template, 0L).map(doSomething(_)) http://www.casualmiracles.com/ do nothing for none - verbose to use pattern matching (x:T) => doSomething(x) is a first class function
  • ASIDE Options can be implemented in other languages Clumsy in Java but still useful An experiment: Problems exposed where null was not expected Clarify business logic and behaviour http://www.casualmiracles.com/
  • IDIOMS - RETURN VALUES int iterations = 10000; if (args.length > 0) iterations = Integer.parseInt(args[0]); val iterations = if (args.length > 0) args(0).toInt else 10000 def urlFor(path: String) = try { new URL(path) } catch { case e: MalformedURLException => new URL("http://www.scala-lang.org") } http://www.casualmiracles.com/ pattern matching for exceptions exceptions are runtime
  • IDIOMS - FILTERING public Collection<FlyServerRep> getMatchingReps(String [] tags) { Collection matched = new ArrayList<FlyServerRep>(); for (FlyServerRep rep : reps.values()) { if (rep.tagsMatch(tags)) { matched.add(rep); } } return matched; } def getMatchingReps(tags:Array[String]):Collection[FlyServerRep] = reps.values.filter((rep:FlyServerRep) => rep.tagsMatch(tags)).toList def getMatchingReps(tags:Array[String]):Collection[FlyServerRep] = reps.values.filter(_.tagsMatch(tags)).toList http://www.casualmiracles.com/ filter items from a collection
  • IDIOMS - COMPREHENSIONS public StatsBean[] getStatsArray(DataInputStream dis) throws IOException { long statsCount = dis.readLong(); StatsBean [] stats = new StatsBean[(int)statsCount]; for (int i = 0; i < statsCount; i++) { stats[i] = StatsBean.makeBeanFromStream(dis); } return stats; } def getStats(dis: DataInputStream): Seq[StatsBean] = for (i <- 0 until dis.readLong().toInt) yield StatsBean.makeBeanFromStream(dis) http://www.casualmiracles.com/ Create an array of items for comprehension - iterate over something collecting results of the expression after yield
  • FOR COMPREHENSION Syntax: for ( seq ) yield e Where seq is a sequence of generators, definitions and filters e evaluated for each binding of generators and definitions Return a sequence of evaluated values http://www.casualmiracles.com/ generator— roughly speaking, an expression that pulls an item from a collection easier to show an example...
  • FOR COMPREHENSION val names = for { p <- persons // a generator n = p.name // a definition if (n startsWith "To") // a filter } yield n http://www.casualmiracles.com/ p bound to each item in persons
  • IDIOMS - FOLD /** * @return the lease of the last entry written */ public long writeMany(Collection entries, long lease) { long lastLease = 0; for (Object entry : entries) { lastLease = codec.write( entry, lease ); } return lastLease; } def writeMany(entries: Collection[AnyRef], lease: Long): Long = (0L /: entries){(previousLease, nextEntry) => codec.write(nextEntry, lease)} http://www.casualmiracles.com/ method writes entries to the space and returns the lease of the last item written function takes two parameters, ignores previousLease, returns the result of codec.write good use of fold?
  • IDIOMS - ACCESSORS public class FlyServerRep { class FlyServerRep(var flyAddr:InetAddress, var flyTags:Array[String]) private String [] flyTags; private InetAddress flyAddr; FlyServerRep(InetAddress addr, String[] tags) { flyAddr = addr; flyTags = tags; } public String[] getFlyTags() { return flyTags; } public void setFlyTags(String[] flyTags) { this.flyTags = flyTags; } public InetAddress getFlyAddr() { return flyAddr; } public void setFlyAddr(InetAddress flyAddr) { this.flyAddr = flyAddr; } } http://www.casualmiracles.com/ var on constructor parameters, scala generates accessor methods: x and x_
  • IDIOMS - FUNCTIONS public Object read(Object template, long timeout) { public Object take(Object template, long timeout) { Object ret = codec.read(template, 0); Object ret = codec.take(template, 0); .... .... while(...) while(...) ret = codec.read(template, 0); ret = codec.take(template, 0); def read[T <: AnyRef](template: T, timeout: Long): Option[T] = retrieve(template, timeout, codec.read) def take[T <: AnyRef](template: T, timeout: Long): Option[T] = retrieve(template, timeout, codec.take) private def retrieve[T](template: T, timeout: Long, m: (T, Long) => Option[T]): Option[T] = { var ret = m(template, 0L) .... while(...) ret = m(template, 0) http://www.casualmiracles.com/
  • CONTROL ABSTRACTION System.out.println("Processing " + iterations + " writes and reads"); long start = System.currentTimeMillis(); for (int i = 0; i < iterations; i++) { space.write(object, 1000); space.read(template, 0L); } long end = System.currentTimeMillis(); float timeInSeconds = (float) (end - start) / 1000.0f; System.out.println("Which took " + timeInSeconds + " secondsn"); http://www.casualmiracles.com/
  • CONTROL ABSTRACTION Time("Processing " + iterations + " writes and takes", iterations) { space.write(obj, 1000) space.take(template, 0L) } object Time { def apply(name: String, iterations: Int)(block: => Unit): Unit = { println(name) val start = System.currentTimeMillis() for (i <- 0 until iterations) block val end = System.currentTimeMillis() val timeInSeconds = (end - start) / 1000.0F println("Completed in " + timeInSeconds + " secondsn") } } http://www.casualmiracles.com/ apply methods have special meaning - invoked using a method-less expression eg Time (... is the same as Time.apply(...
  • CONTROL ABSTRACTION trait NotiFly extends FlyPrime { def notifyWrite(template: AnyRef, leaseTime: Long)(block: => Unit): Boolean } fly.notifyWrite(template, LEASE){ println("Block Template matched!") } http://www.casualmiracles.com/
  • ACTORS Scala’s primary concurrency construct Concurrent processes communicating by exchanging messages Scala Actor implementation is a library - several of them http://www.casualmiracles.com/
  • ACTORS trait NotiFly extends FlyPrime { def notifyWrite(template: AnyRef, leaseTime: Long, actor: Actor): Boolean } import scala.actors.Actor._ val myActor = actor { // factory method taking a block loop { // we want the actor to keep processing messages react { // handle messages case FlyPrime.ACTOR_MESSAGE => println("Actor received a message!") } } } fly.notifyWrite(template, LEASE, myActor) http://www.casualmiracles.com/
  • JAVA TO SCALA COMPARED  Java has 1556 LoC, Scala has 934 LoC => 60%  Core code is about half the size  Why?  Most algorithms can be characterised as Searching, Sorting, Filtering, Mapping, Combining, Counting (Peter Norvig)  Scala and functional languages provide good abstractions for these  Java is 2% faster  Need more comprehensive tests to find out why http://www.casualmiracles.com/
  • WHAT NEXT?  Scala 2.8  Port from 2.7.7 complete  Available for 2.8 soon  Implement the library from scratch?  Design of existing library is the same as the Java library  Current version made improvements in the small  Perhaps a more functional approach would be better? http://www.casualmiracles.com/
  • > <---- ---------> <---- > FROM JAVA TO SCALA http://www.casualmiracles.com/ 2/3 lines of code could be better