3. Java Bytecode
§ ¤
x = 5 + 6; // J a v a
¦ ¥
§ ¤
( d e f x (+ 5 6 ) ) ; Clojure
¦ ¥
§ ¤
0 iload_1 // J a v a b y t e c o d e
1 iload_2
2 iadd
3 istore_3
¦ ¥
§ ¤
add eax , edx ; Assembler
mov ecx , eax
¦ ¥
5. Trenger vi funksjoner i Java?
§ ¤
L i s t <S t r i n g > n a v n e L i s t e = . . .
L i s t <S t r i n g > navnPaaE = new A r r a y L i s t <S t r i n g >() ;
f o r ( S t r i n g navn : n a v n e L i s t e ) {
i f ( navn . s t a r t s W i t h ( "E" ) ) {
navnPaaE . add ( navn ) ;
}
}
¦ ¥
§ ¤
val navneListe : List [ String ] = . . .
v a l navnPaaE = n a v n e L i s t e . f i l t e r (_ s t a r t s W i t h "E" )
¦ ¥
7. Scala
§ ¤
// F u n k s j o n som v a r i a b e l
v a l p a r t a l l = ( x : I n t ) = x % 2 == 0
>
p a r t a l l ( 4 ) // t r u e
// F u n k s j o n som argument
v a l parU20 = ( 1 u n t i l 2 0 ) . f i l t e r ( p a r t a l l )
// Anonym f u n k s j o n
v a l parU20 = ( 1 u n t i l 2 0 ) . f i l t e r (_ % 2 == 0 )
¦ ¥
8. JRuby
§ ¤
# F u n k s j o n som v a r i a b e l
p a r t a l l = lambda { | x | x % 2 == 0 }
p a r t a l l . c a l l (4) # true
# F u n k s j o n som argument
parU20 = ( 1 . . . 2 0 ) . f i n d _ a l l { p a r t a l l }
# Anonym f u n k s j o n
parU20 = ( 1 . . . 2 0 ) . f i n d _ a l l { | x | x % 2 == 0 }
¦ ¥
9. Groovy
§ ¤
// F u n k s j o n som v a r i a b e l
p a r t a l l = { i t % 2 == 0 }
p a r t a l l ( 4 ) // t r u e
// F u n k s j o n som argument
parU20 = ( 1 . . < 2 0 ) . f i n d A l l ( p a r t a l l )
// Anonym f u n k s j o n
parU20 = ( 1 . . < 2 0 ) . f i n d A l l ( { i t % 2 == 0 } )
¦ ¥
10. Clojure
§ ¤
; D e f i n e r f u n k s j o n som v e r d i
( d e f n p a r t a l l [ x ] (= 0 (mod x 2 ) ) )
( p a r t a l l 4) ; t r u e
; F u n k s j o n som argument
( d e f parU20
( filter partall
( range 20) ) )
; Anonym f u n k s j o n
( d e f parU20
( f i l t e r ( f n [ x ] (= 0 (mod x 2 ) ) )
( range 20) ) )
¦ ¥
11. Java 7
§ ¤
// F u n k s j o n som v a r i a b e l
#i n t ( i n t ) p a r t a l l = #( i n t x ) { x % 2 == 0}
p a r t a l l ! ( 4 ) // t r u e
// F u n k s j o n som argument
L i s t <I n t e g e r > t i l 2 0 = // Lag a r r a y med t a l l e n e 1 t i l 20
L i s t <I n t e g e r > parU20 = t i l 2 0 . f i l t e r ( p a r t a l l )
// Anonym f u n k s j o n
L i s t <I n t e g e r > parU20 = t i l 2 0 . f i l t e r (
#( i n t x ) { x % 2 == 0 } )
¦ ¥
12. Klasser i Java
§ ¤
i n t e r f a c e F u n c t i o n <A , R> {
R e x e c (A a r g ) ;
}
F u n c t i o n <I n t e g e r , Boolean > p a r t a l l =
new F u n c t i o n <I n t e g e r , Boolean >() {
p u b l i c Boolean exec ( I n t e g e r arg ) {
r e t u r n a r g % 2 == 0 ;
}
};
i n t e r f a c e L i s t <T> {
L i s t f i l t e r ( F u n c t i o n <T , Boolean > f n ) ;
}
L i s t nummer = . . .
nummer . f i l t e r ( new P a r t a l l ( ) )
¦ ¥
14. Rene funksjoner er tabeller!
§ ¤
d e f PI = 3 . 1 4
def dobbel ( x : I n t ) = x ∗ 2
d e f leggSammen ( x : I n t , y : I n t ) = x + y
¦ ¥
Funksjon Argumenter Returverdi
PI - 3.14
dobbel 2 4
dobbel 21 42
leggSammen 2, 3 5
leggSammen 20, 22 42
16. Clojure – memoization
§ ¤
( defn slow−double [ n ]
( Thread / s l e e p 1 0 0 )
(∗ n 2) )
( d e f mem−double ( memoize s l o w − d o u b l e ) )
( def values [1 2 1 2 1 2])
( t i m e ( d o r u n ( map s l o w − d o u b l e v a l u e s ) ) )
; " E l a p s e d t i m e : 6 0 2 . 9 3 1 msecs "
( t i m e ( d o r u n ( map mem−double v a l u e s ) ) )
; " E l a p s e d t i m e : 2 0 0 . 7 4 4 msecs "
¦ ¥
18. Rekursjon
• Stas i funksjonell programmering
• Mange eksekveringer på stakken
• Mye snakk om (mangel på) “tail-call optimization”
§ ¤
( defn f i b [ n ]
( i f (<= n 1 )
1
(+ ( f i b (− n 1 ) ) ( f i b (− n 2 ) ) )
)
)
¦ ¥
19. Scala – tail-call optimization
§ ¤
d e f a p p r o x i m a t e ( g u e s s : Double ) : Double =
i f ( isGoodEnough ( g u e s s ) ) g u e s s
e l s e approximate ( improve ( guess ) )
¦ ¥
§ ¤
d e f a p p r o x i m a t e L o o p ( i n i t i a l G u e s s : Double ) : Double = {
var guess = i n i t i a l G u e s s
w h i l e ( ! isGoodEnough ( g u e s s ) )
guess = improve ( guess )
guess
}
¦ ¥
21. Scala – 2.7.x
§ ¤
// R e t u r n e r e r RandomAccessSeq . P r o j e c t i o n [ I n t ]
v a l x5 = f o r ( i <− 0 t o 1 0 ) y i e l d ( i ∗ 5 )
// F ø r s t h e r b l i r v e r d i e n k a l k u l e r t
p r i n t l n ( " 5 x 4 = " + x5 ( 4 ) )
// S a m t i d i g h e t s −p u z z l e
v a l a c t o r s = f o r ( i <− 0 t o 1 0 ) y i e l d a c t o r { . . . }
¦ ¥
22. Scala – 2.8
§ ¤
// abba , r e g n i n g e r , t i l l i t , i n n i
d e f i s P a l i n d r o m e ( x : S t r i n g ) = x == x . r e v e r s e
d e f f i n d P a l i n d r o m e ( s : Seq [ S t r i n g ] ) =
s . find ( isPalindrome )
// M i d l e r t i d i g s e k v e n s en m i l l i o n e l e m e n t e r
f i n d P a l i n d r o m e ( words t a k e 1 0 0 0 0 0 0 )
// M i d l e r t i d i g s e k v e n s kun f r e m t i l f ø r s t e treff
f i n d P a l i n d r o m e ( words . v i e w t a k e 1 0 0 0 0 0 0 )
¦ ¥
23. by-name param
§ ¤
// T y p i s k J a v a . . .
i f ( debugLogEnabled ( ) ) {
l o g . debug ( " T e k s t " + t u n g B e r e g n i n g ( ) + " t e k s t " ) ;
}
¦ ¥
§ ¤
// F o r e n k l e t s l f 4 s
d e f debug ( msg : = S t r i n g ) =
>
i f ( debugLogEnabled ) {
debugLog . w r i t e ( msg )
}
// T y p i s k S c a l a . . . : )
l o g . debug ( " T e k s t " + t u n g B e r e g n i n g + " t e k s t " )
¦ ¥
24. Clojure – uendelige sekvenser
§ ¤
( d ef p o s I n t s ( i t e r a t e i n c 0) )
( t a k e 10 p o s I n t s )
( def rands ( r e p e a t e d l y rand ) )
( take 3 rands )
¦ ¥
26. Typesystemer
• Type inference
• Implisitt konvertering
• Pattern matching
• Avanserte type-parametre/generics
§ ¤
val x = 5
val x : Int = 5
d e f add ( x : I n t , y : I n t ) = x + y
val l i s t = L i s t (1 , 2 , 3) // L i s t [ I n t ]
val l i s t = L i s t (1 , 2 , 3.0) // L i s t [ AnyVal ]
val l i s t = L i s t ( 1 , " t o " , 3 . 0 ) // L i s t [ Any ]
¦ ¥
27. Pattern matching
§ ¤
d e f d e s c ( x : Any ) = x match {
case 5 = " f i v e "
>
c a s e i : I n t i f i > 10 = " i n t : " + i . t o S t r i n g
>
case s : S t r i n g = " s t r : " + s
>
case (a , b) = " t u p l e : " + a + b
>
c a s e _ = " unknown "
>
}
d e s c ( 5 ) // " f i v e "
d e s c ( 6 ) // " unknown "
d e s c ( 1 1 ) // " i n t : 11"
¦ ¥
29. Funksjonell programmering og ytelse
• Funksjonell vs. imperativ
• Dynamisk vs. statisk typing
• Autoboxing/primitiver
• Data strukturer
• Rene funksjoner - memoization
• Samtidighet/parallell-prosessering
30. Løkker – for comprehension vs. while
• Scala for comprehension – filter, map og flatMap
• “Vanlig” løkke – while
• 1000x1000 matrise + funksjoner:
• for med yield – 8090ms
• for uten yield – 3507ms
• while – 1865ms
§ ¤
val l i s t = f o r ( i <− 1 t o 1 0 ) y i e l d ( i ∗ 2 )
var l i s t : L i s t [ Int ] = Nil
f o r ( i <− 1 t o 1 0 ) l i s t += i ∗ 2
var i = 1
var l i s t : L i s t [ Int ] = Nil
w h i l e ( i <= 1 0 ) {
l i s t += i ∗ 2
i += 1
}
¦ ¥
31. Dynamisk vs. statisk typing
• Legge til 1 i løkke 10 mill ganger
• Dynamisk typing er tregt på JVM – invokedynamic
• Obs! “Idiot”-implementasjoner
§ ¤
Java time : 8ms
Groovy time : 398ms
JRuby time : 1071ms
Scala time : 18ms
Clojure time : 300ms
Clojure time : 186ms ( t y p e h i n t s )
¦ ¥
§ ¤
( d ef j 1)
( print " Clojure ")
( time
( dotimes [ i 10000000]
(+ ( i n t i ) ( i n t j ) ) ) )
¦ ¥
32.
33. Andre foredrag på JavaZone:
8. september:
10:15 - Scala - fra newbie til ninja på en time
11:45 - Howto: Implement Collaborative Filtering with Map/Reduce
13:00 - Pattern matching in Scala
14:15 - Kontoeksempelet i Java og Clojure
14:15 - Akka: Simpler Scalability, Fault-Tolerance, Concurrency &
Remoting through Actors
15:45 - Erjang - A JVM-based Erlang VM
17:00 - Cloud Computing with Scala and GridGain
9. september:
17:00 - Practical use of Scala Actors