Python to scala

Post on 22-Jan-2017

614 views 0 download

Transcript of Python to scala

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.