This is the mail archive of the kawa@sourceware.org mailing list for the Kawa project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Embedding a REPL in a Java application


On Nov 14, 2009, at 12:22 PM, Per Bothner wrote:

On 11/13/2009 04:10 PM, Jamison Hope wrote:
Is there a way to construct two instances of ReplDocument which share
an environment, without having access to package-visible fields?

After a little bit of thought, I think adding a "copy constructor" for ReplDocument might make sense:

 public ReplDocument (ReplDocument old)
 {
   this(new SwingContent(), old.language, old.environment, true);
 }

and add a GuiConsole method to take a ReplDocument:

public GuiConsole(ReplDocument rdoc)
{
super("Kawa");
repl.getLanguage(); // In case a new GuiConsole is created from Java.
init(doc);
}


public GuiConsole(Language language, Environment penvironment, boolean shared)
{
this(new ReplDocument(language, penvironment, shared));
}


Then the shared action becomes:

   else if (cmd.equals(NEW_SHARED))
     new GuiConsole(new ReplDocument(document));

Could you this approach, and see how it works, both for the
existing GuiConsole, and your application?

It sounds like for this to work, I would need to create and hold onto a special initial ReplDocument (with shared=false) and then all subsequent ReplDocument instances I would create from it with the proposed copy constructor. That could work, but it seems a bit heavy. Let me step back for a moment and state my overall aims for this:


(1) I want to augment my application with a Scheme layer, accessible to the user through one or more REPL windows.
(2) I want all REPL windows to be on an equal footing: the user should be able to open and close them at will. In particular, the first one shown should not be any more special than any other.
(3) I want all REPL windows to share an environment, in the sense that define and set! statements evaluated in one produce bindings visible in any other. In other words, I want these windows to be (or at least to appear to be) stateless views into a common underlying Scheme environment.
(4) I want the shared Scheme environment to be lazily loaded the first time the user requests a REPL, to keep it an opt-in feature.
(5) I want Scheme to be initialized with a number of domain-specific bindings (references to objects, as well as procedures and macros) prior to the first REPL window being displayed. For generality, let's assume that these can come from plaintext scm files, compiled class files, as well as direct "define" method calls in Java.
(5) Once instantiated, this shared environment should persist until I quit the program, even if all REPL windows have already been closed.


Each ReplDocument has its own backing Thread (a Future), right? So if I use one -- one not associated with any visible Frame -- as the (container of the) persistent Environment, I'll have spawned an extra Thread which is doing absolutely nothing. Is that as wasteful as it seems, or is such a Thread unavoidable if I want to preserve the Environment beyond the lifespan of a particular REPL window?

It also occurs to me that I may run into trouble with ReplDocument due to it calling repl.exitIncrement/exitDecrement. Unlike in the pure GuiConsole case, I don't want my application shutting down just because the last REPL window was closed!

I do think that the copy constructor would be a worthwhile addition to the ReplDocument API, regardless of whether it's right for my problem.

Thanks,
Jamie

--
Jamison Hope
The PTR Group
www.theptrgroup.com




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]