The slides are for Tokyo Kabukiza.tech Meetup #9 "Programming Languages Battle Royal." An introduction to Frege - Haskell for JVM, focusing on the Java interoperation with monads. The original talk is in Japanese (http://www.slideshare.net/y_taka_23/frege).
6. Frege’s Essence
● Pure, non-strict functional language
● Strictly-typed, Hindley-Milner type inference
● Java interoperation with elegance
7. “Hello, World” in Haskell
module Hello where
greeting :: String -> String
greeting name = “Hello, ” ++ name
main :: IO ()
main = do
putStrLn $ greeting “World”
8. “Hello, World” in Frege
module Hello where
greeting :: String -> String
greeting name = “Hello, ” ++ name
main :: [String] -> IO ()
main args = do
putStrLn $ greeting “World”
10. “Learn you a Haskell” Translation
● All example snipets into Frege
○ https://github.com/y-taka-23/learn-you-a-frege
● Compilable even in “dead-copied” translation
11. Compatibility with Haskell
● Syntax, standard libs : almost compatible!
● Hard to use in “practical” Haskell
○ External dependencies
○ Most of GHC extensions
○ Template Haskell
● Java interoperation is necessary
13. Advantage of JVM Languages
● Platform-independent
○ Frege compiler generates Java source codes
● Feel free to invoke Java libraries
○ But pretty different regarding side-effects
■ Frege : Pure
■ Java : Impure, objects have own states
14. Can we invoke Java in nicer way
with Frege’s purity?
15. “Levels” of Java’s Impurity
● Immutable
○ ???
● Mutable, but without I/O
○ ???
● With I/O
○ ???
16. “Levels” of Java’s Impurity
● Immutable
○ Maps to Frege’s data types directly
● Mutable, but without I/O
○ ???
● With I/O
○ ???
17. Immutable Classes
data JBigInt =
pure native java.math.BigInteger where
pure native new :: String -> JBigInt
pure native add :: JBigInt -> JBigInt
-> JBigInt
add3 :: JBigInt -> JBigInt -> JBigInt
-> JBigInt
add3 n1 n2 n3 = (n1.add n2).add n3
18. Immutable Classes
data JBigInt =
pure native java.math.BigInteger where
pure native new :: String -> JBigInt
pure native add :: JBigInt -> JBigInt
-> JBigInt
add3 :: JBigInt -> JBigInt -> JBigInt
-> JBigInt
add3 n1 n2 n3 = (n1.add n2).add n3
the identifier for Frege
19. Immutable Classes
data JBigInt =
pure native java.math.BigInteger where
pure native new :: String -> JBigInt
pure native add :: JBigInt -> JBigInt
-> JBigInt
add3 :: JBigInt -> JBigInt -> JBigInt
-> JBigInt
add3 n1 n2 n3 = (n1.add n2).add n3
“pure native”, if it’s immutable
20. Immutable Classes
data JBigInt =
pure native java.math.BigInteger where
pure native new :: String -> JBigInt
pure native add :: JBigInt -> JBigInt
-> JBigInt
add3 :: JBigInt -> JBigInt -> JBigInt
-> JBigInt
add3 n1 n2 n3 = (n1.add n2).add n3
the FQCN in Java
21. Immutable Classes
data JBigInt =
pure native java.math.BigInteger where
pure native new :: String -> JBigInt
pure native add :: JBigInt -> JBigInt
-> JBigInt
add3 :: JBigInt -> JBigInt -> JBigInt
-> JBigInt
add3 n1 n2 n3 = (n1.add n2).add n3
the constructor
22. Immutable Classes
data JBigInt =
pure native java.math.BigInteger where
pure native new :: String -> JBigInt
pure native add :: JBigInt -> JBigInt
-> JBigInt
add3 :: JBigInt -> JBigInt -> JBigInt
-> JBigInt
add3 n1 n2 n3 = (n1.add n2).add n3
BigInteger#add in Java
23. Immutable Classes
data JBigInt =
pure native java.math.BigInteger where
pure native new :: String -> JBigInt
pure native add :: JBigInt -> JBigInt
-> JBigInt
add3 :: JBigInt -> JBigInt -> JBigInt
-> JBigInt
add3 n1 n2 n3 = (n1.add n2).add n3
invoke the method by dot-notations
24. “Levels” of Java’s Impurity
● Immutable
○ Maps to Frege’s data types directly
● Mutable, but without I/O
○ ???
● With I/O
○ Maps to IO monads
25. Classes with I/O
data JFReader =
mutable native java.io.FileReader where
native new :: String -> IO JFReader
native read :: JFReader -> IO Int
readOneFrom :: String -> IO Int
readOneFrom filename = do
fr <- JFReader.new filename
fr.read
26. Classes with I/O
data JFReader =
mutable native java.io.FileReader where
native new :: String -> IO JFReader
native read :: JFReader -> IO Int
readOneFrom :: String -> IO Int
readOneFrom filename = do
fr <- JFReader.new filename
fr.read
“mutable native”, if it acts on I/O
27. Classes with I/O
data JFReader =
mutable native java.io.FileReader where
native new :: String -> IO JFReader
native read :: JFReader -> IO Int
readOneFrom :: String -> IO Int
readOneFrom filename = do
fr <- JFReader.new filename
fr.read
the return values are in IO contexts
28. Classes with I/O
data JFReader =
mutable native java.io.FileReader where
native new :: String -> IO JFReader
native read :: JFReader -> IO Int
readOneFrom :: String -> IO Int
readOneFrom filename = do
fr <- JFReader.new filename
fr.read
use them as IO monads
29. “Levels” of Java’s Impurity
● Immutable
○ Maps to Frege’s data types directly
● Mutable, but without I/O
○ ???
● With I/O
○ Maps to IO monads
30. “Outwardly Pure” Methods
public String greeting(String name) {
StringBuilder sb =
new StringBuilder(“Hello, ”);
sb.append(name);
return sb.toString();
}
32. “Outwardly Pure” Methods
public String greeting(String name) {
StringBuilder sb =
new StringBuilder(“Hello, ”);
sb.append(name);
return sb.toString();
}
but the return value is pure, though
34. “Levels” of Java’s Impurity
● Immutable
○ Maps to Frege’s data types directly
● Mutable, but without I/O
○ Maps to ST monads
● With I/O
○ Maps to IO monads
35. ST (State Transformer) Monads
● Encapsulates destructive mutations
● ST s TypeName
○ s represents ”unobservable” internal states
○ s must be a type variable
● We can retrieve pure values from the contexts
○ Unlike IO monads
36. Mutable Classes
data JBuilder =
native java.lang.StringBuilder where
native new :: String
-> ST s (Mutable s JBuilder)
native append :: Mutable s JBuilder
-> String
-> ST s (Mutable s JBuilder)
37. Mutable Classes
data JBuilder =
native java.lang.StringBuilder where
native new :: String
-> ST s (Mutable s JBuilder)
native append :: Mutable s JBuilder
-> String
-> ST s (Mutable s JBuilder)
“native”, if it has no I/O effects
38. Mutable Classes
data JBuilder =
native java.lang.StringBuilder where
native new :: String
-> ST s (Mutable s JBuilder)
native append :: Mutable s JBuilder
-> String
-> ST s (Mutable s JBuilder)
“unobservable” states
39. Mutable Classes
data JBuilder =
native java.lang.StringBuilder where
native new :: String
-> ST s (Mutable s JBuilder)
native append :: Mutable s JBuilder
-> String
-> ST s (Mutable s JBuilder)
wrap the values in “Mutable s”
40. Mutable Classes
data JBuilder =
native java.lang.StringBuilder where
native new :: String
-> ST s (Mutable s JBuilder)
native append :: Mutable s JBuilder
-> String
-> ST s (Mutable s JBuilder)
the return values are in ST contexts
41. Mutable Classes
greeting :: String -> ST s String
greeting name = do
sb <- JBuilder.new “Hello, ”
sb.append name
sb.toString
pureFunc :: String -> String
pureFunc name = (greeting name).run
42. Mutable Classes
greeting :: String -> ST s String
greeting name = do
sb <- JBuilder.new “Hello, ”
sb.append name
sb.toString
pureFunc :: String -> String
pureFunc name = (greeting name).run
use them as ST monads
43. Mutable Classes
greeting :: String -> ST s String
greeting name = do
sb <- JBuilder.new “Hello, ”
sb.append name
sb.toString
pureFunc :: String -> String
pureFunc name = (greeting name).run
“run” it to retrieve the pure value
44. Mutable Classes
greeting :: String -> ST s String
greeting name = do
sb <- JBuilder.new “Hello, ”
sb.append name
sb.toString
pureFunc :: String -> String
pureFunc name = (greeting name).run
we can regard it as a pure function
45. Summary
● Frege is the very Haskell for JVM
○ Syntax is just like Haskell’s
○ Pretty low learning cost for Haskellers
● Java interoperation with elegance
○ Compatible with the Haskell-like type system
○ Classify side-effects into pure, ST and IO
46. Have a Nice Frege Coding!
Presented by
CheshireCat (@y_taka_23)