Top Banner
Manuel M T Chakravarty University of New South Wales Foreign Inline Code in Haskell mchakravarty α TacticalGrace TacticalGrace justtesting.org 1 30 minute time slot: 25min talking + 5min [15min The Problem; 5min TH+Quasiquoting; 5min Inline Objective-C]
95

Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Mar 18, 2019

Download

Documents

phungkhanh
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Manuel M T ChakravartyUniversity of New South Wales

Foreign Inline Code in Haskell

mchakravarty

α TacticalGraceTacticalGracejusttesting.org

1

30 minute time slot: 25min talking + 5min[15min The Problem; 5min TH+Quasiquoting; 5min Inline Objective-C]

Page 2: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

λShiny new functional language

2

» Imagine, you have got a shiny, new functional language...

Page 3: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

3

» ...and you want to use it to write a great new app...

Page 4: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

λ4

» ...then you will need to use many existing frameworks and libraries.» Luckily, any serious language will have a foreign function interface!» Haskell standard includes a simple, but versatile FFI

Page 5: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

“Problem solved?”

5

» Does that solve the problem of language interoperability?» Let me explain that at an example...

Page 6: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

“Problem solved?”No!

5

» Does that solve the problem of language interoperability?» Let me explain that at an example...

Page 7: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

dumpURL :: String -> IO () dumpURL urlString = do urlData <- stringWithContentsOfUrl urlString putStr urlData

What we want to write

6

Page 8: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

dumpURL :: String -> IO () dumpURL urlString = do urlData <- stringWithContentsOfUrl urlString putStr urlData

What we want to write

char *stringWithContentsOfUrlCstub(char *urlString) { NSURL *url = [NSURL URLWithString:urlString]; [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:NULL]; }

What we want to call (& need to put into an extra file)

6

Page 9: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

What we have to write as well…

foreign import stringWithContentsOfURLCstub :: CString -> IO CString

stringWithContentsOfURL :: String -> IO String stringWithContentsOfURL url = withCString url $ \urlC -> do resultC <- stringWithContentsOfURLCstub urlC result <- peek resultC free resultC return result

7

» FFI code: If you find it confusing, that’s fine, as I want to argue that you shouldn’t write it in the first place.* Anything extensively relying on foreign frameworks will be a pain[Hybrid languages (eg, F# & Scala) have a different set of trade offs, but don’t solve it either.]

Page 10: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Bridging Libraries 1-to-1 transliteration of types & functions

8

* Bridging or binding libraries transliterate types & functions* Need to be maintained and documented; track multiple versions of base library* Lack of type safety* Tools and dynamic transliteration (by reflection) help

Page 11: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

C➙Haskellc2hs

A case study

GTK+

9

* c2hs: automation for bridging C libraries to Haskell <https://hackage.haskell.org/package/c2hs>

* Implements large parts of a C compiler front-end* Bridge for the cross-platform Gnome GUI library GTK+ <http://projects.haskell.org/

gtk2hs/>

Page 12: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

10

* AFAIK, currently the only fully featured and properly maintained Haskell GUI library* Haskell GTK+ library is used for realistic applications

Page 13: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

“Does this approach scale?”

11

» Read question* It requires significant resources & constant effort to track the original library* Application frameworks: enormous and growing footprint

Page 14: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

February 2011Introduction of GTK+ 3

12

* Base GTK+ development isn’t even particularly fast* Bridging libraries lag behind their base libraries* Another example: Haskell OpenGL library

Page 15: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

February 2011Introduction of GTK+ 3

December 2013GTK+ 3 in Haskell Bridge

12

* Base GTK+ development isn’t even particularly fast* Bridging libraries lag behind their base libraries* Another example: Haskell OpenGL library

Page 16: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

13

* Compared to modern application frameworks, GTK+ is small!

Page 17: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Bridging libraries don’t scale Too much weight!

14

Page 18: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

“Interoperability is an old problem — maybe an old

solution can help?”

15

Page 19: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

16

* Modula-2 with inline 68000 assembly* Assembly code can symbolically refer to Modula-2 entities (e.g., variables)

Page 20: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

16

* Modula-2 with inline 68000 assembly* Assembly code can symbolically refer to Modula-2 entities (e.g., variables)

Page 21: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

16

* Modula-2 with inline 68000 assembly* Assembly code can symbolically refer to Modula-2 entities (e.g., variables)

Page 22: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

“Inline C, C++, Objective-C, … in Haskell?”

17

* We don’t want to build front ends for a few more languages into GHC* How do we share entities between the languages?

Page 23: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Meta-programmingTemplate Haskell

18

» Generic infrastructure for program manipulationNOTE: I'll run through this quickly; I'll explain the details at the workshop.

Page 24: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

HASKELL WORKSHOP 2002

19

* Template Haskell: Haskell extension implemented by GHC* Useful for: defining macros, code generators, code transformations…* Other languages have their own variants; eg., MetaOCaml» Let’s look at an example…

Page 25: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

HASKELL WORKSHOP 2002

#define

macros

19

* Template Haskell: Haskell extension implemented by GHC* Useful for: defining macros, code generators, code transformations…* Other languages have their own variants; eg., MetaOCaml» Let’s look at an example…

Page 26: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

HASKELL WORKSHOP 2002

#define

macros

[| … |]code

generators19

* Template Haskell: Haskell extension implemented by GHC* Useful for: defining macros, code generators, code transformations…* Other languages have their own variants; eg., MetaOCaml» Let’s look at an example…

Page 27: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

HASKELL WORKSHOP 2002

#define

macros

[| … |]code

generators

trafo (ConE name) = …code

transformations19

* Template Haskell: Haskell extension implemented by GHC* Useful for: defining macros, code generators, code transformations…* Other languages have their own variants; eg., MetaOCaml» Let’s look at an example…

Page 28: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

$(sel 1 3) (a, b, c) = a

20

* Meta function executed at splice point, generating spliced code

Page 29: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

$(sel 1 3) (a, b, c) = a

meta-programming function

20

* Meta function executed at splice point, generating spliced code

Page 30: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

$(sel 1 3) (a, b, c) = a

meta-programming function

splice

20

* Meta function executed at splice point, generating spliced code

Page 31: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

$(sel 1 3) (a, b, c) = a

meta-programming function

splice \tup -> case tup of {(x, y, z) -> x} :: (a, b, c) -> a

20

* Meta function executed at splice point, generating spliced code

Page 32: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

$(sel 1 3) (a, b, c) = a

meta-programming function

splice \tup -> case tup of {(x, y, z) -> x} :: (a, b, c) -> a

$(sel 5 5) (a, b, c, d, e) = e

20

* Meta function executed at splice point, generating spliced code

Page 33: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

$(sel 1 3) (a, b, c) = a

meta-programming function

splice \tup -> case tup of {(x, y, z) -> x} :: (a, b, c) -> a

$(sel 5 5) (a, b, c, d, e) = e

\tup -> case tup of {(x, y, z, v, w) -> w} :: (a, b, c, d, e) -> e

20

* Meta function executed at splice point, generating spliced code

Page 34: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

sel :: Int -> Int -> ExpQ sel i n = [| \tup -> case tup of {$pat -> $res} |] where pat = tupP (map varP names) res = varE (names !! (i - 1)) names = [mkName $ "v" ++ show i | i <- [1..n]]

21

* Quasiquotations in [|..|] brackets* Explain TH in more detail in the workshop

Page 35: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

sel :: Int -> Int -> ExpQ sel i n = [| \tup -> case tup of {$pat -> $res} |] where pat = tupP (map varP names) res = varE (names !! (i - 1)) names = [mkName $ "v" ++ show i | i <- [1..n]]

type of Haskell expressions

21

* Quasiquotations in [|..|] brackets* Explain TH in more detail in the workshop

Page 36: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

sel :: Int -> Int -> ExpQ sel i n = [| \tup -> case tup of {$pat -> $res} |] where pat = tupP (map varP names) res = varE (names !! (i - 1)) names = [mkName $ "v" ++ show i | i <- [1..n]]

type of Haskell expressions quasi-quotation

21

* Quasiquotations in [|..|] brackets* Explain TH in more detail in the workshop

Page 37: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

sel :: Int -> Int -> ExpQ sel i n = [| \tup -> case tup of {$pat -> $res} |] where pat = tupP (map varP names) res = varE (names !! (i - 1)) names = [mkName $ "v" ++ show i | i <- [1..n]]

type of Haskell expressions quasi-quotation

spliced expression(anti quote)

21

* Quasiquotations in [|..|] brackets* Explain TH in more detail in the workshop

Page 38: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Processing other languagesGeneric quasi-quotation

22

* Quoting arbitrary languages

Page 39: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

HASKELL WORKSHOP 2007

Quasiquoting for any language you can provide a parser for

23

Page 40: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Language.C.Quote

add n = [cfun| int addConstant(int x) { return x + $int:n; } |]

24

* QQ for C including some GNU extensions, parts of CUDA & OpenCL, and all of Objective-C

Page 41: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Language.C.Quote

add n = [cfun| int addConstant(int x) { return x + $int:n; } |]

quasi-quotation identifier

24

* QQ for C including some GNU extensions, parts of CUDA & OpenCL, and all of Objective-C

Page 42: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Language.C.Quote

add n = [cfun| int addConstant(int x) { return x + $int:n; } |]

quasi-quotation identifier

splice identifier

24

* QQ for C including some GNU extensions, parts of CUDA & OpenCL, and all of Objective-C

Page 43: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

mkMap dev aenv fun arr = return $ CUTranslSkel "map" [cunit|

$esc:("#include <accelerate_cuda.h>") extern "C" __global__ void map ($params:argIn, $params:argOut) { const int shapeSize = size(shOut); const int gridSize = $exp:(gridSize dev); int ix;

for ( ix = $exp:(threadIdx dev) ; ix < shapeSize ; ix += gridSize ) { $items:(dce x .=. get ix) $items:(setOut "ix" .=. f x) } } |] where ...

25

* Accelerate: embedded high-performance array language for GPUs* Combinators as code skeletons (code templates with holes)* Yellow splices/anti-quotes are the holes (parameters) of the template* Doing this with strings or explicit AST construction would be much worse

Page 44: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

mkMap dev aenv fun arr = return $ CUTranslSkel "map" [cunit|

$esc:("#include <accelerate_cuda.h>") extern "C" __global__ void map ($params:argIn, $params:argOut) { const int shapeSize = size(shOut); const int gridSize = $exp:(gridSize dev); int ix;

for ( ix = $exp:(threadIdx dev) ; ix < shapeSize ; ix += gridSize ) { $items:(dce x .=. get ix) $items:(setOut "ix" .=. f x) } } |] where ...

25

* Accelerate: embedded high-performance array language for GPUs* Combinators as code skeletons (code templates with holes)* Yellow splices/anti-quotes are the holes (parameters) of the template* Doing this with strings or explicit AST construction would be much worse

Page 45: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

mkMap dev aenv fun arr = return $ CUTranslSkel "map" [cunit|

$esc:("#include <accelerate_cuda.h>") extern "C" __global__ void map ($params:argIn, $params:argOut) { const int shapeSize = size(shOut); const int gridSize = $exp:(gridSize dev); int ix;

for ( ix = $exp:(threadIdx dev) ; ix < shapeSize ; ix += gridSize ) { $items:(dce x .=. get ix) $items:(setOut "ix" .=. f x) } } |] where ...

25

* Accelerate: embedded high-performance array language for GPUs* Combinators as code skeletons (code templates with holes)* Yellow splices/anti-quotes are the holes (parameters) of the template* Doing this with strings or explicit AST construction would be much worse

Page 46: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Inlining foreign languagesInline C Code

26

Page 47: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Language.C.Inline

dumpURL :: String -> IO () dumpURL urlString = do urlData <-

putStr urlData

stringWithContentsOfUrl urlString

27

* Inline Objective-C* All the FFI code is generated automatically* Again, details in the workshop

Page 48: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Language.C.Inline

dumpURL :: String -> IO () dumpURL urlString = do urlData <-

putStr urlData

$(objc ['urlString] ''String [cexp| [NSString stringWithContentsOfURL: [NSURL URLWithString:urlString] encoding:NSUTF8StringEncoding error:NULL] |])

inline Objective-C splice

27

* Inline Objective-C* All the FFI code is generated automatically* Again, details in the workshop

Page 49: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Inline C…is simple

28

* Lack of bridge saves a lot of work; instant access to new versions* Bridges require familiarity with native libraries already; inline code leverages that directly* Haskell types are automatically mapped to types of the inline language

Page 50: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Inline C…is simple

No bridging library needs to be maintained

28

* Lack of bridge saves a lot of work; instant access to new versions* Bridges require familiarity with native libraries already; inline code leverages that directly* Haskell types are automatically mapped to types of the inline language

Page 51: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Inline C…is simple

No extra documentation

No bridging library needs to be maintained

28

* Lack of bridge saves a lot of work; instant access to new versions* Bridges require familiarity with native libraries already; inline code leverages that directly* Haskell types are automatically mapped to types of the inline language

Page 52: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Inline C…is simple

No extra documentation

Some type safety

No bridging library needs to be maintained

28

* Lack of bridge saves a lot of work; instant access to new versions* Bridges require familiarity with native libraries already; inline code leverages that directly* Haskell types are automatically mapped to types of the inline language

Page 53: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Language integration bylanguage inlining

types >< state languages

29

Outline workshop* Get familiar with TH and Language.C.Quote* Run through three exercises using inline Objective-C including a graphical REPL

Page 54: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Workshop Part 1Template Haskell

30

* http://www.haskell.org/haskellwiki/Template_Haskell* http://hackage.haskell.org/package/template-haskell

Page 55: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Clone https://github.com/mchakravarty/ylj14-workshop

31

Page 56: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

32

Page 57: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

32

Page 58: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

32

Page 59: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

33

Page 60: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

printf :: String -> ExpQ printf fmt = gen (parse fmt)

33

Page 61: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

printf :: String -> ExpQ printf fmt = gen (parse fmt)

data Format = D | S | L String parse :: String -> [Format]

33

Page 62: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

printf :: String -> ExpQ printf fmt = gen (parse fmt)

data Format = D | S | L String parse :: String -> [Format]

gen :: [Format] -> ExpQ gen [D] = [| \n -> show n |] gen [S] = [| \s -> s |] gen [L s] = [| s |]

33

Page 63: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Task ❶

A recursive generator

34

Page 64: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

printf/

35

Page 65: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

printf :: String -> ExpQ printf fmt = gen (parse fmt) [| "" |]

printf/

35

Page 66: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

printf :: String -> ExpQ printf fmt = gen (parse fmt) [| "" |]

gen :: [Format] -> ExpQ -> ExpQ

printf/

35

Page 67: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

printf :: String -> ExpQ printf fmt = gen (parse fmt) [| "" |]

gen :: [Format] -> ExpQ -> ExpQ gen [] prefix = prefix

printf/

35

Page 68: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

printf :: String -> ExpQ printf fmt = gen (parse fmt) [| "" |]

gen :: [Format] -> ExpQ -> ExpQ gen [] prefix = prefix gen (D : fmt) prefix

printf/

35

Page 69: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

printf :: String -> ExpQ printf fmt = gen (parse fmt) [| "" |]

gen :: [Format] -> ExpQ -> ExpQ gen [] prefix = prefix gen (D : fmt) prefix = [| \n -> $(gen fmt [| $prefix ++ show n |]) |]

printf/

35

Page 70: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

printf :: String -> ExpQ printf fmt = gen (parse fmt) [| "" |]

gen :: [Format] -> ExpQ -> ExpQ gen [] prefix = prefix gen (D : fmt) prefix = [| \n -> $(gen fmt [| $prefix ++ show n |]) |] gen (S : fmt) prefix

printf/

35

Page 71: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

printf :: String -> ExpQ printf fmt = gen (parse fmt) [| "" |]

gen :: [Format] -> ExpQ -> ExpQ gen [] prefix = prefix gen (D : fmt) prefix = [| \n -> $(gen fmt [| $prefix ++ show n |]) |] gen (S : fmt) prefix = [| \s -> $(gen fmt [| $prefix ++ s |]) |]

printf/

35

Page 72: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

printf :: String -> ExpQ printf fmt = gen (parse fmt) [| "" |]

gen :: [Format] -> ExpQ -> ExpQ gen [] prefix = prefix gen (D : fmt) prefix = [| \n -> $(gen fmt [| $prefix ++ show n |]) |] gen (S : fmt) prefix = [| \s -> $(gen fmt [| $prefix ++ s |]) |] gen (L s : fmt) prefix

printf/

35

Page 73: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

printf :: String -> ExpQ printf fmt = gen (parse fmt) [| "" |]

gen :: [Format] -> ExpQ -> ExpQ gen [] prefix = prefix gen (D : fmt) prefix = [| \n -> $(gen fmt [| $prefix ++ show n |]) |] gen (S : fmt) prefix = [| \s -> $(gen fmt [| $prefix ++ s |]) |] gen (L s : fmt) prefix = gen fmt [| $prefix ++ s |]

printf/

35

Page 74: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Workshop Part 2Quasi-quotation of C variants

36

* http://hackage.haskell.org/package/language-c-quote

Page 75: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

gensum/

37

Page 76: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

genSum :: Name -> Int -> BlockItem genSum arr n = [citem| { int sum = 0; for (int i = 0; i++; i < $n) sum += $id:(show arr)[i]; } |]

gensum/

37

Page 77: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

genSum :: Name -> Int -> BlockItem genSum arr n = [citem| { int sum = 0; for (int i = 0; i++; i < $n) sum += $id:(show arr)[i]; } |]

custom parser for C block items

gensum/

37

Page 78: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

genSum :: Name -> Int -> BlockItem genSum arr n = [citem| { int sum = 0; for (int i = 0; i++; i < $n) sum += $id:(show arr)[i]; } |]

custom parser for C block items

splicing of a name as an identifier

gensum/

37

Page 79: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

genSum :: Name -> Int -> BlockItem genSum arr n = [citem| { int sum = 0; for (int i = 0; i++; i < $n) sum += $id:(show arr)[i]; } |]

custom parser for C block items

splicing of a name as an identifier

default is to spliceas an expression

gensum/

37

Page 80: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Task ❷

Loop unrolling

38

Page 81: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Replace the for loop by a statement sequence

[cstms| … |] quote a statement sequence$stms:… splice a statement sequence

39

Page 82: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

genSum arr n = [citem| { int sum = 0; $stms:(additions 0) } |] where additions i | i == n = [] | otherwise = [cstms| sum += $id:(show arr)[ $int:i ]; $stms:(additions (i + 1)) |]

Replace the for loop by a statement sequence

[cstms| … |] quote a statement sequence$stms:… splice a statement sequence

39

Page 83: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Workshop Part 3Inline Objective-C Code

40

* http://hackage.haskell.org/package/language-c-inline

Page 84: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

{-# LANGUAGE TemplateHaskell, QuasiQuotes #-}

import Language.C.Quote.ObjC import Language.C.Inline.ObjC

objc_import ["<Foundation/Foundation.h>"]

nslog :: String -> IO () nslog msg = $(objc ['msg] ''() [cexp| NSLog(@"Here is a message from Haskell: %@”,! ! ! ! ! ! msg) |])

objc_emit

minimal/

41

* Complete the skeleton in the exercise pack

Page 85: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

{-# LANGUAGE TemplateHaskell, QuasiQuotes #-}

import Language.C.Quote.ObjC import Language.C.Inline.ObjC

objc_import ["<Foundation/Foundation.h>"]

nslog :: String -> IO () nslog msg = $(objc ['msg] ''() [cexp| NSLog(@"Here is a message from Haskell: %@”,! ! ! ! ! ! msg) |])

objc_emit

imports for the generatedObjective-C code

minimal/

41

* Complete the skeleton in the exercise pack

Page 86: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

{-# LANGUAGE TemplateHaskell, QuasiQuotes #-}

import Language.C.Quote.ObjC import Language.C.Inline.ObjC

objc_import ["<Foundation/Foundation.h>"]

nslog :: String -> IO () nslog msg = $(objc ['msg] ''() [cexp| NSLog(@"Here is a message from Haskell: %@”,! ! ! ! ! ! msg) |])

objc_emit

free variables

imports for the generatedObjective-C code

minimal/

41

* Complete the skeleton in the exercise pack

Page 87: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

{-# LANGUAGE TemplateHaskell, QuasiQuotes #-}

import Language.C.Quote.ObjC import Language.C.Inline.ObjC

objc_import ["<Foundation/Foundation.h>"]

nslog :: String -> IO () nslog msg = $(objc ['msg] ''() [cexp| NSLog(@"Here is a message from Haskell: %@”,! ! ! ! ! ! msg) |])

objc_emit

free variables

imports for the generatedObjective-C code

finalise inline code

minimal/

41

* Complete the skeleton in the exercise pack

Page 88: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Task ❸

Bridging classes

42

Page 89: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

particle/

Particle.hs Represent Haskell record as ObjC classMain.hs Allocate instance and use it

43

Page 90: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

particle/

Particle.hs Represent Haskell record as ObjC classMain.hs Allocate instance and use it

Complete the ObjC class implementation

43

Page 91: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Task ❹

A simple application

44

Page 92: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

app/

Interpreter.hs Haskell interface to package ghcAppDelegate.hs Haskell-Objective-C bridge

45

Page 93: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

app/

Interpreter.hs Haskell interface to package ghcAppDelegate.hs Haskell-Objective-C bridge

Complete AppDelegate.hs

Run with open -a HSApp.app

45

Page 94: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Thank you!

46

Page 95: Foreign Inline Code in Haskell - YOW! Conferences and ...yowconference.com.au/slides/yowlambdajam2014/Chakravarty-Foreign... · trafo (ConE name) = … code transformations 19 * Template

Images from

http://wikimedia.org

http://openclipart.org

GitHub repo

https://github.com/mchakravarty/language-c-inline

Megamax Modula-2 Screenshot by Dirk Steins