Download Introducing Scala-A better and tastier java

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
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/