Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Introducing ScalaA better and tastier java Byju Veedu 16 Dec 2010 Courtesy for Sources http://www.scala-lang.org/ http://www.slideshare.net/Odersky/fosdem-2009-1013261 http://www.slideshare.net/stal42/oop2010-scala-presentation-stal http://www.slideshare.net/jboner/pragmatic-real-world-scala-45-min-presentation Objectives • • • • • • • • • Why scala ? Why it is scalable ? Where it is superior to java ? How scala combines OO and FP ? How type inference works in scala ? Actor concurrency model Functional programming As fast as java Scala is fun for developers History • Scala was designed from 2001 by Martin Odersky and his group at EPFL in Lausanne, Switzerland. • Odersky had previously worked on Generic Java and javac, Sun's Java compiler. • The goal was to combine functional and object-oriented programming, but without the restrictions imposed by the Java language. The first step in this direction was Funnel • The second step scala took some of the ideas of Funnel and put them into a more pragmatic language with special focus on interoperability with standard platforms • Scala was released late 2003 / early 2004 on the Java platform, and on the .NET platform in June 2004. • As of November 2010, the latest release is version 2.8.1 Scala is • • • • • • • • • • • Statically typed Functional Pure Object oriented Compiles to byte code and runs in jvm Interoperate with java Type inference Concurrency with actors Mixins with traits Immutable collections Scripting language As fast as java Scalable language • A language is scalable if it is suitable for very small as well as very large programs. • A single language for extension scripts and the heavy lifting. • Application-specific needs are handled through libraries and embedded DSL's instead of external languages. • Scala shows that this is possible. Hello world class HelloWorld( val name:String){ def print = println("Hello world "+name) } object HelloWorldMain(){ def main(args:Array[String]):Unit = { var hello = new HelloWorld("Scala") hello print } } Application base class object HelloWorld extends Application { println("Hello world") } Scala is a scripting language It has an interactive read-eval-print-loop (REPL). Types can be inferred. Boilerplate is scrapped Simple and expressive. scala> var capital = Map("US" "Washington", "France" "Paris") capital: Map[String, String] = Map(US Washington, France Paris) scala> capital += ("Japan" "Tokio") scala> capital("France") res7: String = Paris Scala compared to Java Scala adds Scala removes + a pure object system - static members + operator overloading - primitive types + closures - break, continue + mixin composition with traits - special treatment of interfaces + existential types - wildcards + abstract types - raw types + pattern matching - enums Modeled in libraries: assert, enums, properties, events, actors, using, queries, … Type inference Compiler understands the type of variable based on the values assigned even though the programmer doesn’t explicitly specify the type. In scala this works except for method parameters and for return values of recursive functions scala> val name="John" name: java.lang.String = John scala> print(name.length) 4 scala> val age =35 age: Int = 35 scala> print (age+10) 45 scala> def getArea (length :Int,width:Int) =length*width getArea: (length: Int,width: Int)Int scala> println(getArea(10,20)) 200 High-level • Java boolean hasUpperCase = false; for (int i = 0; i < name.length(); i++) { if (Character.isUpperCase(name.charAt(i))) { hasUpperCase = true; break; } } • Scala version val hasUpperCase = name.exists(_.isUpperCase) Concise // Java public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } public void setName(String name) { this.name = name; } public void setAge(age: int) { this.age = age; } } // Scala class Person( var name: String, var age: Int) Pure OO • Every value is an object • Every operation is a method call • Exceptions to these rules in Java (such as primitive types, statics) are eliminated 1+2 1.+(2) 123.toString() Inheritance • • • • Scala classes can be derived from at most one base class Classes may be abstract You need to specify whether you override inherited methods abstract class Shape{ type identifier =Int //abstract type def getId:Identifier =12 def draw:String } class Circle (val cx:Double,val cy:Double,val r:Double) extends Shape{ val id:Identifier =getId() override def draw:String =”I am circle” } Uniform access principle Mutable and immutable • Use var and val val name =”Scala” // immutable name =”Ruby” // won't compile as name is a val var age =30 age =40 println(age) // prints 40 def place =”Bangalore” // default is val place =”Chennai” // won't compile Collections • Both mutable and immutable collections • Default is immutable • • • • List Map Set Tuples List var list =List(1, 2, 3) or 1 :: 2 :: 3 :: Nil list.head list.tail list.isEmpty list.map(_ + 1) list.filter(_ < 2) list.exists(_ == 3) list.drop(2) list.reverse list.sort(_ > _) List.flatten(list) list.slice(2, 3) // 1 //List(2, 3) // false // List(2, 3, 4) // List(3) // true // List(3) // List(3, 2, 1) // List(3, 2, 1) // List(1, 2, 3) // List(3) Map var m1 =Map(1->”scala”,2->”java”) val m2= m1+(3->”c#”) println(m2(3)) // new map // add an entry // prints c# Set • • • • var s1 =Set(1,2,3,4) println( s1 contains 2) // print true var s3= s1++s2 // union var s4= s1+5 Tuples def getNameAndAge = { val name = “kumar” val age = 25 (name, age) } val (name, age) = getNameAndAge println(“Name: “ + name) println(“Age: “ + age) Exception Handling • No checked exceptions and throws try { int a = 12/arg } catch { case ex:RuntimeException => println (“Cannot divide by arg”) case _ => println (“Un expected probem”) } finally{ println(“resources closed”) } class Data(bytes: • Send (!) is asynchronous; withcase Cuncurrency Actors Array[Byte]) messages are buffered in an actor's mailbox. • receive picks the first message in the mailbox which matches any of the patterns msgpati. • If no pattern matches, the actor suspends case class Sum(receiver: Actor) val checkSumCalculator = actor { var sum = 0 loop { receive { case Data(bs) => sum += hash(bs) case Sum(receiver) => receiver ! sum } } } } Native xml support def users = <users> <user role=”customer”> <name>{ user.name }</name> <password>{ user.password }</password> <email>{ user.email }</email> </user> ... </users> users match { case <users>{users @ _*}</users> => for (user <- users) println(“User “ + (user \ “name”).text) } Traits and mixin composition class Man(val name: String) extends Human trait Dad { private var children: List[Child] = Nil def addChild(child: Child) = children = child :: children def getChildren = children.clone } // static mixin composition class Man(val name: String) extends Human with Dad val jonas = new Man(“Jonas”) jonas.addChild(new Child(“Jacob”)) //Dynamic mixin composition val jonas = new Man(“Jonas”) with Dad jonas.addChild(new Child(“Jacob”)) Composition with traits trait Entity { ... } trait InventoryItemSet { ... } trait Invoicable { ... } trait PurchaseLimiter { ... } trait MailNotifier { ... } trait ACL { ... } trait Versioned { ... } trait Transactional { ... } val order = new Order(customer) with Entity with InventoryItemSet with Invoicable with PurchaseLimiter with MailNotifier with ACL with Versioned with Transactional Structural Typing: Duck-typing done right “ if it walks like a duck… and talks like a duck… then it’s a duck “ def authorize(target: { def getACL: ACL }) = { val acl = target.getACL ... //authorize } Functions • Scala is a functional language, in the sense that every function is a value. • Functions can be anonymous, curried, nested. • Functions as values val inc = (x: Int) => x + 1 inc(1) // gives 2 • Functions as parameters List(1, 2, 3).map((x: Int) => x + 1) => List(2, 3, 4) • Functions as closures var more = 7 val addMore = (x: Int) => x + more addMore(3) // gives 10 //change more’s value to 8 more = 8 addMore(3) // gives 11 Functions are objects • If functions are values, and values are objects, it follows that functions themselves are objects. The function type S => T is equivalent to scala.Function1[S, T], where Function1 is defined as follows: trait Function1[-S, +T] { def apply(x: S): T } • So functions are interpreted as objects with apply methods. • For example, the anonymous successor function (x: Int ) => x + 1 • is expanded to: new Function1[Int, Int] { def apply(x: Int) = x + 1 } Everything returns a value def getThingsFromSomewhere( fromHere: Boolean): List[Thing] = { try { if (fromHere) { for (thing <- thingsFromHere) yield getRealThing(thing) } else { for (thing <- thingsFromThere) yield thing } } catch { case e => error(e); Nil } } For comprehensions // Find all attendees named “Fred” that speaks Danish for { att <- attendees if att.name == “Fred” lang <- att.spokenLanguages if lang == “Danish” } println(att) // Yielding val companiesForAttendeesFromLondon = for { att <- attendees if att.address.city == “London” } yield att.company Pattern matching def matchAny(a: Any): Any = a match { case 1 => “one” case “two” => 2 case i: Int => “scala.Int” case <tag>{ t }</tag> => t case head :: tail => head case _ => “default” } Regular expressions val pattern =“““\d\d.\d\d.\d\d\d\d”””.r // .r indicate reg exp val sentence =“X was born on 02.09.2010” println(pattern findFirstIn sentence) // gives Some(02.09.2010) Adding new control structures • using for resource control (proposed for Java 7) • using (new BufferedReader(new FileReader(path))) { f => println(f.readLine()) } Instead of • val f = new BufferedReader(new FileReader(path)) try { println(f.readLine()) } finally { if (f != null) f.close() } Can be implemented as • def using[T <: { def close() }] (resource: T) (block: T => Unit) { try { block(resource) } finally { if (resource != null) resource.close() } } What makes Scala scalable? strong typing, inference, little boilerplate,… But mainly, its tight integration of functional and object-oriented programming • Functional programming: Makes it easy to build interesting things from simple parts, using ▫ higher-order functions, ▫ algebraic types and pattern matching, ▫ parametric polymorphism • Object-oriented programming: Makes it easy to adapt and extend complex systems, using ▫ ▫ ▫ subtyping and inheritance, dynamic configurations, classes as partial abstractions. Scala is the Java of the future • It has basically everything Java has now. (sometimes in different form) • It has closures and other functional features (proposed for Java 7, but rejected) • It has traits and pattern matching. (I would not be surprised to see them in Java 8, 9 or 10) • It compiles to .class files, is completely interoperable and runs about as fast as Java • It has type inference to remove boiler plate code • It is pure OO (no primitives) • Simple and succinct syntax • Actors for better concurrency • Native xml support References • • • • • • • • • • • http://www.scala-lang.org/ http://www.artima.com/scalazine/articles/steps.html http://programming-scala.labs.oreilly.com/ http://www.naildrivin5.com/scalatour/wiki_pages/MainPage http://www.simplyscala.com/ http://www.diigo.com/user/byjupv/ScalaVideos?type=all http://daily-scala.blogspot.com/ http://grahamhackingscala.blogspot.com/ http://www.defmacro.org/ramblings/fp.html http://davetron5000.github.com/scala-style/ http://www.planetscala.com/