
I have an application written in OCaml that I'm interested in porting over to Haskell, and I was wondering what the best way to replace the following OCaml function would be: Toploop.initialize_toplevel_env();; let eval txt = let lb = (Lexing.from_string txt) in let phr = !Toploop.parse_toplevel_phrase lb in Toploop.execute_phrase true Format.std_formatter phr;; eval "let add1 x = x +1;;";; eval "add1 2;;";; Where I would like to be able to "eval" Haskell-code instead. It looks like I might be able to achieve something like this using hs-plugins, but it looks a bit more complex. Is hs-plugins the best choice for this kind of "meta"-programming? I'm pretty sure Template Haskell will not work for me, at least as I understand it I can only manipulate program fragments that will be compiled later and as such that it will not be possible to execute them until the next "phase".

geoffw:
I have an application written in OCaml that I'm interested in porting over to Haskell, and I was wondering what the best way to replace the following OCaml function would be:
Toploop.initialize_toplevel_env();;
let eval txt = let lb = (Lexing.from_string txt) in let phr = !Toploop.parse_toplevel_phrase lb in Toploop.execute_phrase true Format.std_formatter phr;;
eval "let add1 x = x +1;;";; eval "add1 2;;";;
Where I would like to be able to "eval" Haskell-code instead. It looks like I might be able to achieve something like this using hs-plugins, but it looks a bit more complex. Is hs-plugins the best choice for this kind of "meta"-programming? I'm pretty sure Template Haskell will not work for me, at least as I understand it I can only manipulate program fragments that will be compiled later and as such that it will not be possible to execute them until the next "phase".
You can do some forms of runtime metaprogrammign with hs-plugins, yes. E.g. Prelude System.Eval.Haskell> v <- eval "1 + 2 :: Int" [] :: IO (Maybe Int) Prelude System.Eval.Haskell> v Just 3 Prelude System.Eval.Haskell> mf <- eval "\\x -> x + 1 :: Int" [] :: IO (Maybe (Int -> Int)) Prelude System.Eval.Haskell> let f = fromJust mf Prelude System.Eval.Haskell> :t f f :: Int -> Int Prelude System.Eval.Haskell> f 7 8 So if your program critically relies on this its possible to do. -- Don

On 5/4/06, Donald Bruce Stewart
geoffw:
I have an application written in OCaml that I'm interested in porting over to Haskell, and I was wondering what the best way to replace the following OCaml function would be:
Toploop.initialize_toplevel_env();;
let eval txt = let lb = (Lexing.from_string txt) in let phr = !Toploop.parse_toplevel_phrase lb in Toploop.execute_phrase true Format.std_formatter phr;;
eval "let add1 x = x +1;;";; eval "add1 2;;";;
Where I would like to be able to "eval" Haskell-code instead. It looks like I might be able to achieve something like this using hs-plugins, but it looks a bit more complex. Is hs-plugins the best choice for this kind of "meta"-programming? I'm pretty sure Template Haskell will not work for me, at least as I understand it I can only manipulate program fragments that will be compiled later and as such that it will not be possible to execute them until the next "phase".
You can do some forms of runtime metaprogrammign with hs-plugins, yes. E.g.
Prelude System.Eval.Haskell> v <- eval "1 + 2 :: Int" [] :: IO (Maybe Int) Prelude System.Eval.Haskell> v Just 3
Prelude System.Eval.Haskell> mf <- eval "\\x -> x + 1 :: Int" [] :: IO (Maybe (Int -> Int)) Prelude System.Eval.Haskell> let f = fromJust mf Prelude System.Eval.Haskell> :t f f :: Int -> Int Prelude System.Eval.Haskell> f 7 8
So if your program critically relies on this its possible to do.
You can also use the GHC library: Prelude> :m GHC Prelude GHC> GHC.init (Just "/home/david/coding/haskell/ghc/usr/lib/ghc-6.5") Prelude GHC> session <- newSession Interactive Prelude GHC> setSessionDynFlags session =<< initPackages =<< getSessionDynFlags session Prelude GHC> setContext session [] [mkModule "Prelude"] Prelude GHC> runStmt session "let add1 x = x + 1" Prelude GHC> runStmt session "add1 2" 3 Prelude GHC> :q Leaving GHCi. -- Friendly, Lemmih

lemmih:
On 5/4/06, Donald Bruce Stewart
wrote: geoffw:
I have an application written in OCaml that I'm interested in porting over to Haskell, and I was wondering what the best way to
replace
the following OCaml function would be:
Toploop.initialize_toplevel_env();;
let eval txt = let lb = (Lexing.from_string txt) in let phr = !Toploop.parse_toplevel_phrase lb in Toploop.execute_phrase true Format.std_formatter phr;;
eval "let add1 x = x +1;;";; eval "add1 2;;";;
Where I would like to be able to "eval" Haskell-code instead. It looks like I might be able to achieve something like this using hs-plugins, but it looks a bit more complex. Is hs-plugins the best choice for this kind of "meta"-programming? I'm pretty sure Template Haskell will not work for me, at least as I understand it I can only manipulate program fragments that will be compiled later and as such that it will not be possible to execute them until the next "phase".
You can do some forms of runtime metaprogrammign with hs-plugins, yes. E.g.
Prelude System.Eval.Haskell> v <- eval "1 + 2 :: Int" [] :: IO (Maybe Int) Prelude System.Eval.Haskell> v Just 3
Prelude System.Eval.Haskell> mf <- eval "\\x -> x + 1 :: Int" [] :: IO (Maybe (Int -> Int)) Prelude System.Eval.Haskell> let f = fromJust mf Prelude System.Eval.Haskell> :t f f :: Int -> Int Prelude System.Eval.Haskell> f 7 8
So if your program critically relies on this its possible to do.
You can also use the GHC library: Prelude> :m GHC Prelude GHC> GHC.init (Just "/home/david/coding/haskell/ghc/usr/lib/ghc-6.5") Prelude GHC> session <- newSession Interactive Prelude GHC> setSessionDynFlags session =<< initPackages =<< getSessionDynFlags session Prelude GHC> setContext session [] [mkModule "Prelude"] Prelude GHC> runStmt session "let add1 x = x + 1" Prelude GHC> runStmt session "add1 2" 3 Prelude GHC> :q Leaving GHCi.
It strikes me that we should be aiming for an interface like something approaching the various ML top levels, with ghc-api. That is, we shouldn't need to deal with setting up package contexts and so on. /me ponders an api ... Something like: > GHC.Top.init > f <- run "let add1 x = x + 1" > f 7 8 Lemmih, any ideas on whether it would be possible to simplify and abstract over some of the details ? Do we need a SoC project... :) -- Don

| /me ponders an api ... | | Something like: | | > GHC.Top.init | > f <- run "let add1 x = x + 1" | > f 7 | 8 GHC's api has a clear notion of a "session" that I believe we should not lose. So it'd be > s <- GHC.Top.init > f <- run s "\x -> x+1" > f 7 Here s is the session handle. Modulo that, I think it'd just be a question of setting up suitable defaults to get this API Simon

Hi,
On 5/4/06, Lemmih
You can also use the GHC library: Prelude> :m GHC Prelude GHC> GHC.init (Just "/home/david/coding/haskell/ghc/usr/lib/ghc-6.5") Prelude GHC> session <- newSession Interactive Prelude GHC> setSessionDynFlags session =<< initPackages =<< getSessionDynFlags session Prelude GHC> setContext session [] [mkModule "Prelude"] Prelude GHC> runStmt session "let add1 x = x + 1" Prelude GHC> runStmt session "add1 2" 3 Prelude GHC> :q Leaving GHCi.
Please tell what options do you use to build ghc in to get package ghc working? I get the following trying to load it: $ ./ghc-inplace --interactive -package ghc ___ ___ _ / _ \ /\ /\/ __(_) / /_\// /_/ / / | | GHC Interactive, version 6.5, for Haskell 98. / /_\\/ __ / /___| | http://www.haskell.org/ghc/ \____/\/ /_/\____/|_| Type :? for help. Loading package base-1.0 ... linking ... done. Loading package template-haskell-1.0 ... linking ... done. Loading package readline-1.0 ... linking ... done. Loading package unix-1.0 ... linking ... done. Loading package Cabal-1.1.4 ... linking ... done. Loading package haskell98-1.0 ... linking ... done. Loading package ghc-6.5 ... ghc-6.5: can't load .so/.DLL for: HSghc (libHSghc.so: cannot open shared object file: No such file or directory) Regards, V.Rudenko -- λ is the ultimate

On 5/4/06, wld
Hi,
On 5/4/06, Lemmih
wrote: You can also use the GHC library: Prelude> :m GHC Prelude GHC> GHC.init (Just "/home/david/coding/haskell/ghc/usr/lib/ghc-6.5") Prelude GHC> session <- newSession Interactive Prelude GHC> setSessionDynFlags session =<< initPackages =<< getSessionDynFlags session Prelude GHC> setContext session [] [mkModule "Prelude"] Prelude GHC> runStmt session "let add1 x = x + 1" Prelude GHC> runStmt session "add1 2" 3 Prelude GHC> :q Leaving GHCi.
Please tell what options do you use to build ghc in to get package ghc working? I get the following trying to load it:
$ ./ghc-inplace --interactive -package ghc ___ ___ _ / _ \ /\ /\/ __(_) / /_\// /_/ / / | | GHC Interactive, version 6.5, for Haskell 98. / /_\\/ __ / /___| | http://www.haskell.org/ghc/ \____/\/ /_/\____/|_| Type :? for help.
Loading package base-1.0 ... linking ... done. Loading package template-haskell-1.0 ... linking ... done. Loading package readline-1.0 ... linking ... done. Loading package unix-1.0 ... linking ... done. Loading package Cabal-1.1.4 ... linking ... done. Loading package haskell98-1.0 ... linking ... done. Loading package ghc-6.5 ... ghc-6.5: can't load .so/.DLL for: HSghc (libHSghc.so: cannot open shared object file: No such file or directory)
Nothing, my patches for loading 'ghc' in ghci have resided in the main repository for a couple of months. -- Friendly, Lemmih

Hello Lemmih, Thursday, May 4, 2006, 6:32:17 AM, you wrote:
Nothing, my patches for loading 'ghc' in ghci have resided in the main repository for a couple of months.
afaik, Lemmih just uses HEAD (6.5), i.e. beta version of ghc, which is only version that includes this lib -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Lemmih wrote:
On 5/4/06, Donald Bruce Stewart
wrote: geoffw:
I have an application written in OCaml that I'm interested in porting over to Haskell, and I was wondering what the best way
the following OCaml function would be:
Toploop.initialize_toplevel_env();;
let eval txt = let lb = (Lexing.from_string txt) in let phr = !Toploop.parse_toplevel_phrase lb in Toploop.execute_phrase true Format.std_formatter phr;;
eval "let add1 x = x +1;;";; eval "add1 2;;";;
Where I would like to be able to "eval" Haskell-code instead. It looks like I might be able to achieve something like this using hs-plugins, but it looks a bit more complex. Is hs-plugins the best choice for
to replace this
kind of "meta"-programming? I'm pretty sure Template Haskell will not work for me, at least as I understand it I can only manipulate program fragments that will be compiled later and as such that it will not be possible to execute them until the next "phase".
You can do some forms of runtime metaprogrammign with hs-plugins, yes. E.g.
Prelude System.Eval.Haskell> v <- eval "1 + 2 :: Int" [] :: IO (Maybe Int) Prelude System.Eval.Haskell> v Just 3
Prelude System.Eval.Haskell> mf <- eval "\\x -> x + 1 :: Int" [] :: IO (Maybe (Int -> Int)) Prelude System.Eval.Haskell> let f = fromJust mf Prelude System.Eval.Haskell> :t f f :: Int -> Int Prelude System.Eval.Haskell> f 7 8
So if your program critically relies on this its possible to do.
You can also use the GHC library: Prelude> :m GHC Prelude GHC> GHC.init (Just "/home/david/coding/haskell/ghc/usr/lib/ghc-6.5") Prelude GHC> session <- newSession Interactive Prelude GHC> setSessionDynFlags session =<< initPackages =<< getSessionDynFlags session Prelude GHC> setContext session [] [mkModule "Prelude"] Prelude GHC> runStmt session "let add1 x = x + 1" Prelude GHC> runStmt session "add1 2" 3 Prelude GHC> :q Leaving GHCi.
Nice example, I've added it to the wiki page: http://haskell.org/haskellwiki/GHC/As_a_library However, there's a caveat with doing this: the RTS linker only has a single symbol table, so the running GHCi will be sharing this symbol table with the new GHC session. Loading object code in both sessions will probably lead to problems. Cheers, Simon

Simon Marlow wrote:
However, there's a caveat with doing this: the RTS linker only has a single symbol table, so the running GHCi will be sharing this symbol table with the new GHC session. Loading object code in both sessions will probably lead to problems.
Is this still a problem if I compile the final program to a standalone executable rather than running it through ghci?

Lemmih wrote:
On 5/4/06, Donald Bruce Stewart
wrote: geoffw:
I have an application written in OCaml that I'm interested in porting over to Haskell, and I was wondering what the best way
the following OCaml function would be:
Toploop.initialize_toplevel_env();;
let eval txt = let lb = (Lexing.from_string txt) in let phr = !Toploop.parse_toplevel_phrase lb in Toploop.execute_phrase true Format.std_formatter phr;;
eval "let add1 x = x +1;;";; eval "add1 2;;";;
Where I would like to be able to "eval" Haskell-code instead. It looks like I might be able to achieve something like this using hs-plugins, but it looks a bit more complex. Is hs-plugins the best choice for
to replace this
kind of "meta"-programming? I'm pretty sure Template Haskell will not work for me, at least as I understand it I can only manipulate program fragments that will be compiled later and as such that it will not be possible to execute them until the next "phase".
You can do some forms of runtime metaprogrammign with hs-plugins, yes. E.g.
Prelude System.Eval.Haskell> v <- eval "1 + 2 :: Int" [] :: IO (Maybe Int) Prelude System.Eval.Haskell> v Just 3
Prelude System.Eval.Haskell> mf <- eval "\\x -> x + 1 :: Int" [] :: IO (Maybe (Int -> Int)) Prelude System.Eval.Haskell> let f = fromJust mf Prelude System.Eval.Haskell> :t f f :: Int -> Int Prelude System.Eval.Haskell> f 7 8
So if your program critically relies on this its possible to do.
You can also use the GHC library: Prelude> :m GHC Prelude GHC> GHC.init (Just "/home/david/coding/haskell/ghc/usr/lib/ghc-6.5") Prelude GHC> session <- newSession Interactive Prelude GHC> setSessionDynFlags session =<< initPackages =<< getSessionDynFlags session Prelude GHC> setContext session [] [mkModule "Prelude"] Prelude GHC> runStmt session "let add1 x = x + 1" Prelude GHC> runStmt session "add1 2" 3 Prelude GHC> :q Leaving GHCi.
Thanks! I think this is a bit closer to what I'm looking for than the hs-plugins eval. It is possible to get runStmt to output the result of the session to a string rather than stdout?

On 5/5/06, Geoffrey Alan Washburn
Lemmih wrote:
On 5/4/06, Donald Bruce Stewart
wrote: geoffw:
I have an application written in OCaml that I'm interested in porting over to Haskell, and I was wondering what the best way
the following OCaml function would be:
Toploop.initialize_toplevel_env();;
let eval txt = let lb = (Lexing.from_string txt) in let phr = !Toploop.parse_toplevel_phrase lb in Toploop.execute_phrase true Format.std_formatter phr;;
eval "let add1 x = x +1;;";; eval "add1 2;;";;
Where I would like to be able to "eval" Haskell-code instead. It looks like I might be able to achieve something like this using hs-plugins, but it looks a bit more complex. Is hs-plugins the best choice for
to replace this
kind of "meta"-programming? I'm pretty sure Template Haskell will not work for me, at least as I understand it I can only manipulate program fragments that will be compiled later and as such that it will not be possible to execute them until the next "phase".
You can do some forms of runtime metaprogrammign with hs-plugins, yes. E.g.
Prelude System.Eval.Haskell> v <- eval "1 + 2 :: Int" [] :: IO (Maybe Int) Prelude System.Eval.Haskell> v Just 3
Prelude System.Eval.Haskell> mf <- eval "\\x -> x + 1 :: Int" [] :: IO (Maybe (Int -> Int)) Prelude System.Eval.Haskell> let f = fromJust mf Prelude System.Eval.Haskell> :t f f :: Int -> Int Prelude System.Eval.Haskell> f 7 8
So if your program critically relies on this its possible to do.
You can also use the GHC library: Prelude> :m GHC Prelude GHC> GHC.init (Just "/home/david/coding/haskell/ghc/usr/lib/ghc-6.5") Prelude GHC> session <- newSession Interactive Prelude GHC> setSessionDynFlags session =<< initPackages =<< getSessionDynFlags session Prelude GHC> setContext session [] [mkModule "Prelude"] Prelude GHC> runStmt session "let add1 x = x + 1" Prelude GHC> runStmt session "add1 2" 3 Prelude GHC> :q Leaving GHCi.
Thanks! I think this is a bit closer to what I'm looking for than the hs-plugins eval. It is possible to get runStmt to output the result of the session to a string rather than stdout?
Yeah: Prelude GHC GHC.Exts> Just n <- compileExpr session "show (add1 2)" Prelude GHC GHC.Exts> let n' = unsafeCoerce# n :: String Prelude GHC GHC.Exts> n' "3" -- Friendly, Lemmih
participants (7)
-
Bulat Ziganshin
-
dons@cse.unsw.edu.au
-
Geoffrey Alan Washburn
-
Lemmih
-
Simon Marlow
-
Simon Peyton-Jones
-
wld