Foreign Inline Code in Haskell Manuel M T Chakravarty University of New South Wales mchakravarty α TacticalGrace TacticalGrace justtesting.org 1 30 minute time slot: 25min talking + 5min [15min The Problem; 5min TH+Quasiquoting; 5min Inline Objective-C]
Shiny new functional language λ 2 » Imagine, you have got a shiny, new functional language...
3 » ...and you want to use it to write a great new app...
λ 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
“Problem solved?” 5 » Does that solve the problem of language interoperability? » Let me explain that at an example...
! o N “Problem solved?” 5 » Does that solve the problem of language interoperability? » Let me explain that at an example...
What we want to write dumpURL :: String -> IO () dumpURL urlString = do urlData <- stringWithContentsOfUrl urlString putStr urlData 6
What we want to write dumpURL :: String -> IO () dumpURL urlString = do urlData <- stringWithContentsOfUrl urlString putStr urlData What we want to call (& need to put into an extra file) char *stringWithContentsOfUrlCstub(char *urlString) { NSURL *url = [NSURL URLWithString:urlString]; [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:NULL]; } 6
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 di fg erent set of trade o fg s, but don’t solve it either.]
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
A case study C ➙ Haskell c2hs 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/>
10 * AFAIK, currently the only fully featured and properly maintained Haskell GUI library * Haskell GTK+ library is used for realistic applications
“Does this approach scale?” 11 » Read question * It requires significant resources & constant e fg ort to track the original library * Application frameworks: enormous and growing footprint
February 2011 Introduction of GTK+ 3 12 * Base GTK+ development isn’t even particularly fast * Bridging libraries lag behind their base libraries * Another example: Haskell OpenGL library
February 2011 Introduction of GTK+ 3 December 2013 GTK+ 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
13 * Compared to modern application frameworks, GTK+ is small!
Bridging libraries Too much weight! don’t scale 14
“Interoperability is an old problem — maybe an old solution can help?” 15
16 * Modula-2 with inline 68000 assembly * Assembly code can symbolically refer to Modula-2 entities (e.g., variables)
16 * Modula-2 with inline 68000 assembly * Assembly code can symbolically refer to Modula-2 entities (e.g., variables)
16 * Modula-2 with inline 68000 assembly * Assembly code can symbolically refer to Modula-2 entities (e.g., variables)
“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?
Meta-programming Template Haskell 18 » Generic infrastructure for program manipulation NOTE: I'll run through this quickly; I'll explain the details at the workshop.
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…
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…
HASKELL WORKSHOP 2002 #define [| … |] code macros generators 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…
HASKELL WORKSHOP 2002 #define [| … |] trafo (ConE name) = … code code macros generators transformations 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…
$(sel 1 3) (a, b, c) = a 20 * Meta function executed at splice point, generating spliced code
meta-programming function $(sel 1 3) (a, b, c) = a 20 * Meta function executed at splice point, generating spliced code
meta-programming function $(sel 1 3) (a, b, c) = a splice 20 * Meta function executed at splice point, generating spliced code
meta-programming function $(sel 1 3) (a, b, c) = a splice \tup -> case tup of {(x, y, z) -> x} :: (a, b, c) -> a 20 * Meta function executed at splice point, generating spliced code
meta-programming function $(sel 1 3) (a, b, c) = a 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
meta-programming function $(sel 1 3) (a, b, c) = a 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
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
type of Haskell expressions 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
type of Haskell expressions quasi-quotation 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
type of Haskell expressions quasi-quotation 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]] spliced expression (anti quote) 21 * Quasiquotations in [|..|] brackets * Explain TH in more detail in the workshop
Processing other languages Generic quasi-quotation 22 * Quoting arbitrary languages
HASKELL WORKSHOP 2007 Quasiquoting for any language you can provide a parser for 23
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
Language.C.Quote quasi-quotation identifier 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
Language.C.Quote quasi-quotation identifier add n = [cfun| int addConstant(int x) { return x + $int:n; } |] splice identifier 24 * QQ for C including some GNU extensions, parts of CUDA & OpenCL, and all of Objective-C
Recommend
More recommend