Methoden Lokale Funktionen First Class Functions Verkürzte FCF

Werbung
Scala Funktion und Closures – Handout
Methoden
27.04.2010 – Schubert, Seilbeck
Verkürzte FCF Syntax
Der Datentyp kann weggelassen werden wo er für
den Compiler ersichtlich ist. Das ist der Fall wenn
eine FCF direkt an eine Methode übergeben wird,
def name (param1: Typ,param2:Typ) welche den Datentyp vorgibt.
:Typ={
}
list.foreach((x:Int)=>
println(x*x))
Überladung möglich. Sichtbarkeit ist
list.foreach((x) => println(x*x))
standardmäßig public.
In diesem Fall können auch die Klammern bei der
Parameterdefinition weggelassen werden.
Funktionsweise wie in Java:
Lokale Funktionen
Eine lokale Funktion ist eine Funktion in einer
Funktion. Die innere Funktion kann nur aus der
äußeren Funktion aufgerufen werden. Die innere
Funktion hat lesenden und schreibenden Zugriff
auf die Variablen der äußeren Funktion und auf
die Membervariablen.
First Class Functions
Funktionen können in Variablen gespeichert
werden.
var sqr = (x:Int) => x * x
Die Funktion in der Variable kann
folgendermaßen aufgerufen werden:
sqr(2) //= 4
Mehrere Parameter werden durch Kommas
getrennt.
list.foreach(x => println(x*x))
Platzhalter Syntax
Der „_“ kann als Platzhalter für einen Parameter
verwendet werden.
Var b = x => println(x)
var b = println(_:Int)
Möglich ist auch die Verwendung von mehreren
Parametern.
Auch hier gilt, dass der Datentyp weggelassen
werden kann, wo er für den Compiler ersichtlich
ist.
list.foreach(println(_))
Ein Nachteil der Platzhaltersyntax ist dass der
Parameter jeweils nur einmal verwendet werden
kann.
var sum = (x:Int,y:Int) => x + y
Partielle Funktionen
Die Variable kann neu zugewiesen werden wobei
Der „_“ kann auch ganze Parameterlisten ersetzen.
die Signatur (inkl. Rückgabewert) beibehalten
werden muss.
var minus=(_:Int) - (_:Int)
Bei mehrzeiligen Ausdrücken muss der
var b = minus(_:Int,_:Int)
Methodenrumpf in {} geklammert werden.
var c = minus _
b(5,3)
SqrPlus2 = (x:Int) =>{
var a= x*x;
a+2;
Bei der Anwendung auf eine überladene Funktion
}
meldet der Compiler einen Fehler.
Ein Teil der Parameter eines Funktionsaufrufes
können mit Werten vorbelegt werden.
Scala Funktion und Closures – Handout
var minus=(_:Int) - (_:Int)
b=minus(5,Int:_)
b(3) //=2
b=minus(Int:_,3)
b(5) //=2
Falls die ganze Parameterliste übernommen
werden soll und der Compiler eine Funktion
erwartet, kann der „_“ komplett weggelassen
werden.
list.foreach(println _)
list.foreach(println)
27.04.2010 – Schubert, Seilbeck
}
Varargs
Funtkionsweise der Varargs in Scala ist fast
identisch mit denen in Java.
def sum(args :Int*)={
var sum=0
for(arg <- args){sum += arg}
return arg }
Statt „...“ wird in Scala ein * verwendet, um ein
Vararg zu kennzeichnen.
Im Gegensatz zu Java ist es nicht möglich, direkt
Closures
ein Array an ein Vararg zu übergeben. Stattdessen
FCF haben Zugriff auf alle Variablen, die sich im muss an den Array „:_*“ angehängt werden. „:_*“
Scope befinden. Greift nun eine FCF auf eine
bringt den Compiler dazu, jedes Element eines
Variable zu, welche nicht als Parameter definiert Arrays in einen einzelnen Parameter
ist, wird sie als Closure bezeichnet.
umzuwandeln.
def createClosure ():(Int)=>Int={ sum(array:_*)
var noParameter = 3
(x: Int)=> x + noParameter
}
Endrekursionen
var closure = createClosure()
Compiler muss Endrekursionen (tail recursions)
closure(8)
// = 11
wegoptimieren
• Rekursiver Aufruf muss am Ende der
Kontext des Closures bleibt bis zum letzten Aufruf
Funktion stehen
bestehen.
Bei der Ausführung eines Closures ist der aktuelle
• Laufzeit nahezu identisch wie iterative
Zustand der Variablen maßgeblich.
Lösung
def createClosure ():(Int)=>Int={
var noParameter = 3
var closure = (x: Int)=> x +
noParameter
noParameter = 5
closure(8) // = 13
}
Ein Closure kann äußere Variablen verändern
def createClosure ()={
var noParameter = 3
var closure =(x:Int)=> x +
(--noParameter)
closure(8)
println(noParameter) //2
Optimierung kann mit dem Compilerparameter
g:notailcalls ausgeschaltet werden
Funktionale Programmierung
Orientiert sich an den Funktionen aus der
Mathematik.
y=sin(x)
Mathematische Funktionen sind frei von
Seiteneffekten. Das Ergebnis hängt allein vom
Parameter ab. Der Kontext spielt keine Rolle.
Solche Funktionen sind gut verständlich und leicht
testbar.
Scala Funktion und Closures – Handout
Durch den Einsatz von unveränderlichen
Variablen wird ein Teil dieses Verhaltens in einer
Programmiersprache nachgebildet. Dadurch
ergeben sich folgende Vorteile:
•
•
•
Nahezu alle Probleme bei Multithreading
werden vermieden
Verringert Komplexität
Daten müssen nicht gekapselt werden
Allerdings muss man auch in Kauf nehmen das
viele Objekte erzeugt werden müssen und sich
manche Bereiche nur schwer bis gar nicht
funktional lösen lassen z.B. IO.
Scala ist eine Multiparadigmen Sprache
(funktional und objektorientiert). Daher bietet
Scala für funktionale Programmierung folgende
Unterstützung:
• Vals statt vars
• Funktionale Datentypen (z.B. List ist
immutable)
• Operationen auf Collections die ohne vars
auskommen (z.B. foreach)
• Actors
27.04.2010 – Schubert, Seilbeck
Herunterladen