BEAUTY AND THE BEAUTY AND THE BEAST BEAST Eta Haskell for JVM - - PowerPoint PPT Presentation

beauty and the beauty and the beast beast
SMART_READER_LITE
LIVE PREVIEW

BEAUTY AND THE BEAUTY AND THE BEAST BEAST Eta Haskell for JVM - - PowerPoint PPT Presentation

BEAUTY AND THE BEAUTY AND THE BEAST BEAST Eta Haskell for JVM JAREK RATAJSKI JAREK RATAJSKI @jarek000000 Loves programming since the first line I wrote for C64 Anarchitect @ Engenius GmbH Java developer (since 1999) with a functional


slide-1
SLIDE 1

BEAUTY AND THE BEAUTY AND THE BEAST BEAST

Eta Haskell for JVM

slide-2
SLIDE 2

JAREK RATAJSKI JAREK RATAJSKI

@jarek000000 Loves programming since the first line I wrote for C64 Anarchitect @ Engenius GmbH Java developer (since 1999) with a functional heart.

slide-3
SLIDE 3

ORIGIN ORIGIN

slide-4
SLIDE 4

Lots of developers that love Haskell

slide-5
SLIDE 5

but when it comes to business...

slide-6
SLIDE 6
slide-7
SLIDE 7
slide-8
SLIDE 8

SOLUTIONS SOLUTIONS

slide-9
SLIDE 9

WRITE WRITE HASKELL HASKELL USING JAVA USING JAVA

return List.ofAll(iterableRead) .foldLeft(HashMap.<String, Topic>empty(), (existingMap, newElement) -> existingMap.put( newElemen existingMap.get( n .getOrElse .addMessag ); } catch (IOException e) { return HashMap.<String, Topic>empty(); }

slide-10
SLIDE 10

WRITE WRITE HASKELL HASKELL USING SCALA USING SCALA

implicit val treeApplicative: Applicative[Tree] = new Applic def point[A](a: => A): Tree[A] = Tree(a, Seq.empty) def ap[A, B](fa: => Tree[A])(tf: => Tree[A => B]): Tree[B] val Tree(f, tfs) = tf Tree(f(fa.root), fa.children.map(t => t.map(f)) ++ tfs.m } }

slide-11
SLIDE 11

WRITE HASKELL USING HASKELL WRITE HASKELL USING HASKELL (ETA) (ETA)

slide-12
SLIDE 12

deploy to JVM

slide-13
SLIDE 13

work with Java

slide-14
SLIDE 14

TYPELEAD TYPELEAD

Company founded to create eta and in the future provide commercial support for it.

slide-15
SLIDE 15

I am not associated with Typelead.

slide-16
SLIDE 16

Whatever I say or show here are mine own studies. I got help from typelead developers and eta community. I am neither experienced haskell nor eta developer. What I say might be wrong or may not reflect the reality or the future. I just tried to do my best.

slide-17
SLIDE 17

We talk about half-finished product.

slide-18
SLIDE 18

ETA 1.2.3 INTRO ETA 1.2.3 INTRO

slide-19
SLIDE 19

QUICKSORT(*) QUICKSORT(*)

quicksort [] = [] quicksort (x:xs) = quicksort left ++ [x] ++ quicksort right where left = [ y | y <- xs, y < x ] right = [ y | y <- xs, y >= x ] main = do let result = quicksort arr putStrLn $ show result where arr = [1,7,9,12,90,1,-1,22,0] $ eta Main.hs $ java -jar Main.jar [-1,0,1,1,7,9,12,22,90]

slide-20
SLIDE 20

ETLAS (CABAL FOR ETA) ETLAS (CABAL FOR ETA)

$ etlas init $ etlas build $ etlas run

slide-21
SLIDE 21

For more info see page Eta tour

slide-22
SLIDE 22

ETA SPECIAL ETA SPECIAL

ETA =~= ETA =~= GHC FOR JVM GHC FOR JVM

slide-23
SLIDE 23

backend for GHC -> great compatibility

slide-24
SLIDE 24

STG machine

Fibb.fibbtcoinner :: forall a_a7U9 a1_a7UA. (GHC.Classes.Eq a_a7U9, GHC.Num.Num a_a7U9, GHC.Num.Num a a_a7U9 -> a1_a7UA -> a1_a7UA -> a1_a7UA [GblId, Arity=6, Caf=NoCafRefs, Str=<S(C(C(S))L),U(C(C1(U)),A)><L,U(A,C(C1(U)),A,A,A,A,C(U))> Unf=OtherCon []] = \r srt:SRT:[] [$dEq_s8MJ $dNum_s8MK $dNum1_s8ML eta_s8MM eta1_s8MN eta2_s8MO]

slide-25
SLIDE 25

SPINELESS, TAGLESS G-MACHINE SPINELESS, TAGLESS G-MACHINE

slide-26
SLIDE 26

STG STG

...It defines how the Haskell evaluation model should be efficiently implemented on standard hardware. ...

slide-27
SLIDE 27

STG =~= (bytocode or llvm)

slide-28
SLIDE 28

1ST PHASE HS TO STG 1ST PHASE HS TO STG

Eta compiler in a phase .hs to STG ..is simply a GHC code! (forked)

slide-29
SLIDE 29

2ND PHASE 2ND PHASE - STG TO BYTECODE /

  • STG TO BYTECODE /

JVM JVM

slide-30
SLIDE 30

0: getstatic #127 // Field DZMZN:Leta/runti 3: ifnull 9 6: goto 35 9: ldc #3 // class ghc_prim/ghc/Typ 11: dup 12: astore_0 13: monitorenter 14: getstatic #127 // Field DZMZN:Leta/runt 17: ifnull 23 20: goto 33 23: new #129 // class ghc_prim/ghc/ty 26: dup 27: invokespecial #131 // Method ghc_prim/ghc/t 30: putstatic #127 // Field DZMZN:Leta/runt 33: aload_0

slide-31
SLIDE 31

C IMPORTS C IMPORTS

GHC supports native(C language) calls. (for instance used in Base packages)

slide-32
SLIDE 32

Eta rewrites those parts to use jvm calls.

  • riginal GHC Float.hs fragment

Eta Float.hs fragment

foreign import ccall unsafe "isFloatNaN" isFloatNaN :: Float - foreign import ccall unsafe "isFloatInfinite" isFloatInfinite foreign import ccall unsafe "isFloatDenormalized" isFloatDenor foreign import ccall unsafe "isFloatNegativeZero" isFloatNegat foreign import ccall unsafe "isFloatFinite" isFloatFinite :: F foreign import java unsafe "@static java.lang.Float.isNaN" isFloatNaN :: Float -> Bool foreign import java unsafe "@static java.lang.Float.isInfinite isFloatInfinite :: Float -> Bool foreign import java unsafe "@static eta.base.Utils.isFloatDeno isFloatDenormalized :: Float -> Bool foreign import java unsafe "@static eta.base.Utils.isFloatNega isFloatNegativeZero :: Float -> Bool foreign import java unsafe "@static eta.base.Utils.isFloatFini isFloatFinite :: Float -> Bool

slide-33
SLIDE 33

ETLAS ETLAS

Haskell GHC developers use cabal (or stack). Etlas is eta tool which is ~ cabal. It uses .cabal file format with extensions.

slide-34
SLIDE 34

HACKAGE HACKAGE

slide-35
SLIDE 35

Tons of libraries for haskell. De facto standard.

slide-36
SLIDE 36

Categories: (3), - (1), .NET (9), Accessibility (3), ACME (49 AI (51), Algebra (35), Algorithm (3), Algorithm Visualization Anatomy (1), Animation (6), AOP (2), API (26), Apple (3), Appl Applicative (1), Argumentation (4), Arrows (5), Artificial In Aspect Oriented Programming (2), AST (1), Atom (1), ATS (8), Audio (13), Authentication (9), Automation (2), Avers (4), Av Benchmarking (11), Big Data (2), Binary (1), Bindings (39), B Bitcoin (12), Blockchain (1), Browser (7), BSD (1), Bsd3 (1) Builders (1), Business (3), ByteString (3), ByteStrings (1),

slide-37
SLIDE 37

ETA HACKAGE PATCHES ETA HACKAGE PATCHES

slide-38
SLIDE 38

Project typelead/hackage == patches for common hackage projects.

slide-39
SLIDE 39

Mostly 1 to 1 native C to Java calls changes. https://github.com/typelead/eta- hackage/blob/master/patches/text-1.2.2.2.patch

{-# INLINE equal #-}

  • foreign import ccall unsafe "_hs_text_memcpy" memcpyI

+foreign import java unsafe "@static eta.text.Utils.memcpy" m :: MutableByteArray# s -> CSize -> ByteArray# -> CSize -

  • foreign import ccall unsafe "_hs_text_memcmp" memcmp

+foreign import java unsafe "@static eta.text.Utils.memcmp" m :: ByteArray# -> CSize -> ByteArray# -> CSize -> CSize -

slide-40
SLIDE 40

SUPPORTS COMPILE SUPPORTS COMPILE EXTENSIONS EXTENSIONS

slide-41
SLIDE 41

{-# LANGUAGE FlexibleContexts, DataKinds, TypeFamilies, RankNT

  • - whatever
slide-42
SLIDE 42

Eta is as close as you can get with Haskell/GHC on JVM

slide-43
SLIDE 43

Lots of crazy haskell codes that use GHC extensions work on Eta without any problems.

slide-44
SLIDE 44

BASIC BASIC OPTIMIZATIONS OPTIMIZATIONS

slide-45
SLIDE 45

TCO TCO

slide-46
SLIDE 46

Naive fibonacci

fibnaive 0 = 1 fibnaive 1 = 1 fibnaive n = fibnaive ( n-1) + fibnaive ( n - 2)

slide-47
SLIDE 47

better

fibtcoinner 0 sum presum = sum fibtcoinner n sum presum = fibtcoinner (n-1) (sum + presum) s fibtco n = fibbtcoinner n 1 0

slide-48
SLIDE 48

Java

private static BigInteger fibonacci(int n, BigInteger sum, Big if ( n== 0) { return sum; } else { return fibonacci(n-1, sum.add(presum), sum); } }

slide-49
SLIDE 49

How much java stands?

slide-50
SLIDE 50

~ 10.000

slide-51
SLIDE 51

Eta

fibtcoinner 0 sum presum = sum fibtcoinner n sum presum = fibtcoinner (n-1) (sum + presum) s fibtco n = fibbtcoinner n 1 0

slide-52
SLIDE 52

First results....

slide-53
SLIDE 53

[1,1,2,4,8,16,32,64,128,256,512...]

slide-54
SLIDE 54

BUG #603 BUG #603

It took couple of nights to fix this bug. I've Learned ... haskell

slide-55
SLIDE 55

Error

while(var8) { Main.sat_s7YH var12 = new Main.sat_s7YH(var3); var1.R1 = var2; Closure var13 = Classes.zeze().enter(var1).apply2(var1, ( if (!(var13 instanceof False)) { return ((Closure)var10).evaluate(var1); } Main.sat_s7YM var14 = new Main.sat_s7YM(var4, (Closure)va Main.sat_s7YL var15 = new Main.sat_s7YL(var3, (Closure)va var9 = var15; //assign n-1 var10 = var14; //assign new sum var11 = var14; //assign presum var8 = true;

slide-56
SLIDE 56

while( n > 0) { n = n -1; newSum = presum + sum sum = newSum presum = sum }

slide-57
SLIDE 57

from http://geek-and-poke.com

slide-58
SLIDE 58

while( n > 0) { n = n -1; newSum = presum + sum presum = sum // swapped sum = newSum // swapped

slide-59
SLIDE 59

Fix

slide-60
SLIDE 60

Fix compiler of Haskell written in Haskell (ghc) while learning haskell.

slide-61
SLIDE 61
slide-62
SLIDE 62

withContinuation unknownCall contCode lastCode JumpToIt label cgLocs mLne -> do JumpToIt label c traceCg (str "cgIdApp: JumpToIt") traceCg (st

  • codes <- getNonVoidArgCodes args + deps <- depe
  • emit $ multiAssign cgLocs codes + let sorted =

+ codes <- getNonVoidArgCodes $ arg <$> sorted + emit $ multiAssign (from <$> sorted) codes <> maybe mempty <> maybe mempty (\(target, targetLoc) -> (\ storeLoc targetLoc (iconst (locFt targetLoc mLne mLne <> goto label <> goto label +data LocalDep = LocalDep Int Int +{-

slide-63
SLIDE 63

Decompiled eta. Fixed.

while(var8) { Main.sat_s7YH var12 = new Main.sat_s7YH(var3); var1.R1 = var2; Closure var13 = Classes.zeze().enter(var1).apply2(var1, ( if (!(var13 instanceof False)) { return ((Closure)var10).evaluate(var1); } Main.sat_s7YM var14 = new Main.sat_s7YM(var4, (Closure)va Main.sat_s7YL var15 = new Main.sat_s7YL(var3, (Closure)va var11 = var10; //assign presum var10 = var14; //assign new sum var9 = var15; //assign n-1 var8 = true; }

slide-64
SLIDE 64

HOW MUCH ETA STANDS??? HOW MUCH ETA STANDS???

slide-65
SLIDE 65

main = print $ show $ fibtco 1000000

slide-66
SLIDE 66

yes 1.000.000

slide-67
SLIDE 67

TRAMPOLINE TRAMPOLINE

import Control.Monad.Trans.Cont fibCps::Int->Cont r Int fibCps 0 = return 1 fibCps 1 = return 1 fibCps n = do n1 <- fibCps $ n-1 n2 <- fibCps $ n-2 return $ n1 + n2 main = do let result = trampoline $ runCont ( fibCps 100 ) id putStrLn $ show result

slide-68
SLIDE 68

PERFORMANCE PERFORMANCE

slide-69
SLIDE 69

JMH Quick sort implementations exported and called from java naive and real quicksort compared to same solutions in Java (using vavr.io) not very professional - just to get some overview

slide-70
SLIDE 70

Naive quicksort Eta Naive quicksort Java/vavr

quicksort [] = [] quicksort (x:xs) = quicksort left ++ [x] ++ quicksort right where left = [ y | y <- xs, y < x ] right = [ y | y <- xs, y >= x ] private List<Integer> qsort(List<Integer> input) { if (!input.isEmpty()) { final int middle = input.head(); final List<Integer> left = input.tail().filter( final List<Integer> right = input.tail().filter return qsort(left).appendAll(qsort(right).prepe } else { return input; } }

slide-71
SLIDE 71

Real quicksort ETA

qvsort :: (G.Vector v a, Ord a) => v a -> v a qvsort = G.modify go where go xs | M.length xs < 2 = return () | otherwise = do p <- M.read xs (M.length xs `div` 2) j <- M.unstablePartition (< p) xs let (l, pr) = M.splitAt j xs k <- M.unstablePartition (== p) pr go l; go $ M.drop k pr myvsort ::[Int] ->[Int] myvsort li = let vec = V.fromList li :: (V.Vector Int) sorted = qvsort vec :: (V.Vector Int) converted = V.toList sorted :: [Int]

slide-72
SLIDE 72

Real quicksort Java (*)

list.sort(); // :-)

slide-73
SLIDE 73

Results

slide-74
SLIDE 74

VS OTHER VS OTHER HASKELLS HASKELLS

12 Queens

slide-75
SLIDE 75

{-# LANGUAGE BangPatterns #-}

  • - solution by Oystein Kolsrud
  • - https://www.youtube.com/watch?v=I2tMmsZC1ZU
  • kToAdd :: Int -> [Int] -> Bool
  • kToAdd q qs = all (okToAddDirection q qs) [succ, pred, id]

where

  • kToAddDirection q qs f = and $ zipWith (/=) (tail

extendSolution n qs = map (\q -> q:qs) $ filter (\q -> okTo allSolutions !n 0 = [[]] allSolutions !n k = concatMap (extendSolution n) (allSoluti

slide-76
SLIDE 76

Implementation Task Solutions Time (real) Frege 12 Queens 14200 Solutions (*)45.816s Eta 12 Queens 14200 Solutions (*)26.472s Ghc 12 Queens 14200 Solutions 9.806s

slide-77
SLIDE 77

Unfair benchmark - both frege and eta were measured with JVM startup time.

slide-78
SLIDE 78

JAVA JAVA INTEROPABILITY INTEROPABILITY

slide-79
SLIDE 79

JWT - JAVA TYPES JWT - JAVA TYPES

data JColor = JColor @java.awt.Color deriving Class

slide-80
SLIDE 80

FOREIGN IMPORT FOREIGN IMPORT

foreign import java unsafe "getGreen" getGreen :: Java JColor Int

slide-81
SLIDE 81

Java is a Monad.

  • - Execute a Java action in the IO monad.

java :: Java c a -> IO a

  • - Execute a Java action in the IO monad with respect to the
  • - given object.

javaWith :: (Class c) => c -> Java c a -> IO a

  • - Execute a Java action in the Java monad of another class
  • - with respect to the given object.

(<.>) :: (Class c) => c -> Java c a -> Java b a withObject :: (Class c) => c -> Java c a -> Java b a

  • - Chain Java actions.

(>-) :: (Class b) => Java a b -> Java b c -> Java a c

slide-82
SLIDE 82

FOREIGN EXPORT FOREIGN EXPORT

foreign export java "@static eta.example.MyExportedClass.sort" sort :: JIntArray -> JIntArray

slide-83
SLIDE 83

STYLES OF STYLES OF INTEROPERATIBILIY INTEROPERATIBILIY

slide-84
SLIDE 84

FULL HASKELL WAY FULL HASKELL WAY

Example: WAI Servlet

appAll :: FilePath -> Application appAll filePath req respond = case pathInfo req of ["state"] -> appState (unsafePerformIO $ newMVar 0) r ["stream"] -> appStream req respond ["request-info"] -> appShowReq req respond ["static-file"] -> appFile filePath req respond _ -> appSimple req respond

slide-85
SLIDE 85

CLASSES IN JAVA LOGIC IN CLASSES IN JAVA LOGIC IN HASKELL HASKELL

Types defined in java Haskell functions wok on Java objects Support and use of Java frameworks, serializations, db bindings, jsons.

slide-86
SLIDE 86

Hint: in 2018a most of java frameworks do not need classical/ ugly JavaBeans anymore.

slide-87
SLIDE 87
slide-88
SLIDE 88

@JsonDeserialize public class Ball extends GameObject { private static final long serialVersionUID = 1L; public final Vector2D speed; @JsonCreator public Ball(float x, float y, Vector2D speed) { super(x, y); this.speed = speed; }

slide-89
SLIDE 89

@JsonDeserialize public class GameState implements Serializable { private static final long serialVersionUID = 1L; public final GamePhase phase; public final Ball ball; public final Players players; public final long updateTime; @JsonCreator public GameState( final Ball ball, final Players players, final long updateTime) { this.ball = ball; this.players = players;

slide-90
SLIDE 90

foreign import java unsafe "@new" newGameState :: Ball.Ball - foreign import java unsafe "@field phase" phase :: GameState - foreign import java unsafe "@field ball" ball :: GameState -> foreign import java unsafe "@field players" players :: GameSta foreign import java unsafe "@field updateTime" updateTime :: G push::GameState->Int64->J.Random->IO GameState push state time rnd | (aPhase == GamePhase.started ) = pushStarted state | otherwise = return state where aPhase = phase state

slide-91
SLIDE 91

Linguistic determinism

slide-92
SLIDE 92

from http://postcogtopics.blogspot.com/2016/

slide-93
SLIDE 93

//A piece of smart code in Players should reduce both meth private Tuple2<Ball, Players> bouncePlayer1(final Players if (this.x < 0 && speed.x < 0) { if (isTouchingPaddle(players.player1.paddle, this. return Tuple.of(new Ball(0f, this.y, this.spee } else { return Tuple.of(Ball.randomDirection(rnd), pla } } return Tuple.of(this, players); } private Tuple2<Ball, Players> bouncePlayer2(final Players if (this.x > 1.0f && speed.x > 0) { if (isTouchingPaddle(players.player2.paddle, this.

slide-94
SLIDE 94

bouncePlayerInternal::Ball->Players.Players->J.Random->(Lens' bouncePlayerInternal ball players rnd lens opLens xposition | (isTouchingPaddle paddle thisY) = return (newBall xpos | otherwise = do randomBall <- randomDirection rnd return ( randomBall, set opLens opponentScored playe where thisX = xObj ball thisY = yObj ball thisSpeed = speed ball speedX = Vector2D.x thisSpeed playerView = view lens players

  • pponentScored = Player.incScore $ view opLens players

paddle = Player.paddle playerView

slide-95
SLIDE 95

HAVA HAVA

ballBounceP :: Ball.Ball -> Players.Players -> J.Random -> IO Players.Players

slide-96
SLIDE 96
slide-97
SLIDE 97

POINTER REF POINTER REF WAY WAY

slide-98
SLIDE 98

Data in haskell, businell logic in haskell. Java as Controller.

slide-99
SLIDE 99

We need to expose haskell objects to java.

slide-100
SLIDE 100

Game of life

data Color = Color {red :: Int, g b data Cell = Dead | Alive {color :: Color} type Row = Array Int Cell type Plane = Array Int Row type GOLState = StablePtr Plane initEmptyXP:: Int -> Int -> IO GOLState initEmptyXP wi hi = newStablePtr $ makePlane wi hi newStateXP::GOLState -> IO GOLState public static int newState(int var0) { return ((StablePtr)Runtime.evalIO(new Ap2Upd(TopHandle }

slide-101
SLIDE 101

PROBLEMS PROBLEMS

lot of imports to write for every simple java class this will be fixed thanks to ffi tool it took me a while to find out how to pass state between haskell and java

  • ther bug found (and resolved)

java monad / io monad - not totally intuitive (for a newbie)

slide-102
SLIDE 102

ETA VS FREGE ETA VS FREGE

slide-103
SLIDE 103

I used Frege very shortly. Frege is more mature Interoperation with Java is easier with Frege Frege will not be close to GHC in the near future at the semantics level at the base libraries level

slide-104
SLIDE 104

ETA FOR YOU ETA FOR YOU

slide-105
SLIDE 105

ETA NOW ETA NOW

slide-106
SLIDE 106

Eta is 0.7.0b2 is not production quality yet

slide-107
SLIDE 107

If You think of eta in production soon -> talk to Typelead. They want to provide commercial support - ask them for conditions.

slide-108
SLIDE 108

If you are haskell developer that wants to evaluate haskell on JVM Try it now!

slide-109
SLIDE 109

If you are JVM / JavaDeveloper that wants to learn and play with Haskell Play now!

slide-110
SLIDE 110

ETA COMMUNITY ETA COMMUNITY

slide-111
SLIDE 111

Small.

slide-112
SLIDE 112

Great!

slide-113
SLIDE 113

You can help! There are lot of small things to do.

slide-114
SLIDE 114

Future of eta lies in your hands