Hi. I want to use GHCi as the interface to my Application. The simple solution is to have the Application store its state in global IORefs. A user can then start up ghci with -package Application and use the provided functions to communicate with the Application. This works nicely. Now the tricky part. I want the user to be able to implement her own layers on top of the Application API. A typical user interaction could look something like this: $ ghci -package Application *Application:API> startApplication *Application:API> :load UserLayer *main:UserLayer> myCleverFunction 42 The problem, of course, is that as soon as the user says ':load' ghci forgets all about the state of the Application. My solution to the problem is to compile my own version of ghci (copy InteractiveUI.hs and use -package ghc) and remove the call to rts_revertCAFs when loading new modules. This seems to work, but since I don't really have a clue what I'm doing I wanted to ask a few questions: 1) What is a CAF? 2) What breaks down if you don't revert them? 3) Does not reverting the CAFs really solve my problem? / Ulf
Hi,
Have you seen:
Shellac: http://www.eecs.tufts.edu/~rdocki01/shellac.html
There was one with the JHC stuff which I'm sure i've seen
hs-plugins: http://www.cse.unsw.edu.au/~dons/hs-plugins/
If what you want is a shell like thing, Shellac will give it to you.
If you want to evaluate arbitrary Haskell then hs-plugins will give it
to you. If you want both, combine them.
Probably much easier than hacking at GHCi!
Thanks
Neil
On 8/18/06, Ulf Norell
Hi.
I want to use GHCi as the interface to my Application. The simple solution is to have the Application store its state in global IORefs. A user can then start up ghci with -package Application and use the provided functions to communicate with the Application. This works nicely.
Now the tricky part. I want the user to be able to implement her own layers on top of the Application API. A typical user interaction could look something like this:
$ ghci -package Application *Application:API> startApplication *Application:API> :load UserLayer *main:UserLayer> myCleverFunction 42
The problem, of course, is that as soon as the user says ':load' ghci forgets all about the state of the Application. My solution to the problem is to compile my own version of ghci (copy InteractiveUI.hs and use -package ghc) and remove the call to rts_revertCAFs when loading new modules. This seems to work, but since I don't really have a clue what I'm doing I wanted to ask a few questions:
1) What is a CAF? 2) What breaks down if you don't revert them? 3) Does not reverting the CAFs really solve my problem?
/ Ulf _______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
On Aug 18, 2006, at 11:54 AM, Neil Mitchell wrote:
If what you want is a shell like thing, Shellac will give it to you. If you want to evaluate arbitrary Haskell then hs-plugins will give it to you. If you want both, combine them.
I want to evaluate arbitrary Haskell code, and I did start with hs- plugins. There are a few problems: - It doesn't work 100% on Mac (which I'm using). - It's much slower than GHCi (for each expression to evaluate it creates a file and compiles it) - GHCi has a lot of features that I would have to implement myself for hs-plugins (top-level bindings, Control-C handling, lots of flags, etc).
Probably much easier than hacking at GHCi!
But not nearly as fun! :) / Ulf
If you have gone that far and modified ghci, wouldn't it be easier to
disable the :load command and hardwire the loading of the UserLayer
module ?
1) CAFs (Constant Applicative Form) are essentially top level
bindings. Top level bindings are closures, as anything in ghc, and
they are in suspended state until they are evaluated. When this
happens the closure is updated to store the computed value, and
because of this evaluation effectively happens only once.
2) I don't know, but probably you will notice during your experiments
3) Probably no. What happens to top level bindings in the interactive
environment? I think that you lose that environment too after load and
some other commands. An option is to identify and disable all these
commands.
On 18/08/06, Ulf Norell
Hi.
I want to use GHCi as the interface to my Application. The simple solution is to have the Application store its state in global IORefs. A user can then start up ghci with -package Application and use the provided functions to communicate with the Application. This works nicely.
Now the tricky part. I want the user to be able to implement her own layers on top of the Application API. A typical user interaction could look something like this:
$ ghci -package Application *Application:API> startApplication *Application:API> :load UserLayer *main:UserLayer> myCleverFunction 42
The problem, of course, is that as soon as the user says ':load' ghci forgets all about the state of the Application. My solution to the problem is to compile my own version of ghci (copy InteractiveUI.hs and use -package ghc) and remove the call to rts_revertCAFs when loading new modules. This seems to work, but since I don't really have a clue what I'm doing I wanted to ask a few questions:
1) What is a CAF? 2) What breaks down if you don't revert them? 3) Does not reverting the CAFs really solve my problem?
/ Ulf _______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
I have not followed the details, but you might consider using GHC as a library. That gives you all the facilities of GHCi, but as a library rather than as a separate process. http://haskell.org/haskellwiki/GHC/As_a_library Simon | -----Original Message----- | From: glasgow-haskell-users-bounces@haskell.org [mailto:glasgow-haskell-users-bounces@haskell.org] | On Behalf Of Ulf Norell | Sent: 18 August 2006 10:40 | To: glasgow-haskell-users@haskell.org | Subject: GHCi hacking | | Hi. | | I want to use GHCi as the interface to my Application. The simple | solution is to have the Application store its state in global IORefs. | A user can then start up ghci with -package Application and use the | provided functions to communicate with the Application. This works | nicely. | | Now the tricky part. I want the user to be able to implement her own | layers on top of the Application API. A typical user interaction | could look something like this: | | $ ghci -package Application | *Application:API> startApplication | *Application:API> :load UserLayer | *main:UserLayer> myCleverFunction 42 | | The problem, of course, is that as soon as the user says ':load' ghci | forgets all about the state of the Application. My solution to the | problem is to compile my own version of ghci (copy InteractiveUI.hs | and use -package ghc) and remove the call to rts_revertCAFs when | loading new modules. This seems to work, but since I don't really | have a clue what I'm doing I wanted to ask a few questions: | | 1) What is a CAF? | 2) What breaks down if you don't revert them? | 3) Does not reverting the CAFs really solve my problem? | | / Ulf | _______________________________________________ | Glasgow-haskell-users mailing list | Glasgow-haskell-users@haskell.org | http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
On Aug 18, 2006, at 1:15 PM, Simon Peyton-Jones wrote:
I have not followed the details, but you might consider using GHC as a library. That gives you all the facilities of GHCi, but as a library rather than as a separate process.
I am. I'm using my own modified version of InteractiveUI.hs which I compile with -package ghc. / Ulf
Ulf Norell wrote:
I want to use GHCi as the interface to my Application. The simple solution is to have the Application store its state in global IORefs. A user can then start up ghci with -package Application and use the provided functions to communicate with the Application. This works nicely.
Now the tricky part. I want the user to be able to implement her own layers on top of the Application API. A typical user interaction could look something like this:
$ ghci -package Application *Application:API> startApplication *Application:API> :load UserLayer *main:UserLayer> myCleverFunction 42
The problem, of course, is that as soon as the user says ':load' ghci forgets all about the state of the Application. My solution to the problem is to compile my own version of ghci (copy InteractiveUI.hs and use -package ghc) and remove the call to rts_revertCAFs when loading new modules. This seems to work, but since I don't really have a clue what I'm doing I wanted to ask a few questions:
1) What is a CAF?
others have answered this, but basically a CAF is a top-level non-value. Something bound at the top-level that starts life unevaluated.
2) What breaks down if you don't revert them?
Well, one reason is that you can get space leaks, because CAFs in modules that are unloaded will be retained in the heap. Another reason, if I recall correctly, is to avoid shooting yourself in the foot too badly if you type 'getContents' at the prompt, because that will put stdin into the semi-closed state and prevent it from being used again until it is reverted. There may be other reasons, but I don't remember any. Perhaps the best way to find out is just to try it. Even better would be to run the GHC test suite with that change. If it doesn't seem to break anything really important, we could make it an option you can tweak with :set. Cheers, Simon
participants (5)
-
Neil Mitchell -
pepe -
Simon Marlow -
Simon Peyton-Jones -
Ulf Norell