po* - scalasroka/archiwalne/2012po_gw/scala1.pdf · przygotował: jacek sroka 6 jak uruchamiać -...

35
Przygotował: Jacek Sroka 1 PO* - Scala

Upload: others

Post on 17-Oct-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

1

PO* - Scala

Page 2: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

2

Czemu Scala?

● Język wzorowany na Javie i Haskelu– nowoczesny obiektowy język programowania

– jednocześnie język funkcyjny

● Programy uruchamiają się na JVM– można swobodnie odwoływać się do istniejącego kodu i bibliotek Javy

● Silnie typowany– ciekawy system typów

● Zwięzła składnia i silniejsza abstrakcja = prostsze programy = mniej błędów

● Zaprojektowany do wyrażania powszechnych wzorców projektowych● Robi się trendy?

Page 3: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

3

Pierwszy przykład

object HelloWorld { def main(args: Array[String]) { println("Hello, world!") }}

> scalac HelloWorld.scala

> scala -classpath . HelloWorldHello, world!

● main() jest procedurą

● object deklaruje Singleton (klasa i egzemplarz)

● Nie ma potrzeby dla składowych statycznych

Page 4: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

4

Jak uruchamiać - shell

> scala This is a Scala shell. Type in expressions to have them evaluated. Type :help for more information.

scala> object HelloWorld { | def main(args: Array[String]) { | println("Hello, world!") | } | } defined module HelloWorld

scala> HelloWorld.main(null) Hello, world!

scala>:q

Page 5: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

5

Jak uruchamiać - skrypt

#!/bin/sh exec scala "$0" "$@" !# object HelloWorld { def main(args: Array[String]) { println("Hello, world! " + args.toList) } } HelloWorld.main(args)

> ./script.sh

Page 6: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

6

Jak uruchamiać - kompilacja

● Kompilacja do bytecodu Javy > scalac HelloWorld.scala

lub > scalac -d classes HelloWorld.scala

● Uruchamianie > scala HelloWorld

lub > scala -classpath classes HelloWorld

– argumentem powinien być obiekt najwyższego poziomu

– jeżeli występuje klauzula extends Application to wykonywane są wszystkie polecenia

object HelloWorld2 extends Application { println("Hello, world!") }– wpp wykonywana jest metoda main

Page 7: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

7

Wygodniejsze importy

import java.util.{Date, Locale}import java.text.DateFormatimport java.text.DateFormat._

object FrenchDate { def main(args: Array[String]) { val now = new Date val df = getDateInstance(LONG,Locale.FRANCE) println(df format now) }}

● Zwięzłe importowanie wielu klas z pakietu

● ”_” zamiast ”*”

● Trochę inne niż w javie importowanie składowych statycznych

● Funkcyjna składnia wywoływania metod i przekazywania parametrów

● Domyślnie importowane jest całe java.lang

Page 8: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

8

Wszystko jest obiektem

Włącznie z liczbami i funkcjami.

1 + 2 * 3 / x

(1).+(((2).*(3))./(x))

1.+(2)

(1).+(2) //żeby lexer nie wybrał najdłuższego dopasowanie dla identyfikatorów

Page 9: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

9

Funkcje też są obiektami

object Timer { def oncePerSecond(callback: () => Unit) { while (true) { callback(); Thread sleep 1000 } } def timeFlies() { println("time flies like an arrow...") } def main(args: Array[String]) { oncePerSecond(timeFlies) }}

object TimerAnonymous { def oncePerSecond(callback: () => Unit) { while (true) { callback(); Thread sleep 1000 } }

def main(args: Array[String]) { OncePerSecond(() => println("time flies like an arrow...")) }}

● Możemy przekazywać funkcje jako parametry

● ”() => Unit” to typ wszystkich funkcji bez argumentów i bez wartości zwrotnej

● Do wypisywanie użyliśmy predefiniowanej metody println() zamiast System.out

● Często wygodnie jest używać funkcji anonimowych

Page 10: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

10

Klasy

class Complex(real: Double, imag: Double) { def re() = real def im() = imag}

object ComplexNumbers { def main(args: Array[String]) { val c = new Complex(1.2, 3.4) println("imaginary part: " + c.im()) }}

class Complex(real: Double, imag: Double) { def re = real def im = imag}

class Complex(real: Double, imag: Double) { def re = real def im = imag override def toString() = "" + re + (if (im < 0) "" else "+") + im + "i"}

● Klasy w Scali mają parametrynew Complex(1.5, 2.3)

● Typy zwrotne metod zazwyczaj mogą być wywnioskowane przez kompilator

● Wywołując metody z zerową liczbą argumentów trzeba wstawiać puste nawiasy

● Metody można zdefiniować jako bezparametrowe

● Domyślną nadklasą jest scala.AnyRef

● Przedefiniowując metody trzeba to jawnie wskazać

Page 11: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

11

Warianty i dopasowywanie

abstract class Treecase class Sum(l: Tree, r: Tree) extends Treecase class Var(n: String) extends Treecase class Const(v: Int) extends Tree

//taką funkcją możemy//reprezentować środowisko//dla "x" zwraca 5 wpp wyjątek{ case "x" => 5 }

//alias dla typutype Environment = String => Int

● Wsparcie do reprezentacji drzew, np. XML

● Przykład: kalkulator z sumowaniem, stałymi całkowitymi i zmiennymi

● Const(5) zamiast new Const(5)

● Automatycznie są gettery np. dla c egzemplarza Const mamy c.v

● equals i hashCode działają na strukturze

● toString wypisuje "literał” np. Sum(Var(x,Const(1)))

● Można dopasowywać do wzorca

Page 12: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

12

Warianty i dopasowywanie c.d.

def eval(t: Tree, env: Environment): Int = t match { case Sum(l, r) => eval(l, env) + eval(r, env) case Var(n) => env(n) case Const(v) => v} //jak nic się nie dopasuje to wyjątek

def derive(t: Tree, v: String): Tree = t match { case Sum(l, r) => Sum(derive(l, v), derive(r, v)) case Var(n) if (v == n) => Const(1) //dopasowanie warunkowe case _ => Const(0) //guard}

def main(args: Array[String]) { val exp: Tree = Sum(Sum(Var("x"),Var("x")),Sum(Const(7),Var("y"))) val env: Environment = { case "x" => 5 case "y" => 7 } println("Expression: " + exp) //Expression: Sum(Sum(Var(x),Var(x)),Sum(Const(7),Var(y))) println("Evaluation with =5, y=7: " + eval(exp, env)) //Evaluation with x=5, y=7: 24 println("Derivative relative to x: " + derive(exp, "x")) //...to x: Sum(Sum(Const(1),Const(1)),Sum(Const(0),Const(0))) println("Derivative relative to y: " + derive(exp, "y")) //..to y: Sum(Sum(Const(0),Const(0)),Sum(Const(0),Const(1)))}

Page 13: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

13

Dopasowywanie wzorców vs polimorfizm

● Przy pomocy dopasowywania wzorców bardzo łatwo dodać nową metodę dla całej hierarchii. Dużo roboty jak nowy węzeł.

● Za pomocą polimorfizmu łatwo dodać nowy rodzaj węzła. Dużo roboty jak nowa metoda.

Page 14: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

14

Traits

trait Ord { def < (that: Any): Boolean def <=(that: Any): Boolean = (this < that) || (this == that) def > (that: Any): Boolean = !(this <= that) def >=(that: Any): Boolean = !(this < that)}

● Wzbogacanie klasy (interfejs z implementacją)

● Any to bardziej ogólny Object

Page 15: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

15

Traits c.d.

class Date(y: Int, m: Int, d: Int) extends Ord { def year = y; def month = m def day = d override def toString(): String = year + "" + month + "" + day

override def equals(that: Any): Boolean = that.isInstanceOf[Date] && { val o = that.asInstanceOf[Date] o.day == day && o.month == month && o.year == year }

def <(that: Any): Boolean = { if (!that.isInstanceOf[Date]) error("cannot compare " + that + " and a Date") val o = that.asInstanceOf[Date] (year < o.year) || (year == o.year && (month < o.month || (month == o.month && day < o.day))) }}

Page 16: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

16

Generyki

class Reference[T] { private var contents: T = _ def set(value: T) { contents = value } def get: T = contents}

object IntegerReference { def main(args: Array[String]) { val cell = new Reference[Int] cell.set(13) println("Reference contains the half of " + (cell.get * 2)) }}

● Parametryzowanie kodu typami

● Piszemy ogólny kod i nie musimy bez przerwy rzutować

● "_” to wartość domyślna dla zmiennej

Page 17: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

17

Quicksort

def sort(a: Array[Int]) { def swap(i: Int, j: Int) { val t = a(i); a(i) = a(j); a(j) = t }

def sort1(l: Int, r: Int) { val pivot = a((l + r) / 2) var i = l var j = r while (i <= j) { while (a(i) < pivot) i += 1 while (a(j) > pivot) j -= 1 if (i <= j) { swap(i, j) i += 1 j -= 1 } } if (l < j) sort1(l, j) if (j < r) sort1(i, r) }

if (a.length > 0) sort1(0, a.length - 1)}

● deklaracje zaczynają się zarezerwowanym słowem:def, var, val

● typ podajemy po symbolu ”i :”

● jak się da to kompilator domyśli się typu i nie trzeba go podawać

● Array[Int] zamiast Int[]

● a(i) zamiast a[i]

● zagnieżdżone funkcje mają dostęp do parametrów i zmiennych

Page 18: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

18

Quicksort c.d.

object sort {

def sort(a: Array[Int]) { //... }

def println(ar: Array[Int]) { def print1 = { def iter(i: Int): String = ar(i) + (if (i < ar.length-1) "," + iter(i+1) else "") if (ar.length == 0) "" else iter(0) } Console.println("[" + print1 + "]") }

def main(args: Array[String]) { val ar = Array(6, 2, 8, 5, 1) println(ar) sort(ar) println(ar) }

}

Page 19: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

19

Quicksort – wersja funkcyjna

def sort(a: Array[Int]): Array[Int] = { if (a.length < 2) a else { val pivot = a(a.length / 2) Array.concat(sort(a.filter(x => x < pivot)), a.filter(x => x == pivot), sort(a.filter(x => x > pivot))) } }

● Obiekty Array[T] mają metodę (pochodzącą z klasy Seq[T])def filter(p: T -> Boolean): Array[T]

● Można użyć składni a.filter(_ < pivot) a nawet (partially applied function) a.filter(pivot >)

– Inny sposób zapisania tej funkcji to x => pivot > x

● Operatory przekładają się na wywołania metod: a filter (pivot >)

● Dla podstawowych operatorów kompilator powinien generować dobry kod

● Ponieważ ciało funkcji jest wyrażeniem można pominąć {}

Page 20: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

20

Dyskusja

● zapotrzebowanie na pamięć● wielowątkowość

Page 21: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

21

Funkcje wyższego rzędu

def While (p: => Boolean) (s: => Unit) {

if (p) {s; While(p)(s)}

}

● tak naprawdę jest specjalna konstrukcja ● oba parametry są bezparametrowe● Unit to tak jakby void

● jak nie zwracamy żadnego wyniku to tak jak byśmy zwracali wartość unit ()

● nie trzeba podawać return, domyślnie wynikiem funkcji jest wynik ostatniego wyrażenia

Page 22: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

22

Wyrażenia

scala> 87+145res0: Int = 232

scala> 5+2*3res1: Int = 11

scala> "hello"+" world!"res2: java.lang.String = hello world!

scala> def pi = 3.141592pi: Double

scala> def radius = 10radius: Int

scala> 2*pi*radiusres7: Double = 62.83184

Page 23: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

23

Kiedy jest wyliczana wartość?

● wyrażenie w def x = e jest wyliczane dopiero jak jest potrzebne

● wyrażenie w val x = e jest wyliczane w chwili deklaracji

● zazwyczaj wyrażenia wyliczane są od lewej (redukcja)

(2*pi)*radius(2*3.141592)*radius6.183184*radius6.183184*1061.83184

Page 24: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

24

Proste funkcje

scala> def square(x: Double) = x*xsquare: (Double)Double

scala> square(2)res11: Double = 4.0

scala> square(5+3)res12: Double = 64.0

scala> square(square(4))res13: Double = 256.0

scala> def sumOfSquares(x: Double, y: Double) = square(x)+square(y)sumOfSquares: (Double,Double)Double

scala> sumOfSquares(3,2+2)res14: Double = 25.0

Page 25: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

25

Wyliczanie wartość funkcji

call-by-value

sumOfSquares(3, 2+2)sumOfSquares(3, 4)square(3)+square(4)3*3+square(4)9+square(4)9+4*49+1625

call-by-name

sumOfSquares(3, 2+2)square(3)+square(2+2)3*3+square(2+2)9+square(2+2)9+(2+2)*(2+2)9+4*49+1625

● Dla czystych funkcji zawsze ten sam wynik● call-by-value nie powtarza wyliczania argumentów

– Zazwyczaj bardziej wydajny

● call-by-name nie wylicza nieużywanych (niepotrzebnych) argumentów

Page 26: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

26

Wyliczanie wartości funkcji c.d.

● call-by-value łatwiej zapętlić scala> def loop: Int = loop loop: Int

scala> def first(x: Int, y: Int) = x first: (Int,Int)Int

scala> first(1,loop)

● call-by-name można wymusić scala> def constOne(x:Int, y: => Int) = 1 constOne: (Int,=> Int)Int scala> constOne(1,loop) res2: Int = 1

scala> constOne(loop,1)//pętla

Page 27: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

27

If-else

● Jak w Javie, ale w Scali jest również wyrażeniem (jak Javowy operator ternarny ... ? ... : ...)

scala> def abs(x: Double) = if (x >= 0) x else -x abs: (Double)Double

● Stałe logiczne i operatory są takie same jak w Javie

Page 28: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

28

Metoda Newtona

y x/y (y+x/y)/2

1 2/1 = 2 1.5

1.5 2/1.5 = 1.3333 1.4167

1.4167 2/1.4167 = 1.4118 1.4142

1.4142 ..... .....

Page 29: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

29

Przykład rozwiązania

● def sqrt(x: Double) = sqrtIter(1.0, x)

● def sqrtIter(guess: Double, x: Double): Double = if (isGoodEnough(guess, x)) guess else sqrtIter(improve(guess, x), x)

● def improve(guess: Double, x: Double) = (guess + x/guesss)/2

● def isGoodEnough(guess: Double, x: Double) = abs(square(guess) – x) < 0.001

Page 30: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

30

Zagnieżdżanie funkcji pomocniczych

def sqrt(x: Double) = {

def sqrtIter(guess: Double, x: Double): Double = if (isGoodEnough(guess, x)) guess else sqrtIter(improve(guess, x), x)

def improve(guess: Double, x: Double) = (guess + x/guesss)/2

def isGoodEnough(guess: Double, x: Double) = abs(square(guess) – x) < 0.001

sqrtIter(1.0, x)

}

//bloki w Scali są wyrażeniami o wartości kończącego wyrażenia

Page 31: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

31

Standardowa widoczność w zagnieżdżonych blokach

def sqrt(x: Double) = {

def sqrtIter(guess: Double): Double = if (isGoodEnough(guess, x)) guess else sqrtIter(improve(guess, x), x)

def improve(guess: Double) = (guess + x/guesss)/2

def isGoodEnough(guess: Double) = abs(square(guess) – x) < 0.001

sqrtIter(1.0)

}

Page 32: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

32

;

● każda definicja w bloku musi się kończyć „;”● domyślny średnik jest dodawany na końcu każdej linii, chyba że:

– linia kończy się słowem lub operatorem infiksowym, które nie byłyby dozwolone na końcu wyrażenia

– następna linia zaczyna się słowem od którego nie mogłoby się zaczynać wyrażenie

– jesteśmy otoczeni nawiasami

● def f(x: Int) = x + 1;f(1)+f(2)

● def g(x: Int) = x + 1g(1)+g(2)

● def h(x: Int) = {x+1}; h(1)+h(2) //tu średnik jest obowiązkowy

Page 33: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

33

;

● def m(x: Int) = x + ym(1)*m(2)

● def n(x: Int) = ( x //nawiasy powodują brak średnika + y)n(1)/n(2)

Page 34: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

34

Rekursja ogonowa

● def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)

● gcd(14, 21)if (21 == 0) 14 else gcd(21, 14 % 21)if (false) 14 else gcd(21, 14 % 21)gcd(21, 14 % 21)gcd(21, 14)if (14 == 0) 21 else gcd(14, 21 % 14)gcd(14, 21 % 14)gcd(14, 7)if (7 == 0) 14 else gcd(7, 14 % 7)gcd(7, 14 % 7)gcd(7, 0)if (0 == 0) 7 else gcd(0, 7 % 0)7

Page 35: PO* - Scalasroka/archiwalne/2012po_gw/scala1.pdf · Przygotował: Jacek Sroka 6 Jak uruchamiać - kompilacja Kompilacja do bytecodu Javy > scalac HelloWorld.scala lub > scalac -d

Przygotował: Jacek Sroka

35

Rekursja ogonowa

● def factorial(n: Int): Int = if (n == 0) 1 else n * factorial(n-1)

● factorial(5)if (5 == 0) 1 else 5 * factorial(5 1)5 * factorial(5 1)5 * factorial(4)5 * (4 * factorial(3))5 * (4 * (3 * factorial(2)))5 * (4 * (3 * (2 * factorial(1))))5 * (4 * (3 * (2 * (1 * factorial(0))))5 * (4 * (3 * (2 * (1 * 1))))120