ein blick über den tellerrand funktionale ideen in der ... filemotivation funktionale...
TRANSCRIPT
Ein Blick über den TellerrandFunktionale Ideen in der
praktischen Programmierung
Jasper van de Ven([email protected])
Praktische Informatik 3Universität Bremen
Wintersemester 09/10
Motivation
funktionale Programmierung in der praktischen AnwendungeinordnenProgrammiersprachen, die funktionale Konzepte unterstützenBeispiele wo funktionale Programme mit großem Erfolg eingesetztwerden
Ablauf
Kurze Historie der funktionalen ProgrammierungVorstellung der betrachteten SprachenVorstellung der verwendeten Konzepte
Geschichtsstunde...
The future, according to somescientists, will be exactly like thepast, only far more expensive.
-John Sladek
Geschichtsstunde...
entwickelt aus der akademischen ForschungLambda-KlakülEnde 50iger Jahre → LISP1987 → Haskell
Haskell
vorgestellt 1987Zusammenführung derForschungSprache zumAustausch
main = putStrLn "Hello, World!"
—————————–
fac 0 = 1fac n = n * fac (n-1)
Erlang
Ericsson ComputerScience Lab1987Telekommunikation
-mod(hello).-export([start/0]).
start() ->io:format("Hello, World!").
—————————–
-module(test).-export([fac/1]).
fac(0) -> 1;fac(N) -> N * fac(N-1).
Ruby
Yukihiro ’Matz’Matsumoto1995 (Java auch...)Rails 2005
puts "Hello, world!"
—————————–
def fac(n)result = 1n.times do |i|
result *= iendresult
end
Scala
2003 (2001Entwicklungsbegin)École PolytechniqueFédérale de Lausanne(EPFL)Anfang 2004 → JVMMitte 2004 → .Net
object HelloWorldextends Application {
println("Hello, world!")}
—————————–
def fac(n: Int): Int = {if(n <= 1)
1else
n * fac(n - 1)}
Betrachtete Eigenschaften
ParadigmenTypsysteme
Speziellerfunktionale Techniken in RubyNebenläufigkeit in ErlangScala - Ein Blick in die Zukunft
Betrachtete Eigenschaften
ParadigmenTypsysteme
Speziellerfunktionale Techniken in RubyNebenläufigkeit in ErlangScala - Ein Blick in die Zukunft
Paradigmen der Programmierung
imperativprozeduralobjektorientiert
deklarativlogischfunktional
multiparadigmatisch
Programmiersprachen unterstützen einen Stil und beschränken nichtauf ihn
Paradigmen der Programmierung
imperativprozeduralobjektorientiert
deklarativlogischfunktional
multiparadigmatisch
Programmiersprachen unterstützen einen Stil und beschränken nichtauf ihn
Paradigmen von Erlang
hoch Verfügbar Parallelität
Was heist das jetzt genau?
Ericcson: 99% Verfügbarkeit imJahr
A = 1+5.B = 4+6.C = A+B.
Paradigmen von Erlang
hoch Verfügbar Parallelität
Was heist das jetzt genau?
Ericcson: 99% Verfügbarkeit imJahr
A = 1+5.B = 4+6.C = A+B.
Paradigmen von Erlang
hoch Verfügbar Parallelität
Was heist das jetzt genau?
Ericcson: 99% Verfügbarkeit imJahr
A = 1+5.B = 4+6.C = A+B.
Paradigmen von Ruby
multiparadigmatischobjektorientiert (prozedural, funktional)modularMetaprogrammierung
Paradigmen von Scala
multiparadigmatischobjektorientiert, funktional, imperativdirekte Anbindung an Java
Typsysteme
[A type system is a] tractablesyntactic method for proving the
absence of certain programbehaviors by classifying phrases
according to the kinds of values theycompute.
-Benjamin C. Pierce
Ruby
Duck-Typing
class Entedef beschreibung"Eine graue Ente"
enddef sprechen"Quak!"
endend
class Kuhdef beschreibung
"Eine dicke Kuh"enddef sprechen
"Muuuh!"end
enddef lass_sprechen tierputs tier.beschreibung+ " macht "+tier.sprechen
end
lass_sprechen Ente.newlass_sprechen Kuh.new
Ruby
Duck-Typing
class Entedef beschreibung"Eine graue Ente"
enddef sprechen"Quak!"
endend
class Kuhdef beschreibung
"Eine dicke Kuh"enddef sprechen
"Muuuh!"end
enddef lass_sprechen tierputs tier.beschreibung+ " macht "+tier.sprechen
end
lass_sprechen Ente.newlass_sprechen Kuh.new
Scala
statischstarkTypinferenz
object InferenceTest1extends Application {
val x = 1 + 2 * 3val y = x.toString()def succ(x: Int) = x + 1
}
Scala
statischstarkTypinferenz
object InferenceTest1extends Application {
val x = 1 + 2 * 3val y = x.toString()def succ(x: Int) = x + 1
}
Scala
object InferenceTest2 {def fac(n: Int) = if (n == 0) 1 else n * fac(n - 1)
}
———————–
case class MyPair[A, B](x: A, y: B);object InferenceTest3 extends Application {def id[T](x: T) = xval p = new MyPair(1, "scala")val q = id(1)
}
val x: MyPair[Int, String] =new MyPair[Int, String](1, "scala")
val y: Int = id[Int](1)
Scala
object InferenceTest2 {def fac(n: Int) = if (n == 0) 1 else n * fac(n - 1)
}
———————–
case class MyPair[A, B](x: A, y: B);object InferenceTest3 extends Application {def id[T](x: T) = xval p = new MyPair(1, "scala")val q = id(1)
}
val x: MyPair[Int, String] =new MyPair[Int, String](1, "scala")
val y: Int = id[Int](1)
Proc Objekte
Proc objects are blocks of code thathave been bound to a set of local
variables. Once bound, the code maybe called in different contexts and still
access those variables.-Ruby Dokumentation
Proc Objekte
def gen_times(factor)return Proc.new {|n| n*factor }
end
times3 = gen_times(3)times5 = gen_times(5)
times3.call(12) #=> 36times5.call(5) #=> 25times3.call(times5.call(4)) #=> 60
Proc Objekte
def foo (a, b)a.call(b)
end
putser = Proc.new {|x| puts x}foo(putser, 34)
————————————
putser = lambda {|x| puts x}
Proc Objekte
def foo (a, b)a.call(b)
end
putser = Proc.new {|x| puts x}foo(putser, 34)
————————————
putser = lambda {|x| puts x}
Code Blocks
# a naked block can’t live in Ruby# this is a compilation error !{puts "hello"}
———————–
# now it’s alive, having been converted# to a Proc !pr = lambda {puts "hello"}
pr.call
Code Blocks
# a naked block can’t live in Ruby# this is a compilation error !{puts "hello"}
———————–
# now it’s alive, having been converted# to a Proc !pr = lambda {puts "hello"}
pr.call
Code Blocks
10.times do |i|print "#{i} "
end
numbers = [1, 2, 5, 6, 9, 21]
numbers.each do |x|puts "#{x} is " + (x >= 3 ? "many" : "few")
end
squares = numbers.map {|x| x * x}
Nebenläufigkeit in Erlang
-module(ping_pong).-export([ping/0, pong/0]).
ping() ->Pong = spawn(ping_pong, pong, []),Pong ! {self(), ping},receivepong ->pong
end.
pong() ->receive{Ping, ping} ->Ping ! pong
end.
Scala - Funktionaler Zucker und Nebenläufigkeit
Actor-DesignpatternFunktionen höherer OrdnungAnonyme Funktionen
Actor-Pattern
import scala.actors.Actorimport scala.actors.Actor._
val fussyActor = actor {loop {receive {case s: String =>println("I got a String: " + s)
case i: Int =>println("I got an Int: " + i.toString)
case _ =>println("I have no idea what I just got.")
}}
}
Funktionen höherer Ordnung
def apply(f: Int => String, v: Int) = f(v)
———————–
class Decorator(left: String, right: String) {def layout[A](x: A) = left + x.toString() + right
}
object FunTest extends Application {def apply(f: Int => String, v: Int) = f(v)val decorator = new Decorator("[", "]")println(apply(decorator.layout, 7))
}
Funktionen höherer Ordnung
def apply(f: Int => String, v: Int) = f(v)
———————–
class Decorator(left: String, right: String) {def layout[A](x: A) = left + x.toString() + right
}
object FunTest extends Application {def apply(f: Int => String, v: Int) = f(v)val decorator = new Decorator("[", "]")println(apply(decorator.layout, 7))
}
Anonyme Funktionen
new Function1[Int, Int] {def apply(x: Int): Int = x + 1
}
(x: Int, y: Int) => "(" + x + ", " + y + ")"() => { System.getProperty("user.dir") }
Anonyme Funktionen
new Function1[Int, Int] {def apply(x: Int): Int = x + 1
}
(x: Int, y: Int) => "(" + x + ", " + y + ")"() => { System.getProperty("user.dir") }
Closures
object TargetTest1 extends Application {def whileLoop(cond: => Boolean)
(body: => Unit): Unit =if (cond) {bodywhileLoop(cond)(body)
}var i = 10whileLoop (i > 0) {println(i)i -= 1
}}
Einsatzgebiete und bekannte Projekte
Haskell → akademische WeltErlang → Telekommunikationssysteme (Ericsson)Ruby → Ruby on Rails (Web 2.0)Scala → Twitter (Web 2.0) aber auch z.B. durch französischemEnergie Unternehmen Électricité de France (EDF)
In Gedenken an Klaus’ Katzen-Presentationen...
2
Ich hoffe, dass hab ich...2http://catsonthecounter.blogspot.com/2009/09/im-not-lazyim-sickyeahthat.html