Upload
kao-kuo-tung
View
614
Download
0
Embed Size (px)
Citation preview
python to scala
簡介
● inwinSTACK● Openstack contributor
○ Openstack Kolla core member● kjellytw at gmail dot com● http://www.blackwhite.
tw/
Java to Scala
● Java to Scala
Python
● Object-oriented, ● Imperative● Dynamic type● Interpreted languages● Support shell
Scala
● Functional programming● Static type ● Object-oriented● Type inference● Lazy (non-strict) evaluation● Compiled languages● Support shell
python vs scala
● statement, expression.
● a + b => a.__add__(b)
● f(a,b) => f.__call__(a,b)
● everything "evaluates" to a value.
● a + b => a.+(2)● f(a,b) => f.apply(a,
b)
variable - python vs scala
a = 1 ● The return value of expression is `()`.
var a = 1var a: Int = 1
const - python vs scala
● python doesn’t support const.
● The return value of expression is `()`.
val a = 1val a: Int = 1
lazy
● Not support in native python. (Maybe some library support it.
● Initialization is deferred until it is accessed for the first time
● Check whether the value has already been initialized before a lazy value is accessed.
lazy
● lazy var words = scala.io.Source.fromFile("/usr/share/dict/words").mkString
● lazy val fibs: Stream[BigInt] = BigInt(0) #:: BigInt(1) #:: fibs.zip(fibs.tail).map { n => n._1 + n._2 }
if-else
● statementif a > 5:
print(a)else:
print()
● expression
val x = if(a>5) {1} else 2val y = if(1!=1) 1 //y == ()
while
while a > 5:print(a)a -= 1
● The return value of expression is `()`.
while ( a > 5) {print(a)a -= 1
}
def loop(x: Int, xs: List[Int]): Int = { var max_value = x var rest = xs while (rest != Nil) { if (max_value < rest.head) max_value = rest.head rest = rest.tail } max_value}
tail recursion
def loop(lst: List[Int], maxValue: Int): Int = lst match { case Nil => maxValue case x :: xs => if (x > maxValue) loop(xs, x) else loop(xs, maxValue) }
tail recursion
def max(lst: List[Int]): Int = { lst match { case Nil => 0 case x :: xs => loop(xs, x) } }
tail recursion
● a tail call might lead to the same subroutine being called again later in the call chain.
● a tail recursive function is transformed into a loop by the compiler.
● use `@tailrec`
do while
● Not support do {println(a)a -= 1
while( a > 5)
for
list comprehension vs for yield
python
scala: the syntax is similar with for.
generator vs stream
They are not the same. But they are similar in some case.
function
● You can define many function with the same name. But only the function which is executed in last time will be called.
● Support overloading
scala function
def func(a: Int, b: Int) :Unit = {1
}
scala function
1. def fun = 1 // for pure function2. def fun() {println(“S”)} # for side effect
function argument
● support variable-length argument, keyworded argumen, default argument.
● support variable-length argument, default argument, call-by-name argument.
variable-length , keyworded , default argument
def func(a, b=1, *args, **kwargs):pass
def func(a: Int, b: Int = 1, args: Int*) = { 1}
call-by-name argument
● python doesn’t support call-by-name.● def mywhile(condition: => Boolean, body: => Unit)
def mywhile(condition: => Boolean, body: => Unit): Int = { def loop(count: Int): Int = { if (condition) { body; loop(count + 1) } else count } loop(0)}
var a = 1print(mywhile({ a < 5 }, { a += 1 }))
function return
● use `return` if you want to return something.
● if there are no return in function body, it will return `None`.
● avoid to use `return` keyword.
● if there are no return in function body, it will return the value of the last expression
match-case
● python doesn’t support match-case.
match-case
x.asInstanceOf[Any] match {case x :: xs => println(x)case (a, b, c) => println(a)case p @ Some(v) if v == 2 => println(p)case x: Int if x != 2 => println(x)case _ => println(“None”)
}
class
1. multi inheritance2. public3. Not support
overloading
1. single inheritance2. public, protect,
private3. Support overloading
class constructor
class My(object):def __init__(self, x):
self.x = xself.odd = x%2 ==0
def print_x(self):print(self.x)
class My(var x: Int) {var odd = x % 2 ==0def print_x() {
println(x)}
}
scala auxiliary constructor
class Length(val length: Int) { def this(str: String) { this(str.length) } def this(list: List[Any]) { this(list.length) }}new Length(5)new Length(“Hi”)new Length(List(1,2))
duck typing
class Length1(val length: Int) { def this(o: {def length:Int}) { this(o.length) }}
● All thing is duck typing in python.
● scala support duck typing.
scala companion object
● singleton object● companion object
Singleton object
object Main { def sayHi() { println("Hi!"); }}
companion object
class Main { def sayHelloWorld() { println("Hello World"); }}
object Main { def sayHi() { println("Hi!"); }}
method,used for instance
static method, used for class
How to create instance?
class A(object):passa = A()
class A {}val a = new Aclass B{}object B{def apply() = new B}val bB = B()
Python
Scala
Type checking and cast
1. isinstance(a, str)2. issubclass(A,
object)3. a.__class__
1. "S".isInstanceOf[String]2. 3. 4. "S".asInstanceOf
[String]
Type checking and cast
if isinstance(a, int):print(“int”)
elif isinstance(a, str):print(“str”)
a mtach {case _: Int =>
println(“int”)case _: String =>
println(“Str”)}
class inheritance
● Method Resolution Order
● class X(A, B):pass● X.__mro__
● single inheritance● need `override` when
overriding● class X extends Any
scala trait
● trait is like java interface but allows concrete implementations.
● class A extends B with C with D○ extends + class|trait○ with + trait
case class
● python doesn’t support case class.● case class generate the following method:
○ equals○ apply for companion object .○ unapply for companion object.
Why we need case class?
def Person(object):def __init__(self, name, age):
self.name = nameself.age = age
person = Person(“bill”, 5)
Why we need case class?
case class Person(var name:String, var age:Int)val person = Person(“Bill”, 5)
More case calss
person match { case Person(name, age) if name == "X" => s"$name,$age" case _ => "Nothing"}
Scala hierarchy
Python hierarchy
I don’t care.
package
● folder with `__init__.py` file
● package com.abc.name
import
● the way to use the code in other file.
● use short name
import
● the way to use the code in other file.
● use short name
Implicit
● python doesn’t support implicit.● Implicit Conversions
○ implicit defwrapString(s: String): WrappedString● Implicit Parameters
○ implicit val n: Int = 5○ def add(x: Int)(implicit y: Int) = x + y
● more thing ...
Scala type parameters
● List[String](); def drop1[A](l: List[A]) = l.tail
Scala type parameters
● List[String](); def drop1[A](l: List[A]) = l.tail● more thing about:
○ Bounds -> def biophony[T <: Animal]○ Quantification -> def count(l: List[_]) = l.size○ Variance
Int
● int, long● nerver overflow
● Int(32-bit signed) or Long(64-bit signed) or BigInt
● BitInt supports +,%,*● care for overflow
Boolean
● True and False● False or True● not True
● true && false● true || false● !true
● short-circuit
String
● no char● one line string:
○ “string”○ ‘string’
● multiline string:○ “””dddd”””○ ‘’’ccc’’’○ “abcd”[1]
● char => ‘c’● string => “c”● “abcd”(1)
String format
● "%s %d" % ("Hi", 5)● '{0}'.format('a')● 'Coordinates:
{latitude}'.format(latitude='37.24N',)
● i"{names}" #P0510
● "%s".format(firstName)
● s"Hello, $name"
List in python vs ArrayBuffer in scala
1. List(1, 2, 3, 4)2. [1, 2, 3, 4]3. a[3]4. a[-1]5. a[1:-1]6. a[1:-1:-1]7. a[1] = 1
1. ArrayBuffer(1,2,3,4)2. new ArrayBuffer[Int]()3. a(3)4.5. a.slice(1, a.length-1)6.7. a(1) = 1
List in python vs ArrayBuffer in scala
1. map(a, lambda x: x+1)
2. b = [i + 1 for i in a if i % 2 ==0]
1. a.map(_ + 1)2. val b = for(i <- a if i
% 2 ==0) yield i + 1
a.map(x:Int => {x + 1})a.map(x => {x+1})a.map(x => x+ 1)a.map(_ + 1)
List in python vs ArrayBuffer in scala
1. a.__getitem__2. a.__setitem__
1. a.apply2. a.update
ArrayBuffer
new ArrayBuffer(5) vs ArrayBuffer(5)
Scala List
● Linked list● Optimal for last-in-first-out (LIFO), stack-
like access patterns● Immutable● `Nil` means empty list.
Scala List
● List(1, 2, 3)● 1 :: 2 :: 3 :: Nil● Nil.::(3).::(2).::(1)
Scala List
def max(lst: List[Int]): Int = { lst match { case Nil => 0 case x :: xs => loop(xs, x) } }
Scala Async
Future.apply[T](body: ⇒ T)(implicit executor: ExecutionContext): Future[T]
def combined: Future[Int] = async { val future1 = slowCalcFuture val future2 = slowCalcFuture await(future1) + await(future2)}
val future1 = slowCalcFutureval future2 = slowCalcFuturedef combined: Future[Int] = for { r1 <- future1 r2 <- future2} yield r1 + r2
django vs play framework2
● python web framework
● MVT● support ORM
● scala/java web framework
● MVC● support type
checking in views.
django class-based views vs play controller
def index = Logging { Action { Ok("Hello World") }}
class MyView(TemplateView): template_name = "about.html"
Play
Django
django template vs play view
play view
● type checking● view as function.
○ views.html.list(List(“1”))
function argument
function body
call main function
list.scala.html
django forms vs play forms
Thank you
The slide will update continuously.