capabilities of GHC API

Hello, I think what I'm trying to do is too ambitious, but I thought I would ask to see if it is possible. It seems like there is no easy way to do it, given what I've seen of the GHC API. I would like to have a function, say it is called "this", which has the following effect in ghci
let n = 2 in this n 2
In other words, it captures all the variables which are in scope, and adds them to the GHCi environment. Somebody helpful will probably say "But you can just write 'let n = 2'!", but that is not the aim. There are several aims. One is to be able to look at the variables inside a function which one is trying to debug, then inserting 'this' will cause them to be in scope, I think that would be useful. A more important aim is to be able to use existentially quantified variables easily. Currently I can do:
reifyIntegral 5 (\n -> print $ reflectNum n) 5
but how can I get GHCi to have an 'n' binding which is inside the function? Clearly just returning 'n' will not work:
reifyIntegral 5 id
<interactive>:1:0: Inferred type is less polymorphic than expected ... This is what I am thinking of doing, but as I said it seems ambitious. There are several easier things one could think of:
let n = 2 in bind "n" n n 2
If it were possible to add bindings to the GHCi bindings list, then this would be easy. Is it possible? The documentation doesn't seem to mention such a capability. Also, probably another useful feature would be to combine 'this' with something in the IO monad:
withProgName "blah" thisIO getProgName "blah"
So, are these things currently possible? Planned? Have the functions I describe been implemented already? I think there is a GHCi debugger in the works, so maybe functionality like this will be part of it, I didn't want to start something on my own if that is the case... Many thanks, Frederik -- http://ofb.net/~frederik/

On 5/19/07, Frederik Eaton
Hello,
I think what I'm trying to do is too ambitious, but I thought I would ask to see if it is possible. It seems like there is no easy way to do it, given what I've seen of the GHC API.
I would like to have a function, say it is called "this", which has the following effect in ghci
let n = 2 in this n 2
In other words, it captures all the variables which are in scope, and adds them to the GHCi environment. Somebody helpful will probably say "But you can just write 'let n = 2'!", but that is not the aim. There are several aims. One is to be able to look at the variables inside a function which one is trying to debug, then inserting 'this' will cause them to be in scope, I think that would be useful. A more important aim is to be able to use existentially quantified variables easily. Currently I can do:
reifyIntegral 5 (\n -> print $ reflectNum n) 5
but how can I get GHCi to have an 'n' binding which is inside the function? Clearly just returning 'n' will not work:
reifyIntegral 5 id
<interactive>:1:0: Inferred type is less polymorphic than expected ...
This is what I am thinking of doing, but as I said it seems ambitious. There are several easier things one could think of:
let n = 2 in bind "n" n n 2
If it were possible to add bindings to the GHCi bindings list, then this would be easy. Is it possible? The documentation doesn't seem to mention such a capability.
Also, probably another useful feature would be to combine 'this' with something in the IO monad:
withProgName "blah" thisIO getProgName "blah"
So, are these things currently possible? Planned? Have the functions I describe been implemented already? I think there is a GHCi debugger in the works, so maybe functionality like this will be part of it, I didn't want to start something on my own if that is the case...
This is pretty much that the GHCi debugger does expect it restores the environment at the end of a breakpoint. If you have GHC-6.6 or greater, try: let n = 2 in GHC.Base.breakpoint () -- Cheers, Lemmih

This is pretty much that the GHCi debugger does expect it restores the environment at the end of a breakpoint.
I can't make any sense of what you wrote. Did you mean "what" instead of "that", and "except" instead of "expect"? In that case, it is good news to hear that it has already been done.
If you have GHC-6.6 or greater, try: let n = 2 in GHC.Base.breakpoint ()
Interesting, apparently that statement also contains the word 'print': :) $ ghci fly:~ ___ ___ _ / _ \ /\ /\/ __(_) / /_\// /_/ / / | | GHC Interactive, version 6.6.20070420, for Haskell 98. / /_\\/ __ / /___| | http://www.haskell.org/ghc/ \____/\/ /_/\____/|_| Type :? for help. Loading package base ... linking ... done.
let n = 2 in GHC.Base.breakpoint
<interactive>:1:0: No instance for (Show (a -> a)) arising from use of `print' at <interactive>:1:0-31 Possible fix: add an instance declaration for (Show (a -> a)) In the expression: print it In a 'do' expression: print it -------- Frederik

On Sat, May 19, 2007 at 06:09:45PM +0100, Frederik Eaton wrote:
If you have GHC-6.6 or greater, try: let n = 2 in GHC.Base.breakpoint ()
Interesting, apparently that statement also contains the word 'print': :)
$ ghci fly:~ ___ ___ _ / _ \ /\ /\/ __(_) / /_\// /_/ / / | | GHC Interactive, version 6.6.20070420, for Haskell 98. / /_\\/ __ / /___| | http://www.haskell.org/ghc/ \____/\/ /_/\____/|_| Type :? for help.
Loading package base ... linking ... done.
let n = 2 in GHC.Base.breakpoint
<interactive>:1:0: No instance for (Show (a -> a)) arising from use of `print' at <interactive>:1:0-31 Possible fix: add an instance declaration for (Show (a -> a)) In the expression: print it In a 'do' expression: print it
You forgot the () at the end. (And btw, ghci's autoprinting works by wrapping your code in print) Stefan

On 5/19/07, Frederik Eaton
This is pretty much that the GHCi debugger does expect it restores the environment at the end of a breakpoint.
I can't make any sense of what you wrote. Did you mean "what" instead of "that", and "except" instead of "expect"?
Ah, yes. I should really pay more attention. -- Cheers, Lemmih

Lemmih wrote:
On 5/19/07, Frederik Eaton
wrote: Hello,
I think what I'm trying to do is too ambitious, but I thought I would ask to see if it is possible. It seems like there is no easy way to do it, given what I've seen of the GHC API.
I would like to have a function, say it is called "this", which has the following effect in ghci
let n = 2 in this n 2
In other words, it captures all the variables which are in scope, and adds them to the GHCi environment. Somebody helpful will probably say "But you can just write 'let n = 2'!", but that is not the aim. There are several aims. One is to be able to look at the variables inside a function which one is trying to debug, then inserting 'this' will cause them to be in scope, I think that would be useful. A more important aim is to be able to use existentially quantified variables easily. Currently I can do:
reifyIntegral 5 (\n -> print $ reflectNum n) 5
but how can I get GHCi to have an 'n' binding which is inside the function? Clearly just returning 'n' will not work:
reifyIntegral 5 id
<interactive>:1:0: Inferred type is less polymorphic than expected ...
This is what I am thinking of doing, but as I said it seems ambitious. There are several easier things one could think of:
let n = 2 in bind "n" n n 2
If it were possible to add bindings to the GHCi bindings list, then this would be easy. Is it possible? The documentation doesn't seem to mention such a capability.
Also, probably another useful feature would be to combine 'this' with something in the IO monad:
withProgName "blah" thisIO getProgName "blah"
So, are these things currently possible? Planned? Have the functions I describe been implemented already? I think there is a GHCi debugger in the works, so maybe functionality like this will be part of it, I didn't want to start something on my own if that is the case...
This is pretty much that the GHCi debugger does expect it restores the environment at the end of a breakpoint.
If you have GHC-6.6 or greater, try: let n = 2 in GHC.Base.breakpoint ()
GHC.Base.breakpoint doesn't work in the HEAD at the moment. We might want to restore it; I'm not sure. Since breakpoints are almost everywhere, it didn't seem necessary. I don't currently have breakpoints in either compiled code or expressions typed at the prompt, so you can't do exactly what Frederik was asking for, although if the code is in a source file then it works fine. Instrumenting expressions typed at the prompt wouldn't be hard, I'll add that to the list. The documentation for the GHCi debugger is here, FYI: http://www.haskell.org/ghc/dist/current/docs/users_guide/ghci-debugger.html Cheers, Simon

If you have GHC-6.6 or greater, try: let n = 2 in GHC.Base.breakpoint ()
GHC.Base.breakpoint doesn't work in the HEAD at the moment. We might want to restore it; I'm not sure. Since breakpoints are almost everywhere, it didn't seem necessary.
I don't understand the last sentence. Breakpoints didn't seem necessary since they are almost everywhere? Thanks, Frederik
I don't currently have breakpoints in either compiled code or expressions typed at the prompt, so you can't do exactly what Frederik was asking for, although if the code is in a source file then it works fine.
Instrumenting expressions typed at the prompt wouldn't be hard, I'll add that to the list.
The documentation for the GHCi debugger is here, FYI:
http://www.haskell.org/ghc/dist/current/docs/users_guide/ghci-debugger.html
Cheers, Simon

Frederik Eaton wrote:
If you have GHC-6.6 or greater, try: let n = 2 in GHC.Base.breakpoint () GHC.Base.breakpoint doesn't work in the HEAD at the moment. We might want to restore it; I'm not sure. Since breakpoints are almost everywhere, it didn't seem necessary.
I don't understand the last sentence. Breakpoints didn't seem necessary since they are almost everywhere?
Sorry, that was a bit unclear. In the first implementation of breakpoints you had to explicitly annotate breakpoints in your code using GHC.Base.breakpoint. In the current implementation, the system adds a breakpoint to every subexpression, and you enable them individually via GHCi commands. So there's no need to use GHC.Base.breakpoint (and indeed it doesn't work now). See the docs for details. Cheers, Simon
participants (4)
-
Frederik Eaton
-
Lemmih
-
Simon Marlow
-
Stefan O'Rear