Ajatuksena on, että kerran luotua olioarvoa ei voi koskaan muuttaa, jolloin mitään rinnakkaisten säikeiden poissulkemista tällaisten olioiden käpälöinnissä ei tarvitse harrastaa. Ja näin osa rinnakkaisohjelmoinnin ongelmista poistuu. Roskaa syntyy, totta kai, mutta Java-toteutusten myötä roskankeruun tekniikka on kehittynyt huimasti. Ja säikeitähän riittää hoitelemaan siivoushommiakin...
Ehkäpä vielä koittaa "funktionaalisen olio-ohjelmoinnin" aika?
Seuraavassa rationaalilukujen toteutus "immutaabelina" oliona:
class Rational(n: Int, d: Int) { private def gcd(x: Int, y: Int): Int = { if (x == 0) y else if (x < 0) gcd(-x, y) else if (y < 0) gcd(x, -y) else gcd(y % x, x) } private val g = gcd(n, d) val numer: Int = n/g val denom: Int = d/g def +(that: Rational) = new Rational(numer * that.denom + that.numer * denom, denom * that.denom) def -(that: Rational) = new Rational(numer * that.denom - that.numer * denom, denom * that.denom) def *(that: Rational) = new Rational(numer * that.numer, denom * that.denom) def /(that: Rational) = new Rational(numer * that.denom, denom * that.numer) override def toString() = "(" + numer + "/" + denom +")" }Luokan käyttöä perinneohjelmoinnissa:
println("Rationaalilaskentaa.") println("Anna ensimmäisen luvun osoittaja ja nimittäjä.") val a = new Rational(readInt, readInt) println("Anna toisen luvun osoittaja ja nimittäjä.") val b = new Rational(readInt, readInt) println("Lukujen " + a + " ja " + b +" summa, erotus, tulo ja osamäärä ovat:") println(a+b) println(a-b) println(a*b) println(a/b)Ohjelman suoritusesimerkki:
Rationaalilaskentaa. Anna ensimmäisen luvun osoittaja ja nimittäjä. 4 9 Anna toisen luvun osoittaja ja nimittäjä. 3 6 Lukujen (4/9) ja (1/2) summa, erotus, tulo ja osamäärä ovat: (17/18) (-1/18) (2/9) (8/9)[Hienompi versio rationaalilukujen toteutukseksi]
Harrastetaan sitten vähän "funktionaalista ohjelmointia" - klassisen hirveä toteutus Fibonaccin luvun laskemiseen:
def fibo(i:Int):Int = if (i<2) 1 else fibo(i-1) + fibo(i-2) println("Kultaisen leikkauksen aproksimointi kahden peräkkäisen Fibonaccin luvun suhteena.") println("Miten pitkälle edetään?") val lkm = readInt println(new Rational(fibo(lkm),fibo(lkm-1))) // ei erityisen tehokasta: O(2n) !! ;-) println(1.0*fibo(lkm)/fibo(lkm-1)) // vain tarkistukseksiSuoritusesimerkki:
Kultaisen leikkauksen aproksimointi kahden peräkkäisen Fibonaccin luvun suhteena. Miten pitkälle edetään? 40 (165580141/102334155) 1.618033988749895