learn you a frege for great good!

46
Learn You a Frege for Great Good! Pure functional programming language for JVM CheshireCat (@y_taka_23) Tokyo Kabukiza.tech Meetup #9 (2016/03/20)

Upload: ytaka23

Post on 22-Jan-2017

653 views

Category:

Technology


2 download

TRANSCRIPT

Learn You a Frege for Great Good!Pure functional programming language for JVM

CheshireCat (@y_taka_23)

Tokyo Kabukiza.tech Meetup #9 (2016/03/20)

Who am I?

● Name : CheshireCat○ Twitter: @y_taka_23

○ GitHub: y-taka-23

● Favorites○ Haskell

○ Formal methods (Coq, Alloy, SPIN etc...)

● (Would-be) Frege evangelist

“Frege is a Haskell for JVM”

Agenda

● What is Frege?○ Basic features

○ Compatibility with Haskell

● Frege as a JVM language○ How to deal the impurity

○ Java interoperation

1. What is Frege?

Frege’s Essence

● Pure, non-strict functional language

● Strictly-typed, Hindley-Milner type inference

● Java interoperation with elegance

“Hello, World” in Haskell

module Hello where

greeting :: String -> Stringgreeting name = “Hello, ” ++ name

main :: IO ()main = do putStrLn $ greeting “World”

“Hello, World” in Frege

module Hello where

greeting :: String -> Stringgreeting name = “Hello, ” ++ name

main :: [String] -> IO ()main args = do putStrLn $ greeting “World”

That’s the spitting image!

“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

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

2. Frege as a JVM Language

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

Can we invoke Java in nicer waywith Frege’s purity?

“Levels” of Java’s Impurity

● Immutable○ ???

● Mutable, but without I/O○ ???

● With I/O○ ???

“Levels” of Java’s Impurity

● Immutable○ Maps to Frege’s data types directly

● Mutable, but without I/O○ ???

● With I/O○ ???

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 -> JBigIntadd3 n1 n2 n3 = (n1.add n2).add n3

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 -> JBigIntadd3 n1 n2 n3 = (n1.add n2).add n3

the identifier for Frege

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 -> JBigIntadd3 n1 n2 n3 = (n1.add n2).add n3

“pure native”, if it’s immutable

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 -> JBigIntadd3 n1 n2 n3 = (n1.add n2).add n3

the FQCN in Java

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 -> JBigIntadd3 n1 n2 n3 = (n1.add n2).add n3

the constructor

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 -> JBigIntadd3 n1 n2 n3 = (n1.add n2).add n3

BigInteger#add in Java

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 -> JBigIntadd3 n1 n2 n3 = (n1.add n2).add n3

invoke the method by dot-notations

“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

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 IntreadOneFrom filename = do fr <- JFReader.new filename fr.read

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 IntreadOneFrom filename = do fr <- JFReader.new filename fr.read

“mutable native”, if it acts on I/O

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 IntreadOneFrom filename = do fr <- JFReader.new filename fr.read

the return values are in IO contexts

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 IntreadOneFrom filename = do fr <- JFReader.new filename fr.read

use them as IO monads

“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

“Outwardly Pure” Methods

public String greeting(String name) { StringBuilder sb = new StringBuilder(“Hello, ”); sb.append(name); return sb.toString();}

“Outwardly Pure” Methods

public String greeting(String name) { StringBuilder sb = new StringBuilder(“Hello, ”); sb.append(name); return sb.toString();}

mutation (i.e. destructive updating)

“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

Employ ST Monads!

“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

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

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)

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

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

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”

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

Mutable Classes

greeting :: String -> ST s Stringgreeting name = do sb <- JBuilder.new “Hello, ” sb.append name sb.toString

pureFunc :: String -> StringpureFunc name = (greeting name).run

Mutable Classes

greeting :: String -> ST s Stringgreeting name = do sb <- JBuilder.new “Hello, ” sb.append name sb.toString

pureFunc :: String -> StringpureFunc name = (greeting name).run

use them as ST monads

Mutable Classes

greeting :: String -> ST s Stringgreeting name = do sb <- JBuilder.new “Hello, ” sb.append name sb.toString

pureFunc :: String -> StringpureFunc name = (greeting name).run

“run” it to retrieve the pure value

Mutable Classes

greeting :: String -> ST s Stringgreeting name = do sb <- JBuilder.new “Hello, ” sb.append name sb.toString

pureFunc :: String -> StringpureFunc name = (greeting name).run

we can regard it as a pure function

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

Have a Nice Frege Coding!Presented by

CheshireCat (@y_taka_23)