From: Toby A. <tob...@pe...> - 2004-05-07 01:15:58
Attachments:
multiple_evaluators-1.patch.gz
|
After some delay, here is the promised patch that allows one JVM to host multiple JScheme instances that are isolated (or not if you want) from each other. I can provide the entire changed files on request. Note that there are two new files: src/jsint/Evaluator.java and src/jscheme/SchemeEvaluator.java and one removed file: src/jsint/SI.java. The two main changes are: 1) jscheme.JS now has to be instantiated rather than just having static methods. 2) jsint.Scheme has been gutted and now delegates to a thread-local instance of the new class jsint.Evaluator, which contains almost all of the code from jsint.Scheme in non-static form. The way it works is that each JS instance has an instance of Evaluator, which holds the global variables essentially. Whenever you invoke a method on JS, it tells jsint.Scheme to use its Evaluator as the thread-local Evaluator and any jsint code that calls static methods on jsint.Scheme gets redirected to that Evaluator. For most users of JScheme the changes boil down to: JS js = new JS(); js.eval("(define (f x) (* x x))"); rather than: JS.eval("(define (f x) (* x x))"); Any feedback on these changes is welcome. If you choose to incorporate them then my job becomes much easier :-) Toby. |
From: Andrew M. <and...@wi...> - 2004-05-07 07:49:55
|
Toby Allsopp <tob...@pe...> writes: > After some delay, here is the promised patch that allows one JVM to host > multiple JScheme instances that are isolated (or not if you want) from > each other. I can provide the entire changed files on request. This is great! Thank you. I hope these changes can be incorporated into the main branch. > > Note that there are two new files: src/jsint/Evaluator.java and > src/jscheme/SchemeEvaluator.java and one removed file: > src/jsint/SI.java. > > The two main changes are: > > 1) jscheme.JS now has to be instantiated rather than just having static > methods. > > 2) jsint.Scheme has been gutted and now delegates to a thread-local > instance of the new class jsint.Evaluator, which contains almost all of > the code from jsint.Scheme in non-static form. > > The way it works is that each JS instance has an instance of Evaluator, > which holds the global variables essentially. Whenever you invoke a > method on JS, it tells jsint.Scheme to use its Evaluator as the > thread-local Evaluator and any jsint code that calls static methods on > jsint.Scheme gets redirected to that Evaluator. > > For most users of JScheme the changes boil down to: > > JS js = new JS(); > js.eval("(define (f x) (* x x))"); > > rather than: > > JS.eval("(define (f x) (* x x))"); > > Any feedback on these changes is welcome. If you choose to incorporate > them then my job becomes much easier :-) > > Toby. > > -- andy |
From: Toby A. <tob...@pe...> - 2004-05-10 19:38:00
|
[I hope you don't mind me CCing this to the devel list.] The basic idea is so that you can be running under one evaluator and then create a new one and run some isolated Scheme code. The tests I added are examples of this. This could also be achieved by changing the JS.enter and JS.exit methods to save and restore the previous evaluator, but I prefer it to be explicit. The semantics of creating new threads are a bit easier to understand with an explicit stack, in my opinion. Toby. On Mon, May 10, 2004 at 01:16:12PM -0400, Ken Anderson wrote: > Why is there a stack of evaluators? > > k > > At 07:07 AM 5/10/2004 +1200, Toby Allsopp wrote: > > Okay, here are the changed files. > > > > Toby. > > > > On Fri, May 07, 2004 at 08:12:43AM -0400, Timothy John Hickey wrote: > > > Hi Toby, > > > Could you send me a tar ball of the changed files? > > > I'll have a look and test it out on some of my larger applications.... > > > Thanks, > > > ---Tim--- > > > > > > > > > On May 6, 2004, at 9:15 PM, Toby Allsopp wrote: > > > > > > > After some delay, here is the promised patch that allows one JVM > > > > to host multiple JScheme instances that are isolated (or not if > > > > you want) from each other. I can provide the entire changed > > > > files on request. > > > > > > > > Note that there are two new files: src/jsint/Evaluator.java and > > > > src/jscheme/SchemeEvaluator.java and one removed file: > > > > src/jsint/SI.java. |
From: Ken A. <kan...@bb...> - 2004-05-10 20:55:10
|
I had ment to mention that this was a good first cut. It was a substantial change to the code base, that will guide JScheme in a new, direction. Thanks, k |
From: Ken A. <kan...@bb...> - 2004-05-10 20:44:54
|
Yes, its fine to include the developers. There ideas can certainly help figure out how to proceed. Here's the tests you added: "05/05/2004" ;; multiple independent environments ;; I use true here to mean run during the test for side effects (let ((x 0) (js1 (JS.)) (js2 (JS.))) (true (begin (set! x 0) (.load js1 "(define x 1)") (.load js2 "(define x 2)") (display x)(newline))) (= x 0) (= (.eval js1 'x) 1) (= (.eval js2 'x) 2) (true (set! x 10)) (= x 10) (= (.eval js1 'x) 1) (= (.eval js2 'x) 2) (true (.eval js1 '(set! x 11))) (= x 10) (= (.eval js1 'x) 11) (= (.eval js2 'x) 2) (true (.eval js2 '(set! x 12))) (= x 10) (= (.eval js1 'x) 11) (= (.eval js2 'x) 12)) js1 and js2 are two independent Schemes along with the one that's evaluating this code. Since they are independent, it doesn't feel like there's a need to push and pop evaluators. What am i missing? Perhaps there are static methods in Scheme.java and other classes that should simply be removed. For example, Scheme.runJscheme() should no longer be static, so the currentEvaluator() call in that method wouldn't be necessary. runJscheme() would have to be moved to Evaluator, i guess. I think getting rid of the Scheme class might be the way to go. One thing we need to do is tweeze apart is construction of an Evaluator. It should probably take an environment as an argument. Of course, you may want to fill that environment with the right stuff, such as Primitives, which takes an evaluator. In fact, i see that Primitives and U are probably the first issues to get right. I think i understand what you did to take another wack at it, hopefully with help from Tim. k PS. Do you sail? Tim, compiling is broken because some generated code needs to be changed, but you can compile and run things with javac -classpath src src/jscheme/REPL.java java -classpath src jscheme.REPL At 07:37 AM 5/11/2004 +1200, Toby Allsopp wrote: >[I hope you don't mind me CCing this to the devel list.] > >The basic idea is so that you can be running under one evaluator and >then create a new one and run some isolated Scheme code. The tests I >added are examples of this. > >This could also be achieved by changing the JS.enter and JS.exit methods >to save and restore the previous evaluator, but I prefer it to be >explicit. The semantics of creating new threads are a bit easier to >understand with an explicit stack, in my opinion. > >Toby. > >On Mon, May 10, 2004 at 01:16:12PM -0400, Ken Anderson wrote: >> Why is there a stack of evaluators? >> >> k >> >> At 07:07 AM 5/10/2004 +1200, Toby Allsopp wrote: >> > Okay, here are the changed files. >> > >> > Toby. >> > >> > On Fri, May 07, 2004 at 08:12:43AM -0400, Timothy John Hickey wrote: >> > > Hi Toby, >> > > Could you send me a tar ball of the changed files? >> > > I'll have a look and test it out on some of my larger applications.... >> > > Thanks, >> > > ---Tim--- >> > > >> > > >> > > On May 6, 2004, at 9:15 PM, Toby Allsopp wrote: >> > > >> > > > After some delay, here is the promised patch that allows one JVM >> > > > to host multiple JScheme instances that are isolated (or not if >> > > > you want) from each other. I can provide the entire changed >> > > > files on request. >> > > > >> > > > Note that there are two new files: src/jsint/Evaluator.java and >> > > > src/jscheme/SchemeEvaluator.java and one removed file: >> > > > src/jsint/SI.java. |
From: Toby A. <tob...@pe...> - 2004-05-10 22:35:36
|
Responses inline... On Mon, May 10, 2004 at 04:44:34PM -0400, Ken Anderson wrote: > Yes, its fine to include the developers. There ideas can certainly > help figure out how to proceed. > > Here's the tests you added: > "05/05/2004" ;; multiple independent environments > ;; I use true here to mean run during the test for side effects > (let ((x 0) > (js1 (JS.)) > (js2 (JS.))) > (true (begin > (set! x 0) > (.load js1 "(define x 1)") > (.load js2 "(define x 2)") > (display x)(newline))) Oops, I meant to remove that display. > (= x 0) > (= (.eval js1 'x) 1) > (= (.eval js2 'x) 2) > (true (set! x 10)) > (= x 10) > (= (.eval js1 'x) 1) > (= (.eval js2 'x) 2) > (true (.eval js1 '(set! x 11))) > (= x 10) > (= (.eval js1 'x) 11) > (= (.eval js2 'x) 2) > (true (.eval js2 '(set! x 12))) > (= x 10) > (= (.eval js1 'x) 11) > (= (.eval js2 'x) 12)) > > js1 and js2 are two independent Schemes along with the one that's > evaluating this code. Since they are independent, it doesn't feel > like there's a need to push and pop evaluators. What am i missing? When this thread's current evaluator is set to that of js1, the previous current evaluator (the one that's evaluating the test) needs to be saved somewhere so that it can be restored. Perhaps the need would be clearer in the case of: (= (+ (.eval js1 '(+ (let ((js3 (JS.))) (.load js3 "(define x 3)") (.eval js3 'x)) x)) x) 24) In this example, the variable called 'x is looked up in three different, nested evaluators. As each .eval finishes, the current evaluator must be restored to what it was when the .eval was called. > Perhaps there are static methods in Scheme.java and other classes that > should simply be removed. For example, Scheme.runJscheme() should no > longer be static, so the currentEvaluator() call in that method > wouldn't be necessary. runJscheme() would have to be moved to > Evaluator, i guess. I think getting rid of the Scheme class might be > the way to go. I agree with this. My changes were meant to be the minimum to get this to work. Once the semantics are agreed upon then the refactoring can begin in earnest :-) > One thing we need to do is tweeze apart is construction of an Evaluator. > It should probably take an environment as an argument. Of course, you > may want to fill that environment with the right stuff, such as > Primitives, which takes an evaluator. In fact, i see that Primitives > and U are probably the first issues to get right. Yes, breaking apart the concepts of "environment" (i.e. variable bindings) and "evaluator" (e.g. call stack, optimization settings, verbosity) is something that I considered. You can see in my comments that I was a bit undecided about whether I was talking about environments or evaluators. > I think i understand what you did to take another wack at it, > hopefully with help from Tim. I'm very interested to see what you make of it. > k > > PS. Do you sail? Ironically enough, no, but I have been involved in some sailing-related research. Toby. |
From: Timothy J. H. <tim...@ma...> - 2004-05-12 03:36:03
|
On May 10, 2004, at 6:35 PM, Toby Allsopp wrote: > Responses inline... > > On Mon, May 10, 2004 at 04:44:34PM -0400, Ken Anderson wrote: >> js1 and js2 are two independent Schemes along with the one that's >> evaluating this code. Since they are independent, it doesn't feel >> like there's a need to push and pop evaluators. What am i missing? > > When this thread's current evaluator is set to that of js1, the > previous > current evaluator (the one that's evaluating the test) needs to be > saved > somewhere so that it can be restored. Perhaps the need would be > clearer > in the case of: > > (= (+ (.eval js1 '(+ (let ((js3 (JS.))) > (.load js3 "(define x 3)") > (.eval js3 'x)) > x)) > x) > 24) > > In this example, the variable called 'x is looked up in three > different, > nested evaluators. As each .eval finishes, the current evaluator must > be restored to what it was when the .eval was called. So the stacks are needed because the implementation relies on threadlocal variables and you need to reset the values of the threadlocal variables when the evaluator is complete? > >> Perhaps there are static methods in Scheme.java and other classes that >> should simply be removed. For example, Scheme.runJscheme() should no >> longer be static, so the currentEvaluator() call in that method >> wouldn't be necessary. runJscheme() would have to be moved to >> Evaluator, i guess. I think getting rid of the Scheme class might be >> the way to go. I haven't looked at Toby's code yet, but I wonder if we can get by without threadlocal variables? Perhaps a major revision (of Scheme.java, Primitives.java, ....) would eliminate the need for this complication (and the stacks of interpreters....) > > I agree with this. My changes were meant to be the minimum to get this > to work. Yes, and its a great start!! > Once the semantics are agreed upon then the refactoring can > begin in earnest :-) > >> One thing we need to do is tweeze apart is construction of an >> Evaluator. >> It should probably take an environment as an argument. Of course, you >> may want to fill that environment with the right stuff, such as >> Primitives, which takes an evaluator. In fact, i see that Primitives >> and U are probably the first issues to get right. > > Yes, breaking apart the concepts of "environment" (i.e. variable > bindings) and "evaluator" (e.g. call stack, optimization settings, > verbosity) is something that I considered. You can see in my comments > that I was a bit undecided about whether I was talking about > environments or evaluators. > >> I think i understand what you did to take another wack at it, >> hopefully with help from Tim. > > I'm very interested to see what you make of it. > >> k >> >> PS. Do you sail? > > Ironically enough, no, but I have been involved in some sailing-related > research. > > Toby. |
From: Ken A. <kan...@bb...> - 2004-05-12 20:40:51
|
This is basically what i was thinking. I'm wondering how to proceed? We shouldn't duplicate work. Maybe we should get together and pair program for a couple of hours. Maybe we could use your collaboration tools! k At 11:35 PM 5/11/2004 -0400, Timothy John Hickey wrote: >I haven't looked at Toby's code yet, but I wonder if we can get by without threadlocal >variables? Perhaps a major revision (of Scheme.java, Primitives.java, ....) >would eliminate the need for this complication (and the stacks of interpreters....) |
From: Toby A. <tob...@pe...> - 2004-05-12 21:08:43
|
On Tue, May 11, 2004 at 11:35:51PM -0400, Timothy John Hickey wrote: > On May 10, 2004, at 6:35 PM, Toby Allsopp wrote: > > In this example, the variable called 'x is looked up in three > > different, nested evaluators. As each .eval finishes, the current > > evaluator must be restored to what it was when the .eval was called. > > So the stacks are needed because the implementation relies on > threadlocal variables and you need to reset the values of the > threadlocal variables when the evaluator is complete? Yes, that sums it up exactly. The implementation needs thread-local variables because the existing code relies on calls to static jsint.Scheme methods and I didn't see a clear direction for changing that. > > > Perhaps there are static methods in Scheme.java and other classes > > > that should simply be removed. For example, Scheme.runJscheme() > > > should no longer be static, so the currentEvaluator() call in that > > > method wouldn't be necessary. runJscheme() would have to be moved > > > to Evaluator, i guess. I think getting rid of the Scheme class > > > might be the way to go. > > I haven't looked at Toby's code yet, but I wonder if we can get by > without threadlocal variables? Perhaps a major revision (of > Scheme.java, Primitives.java, ...) would eliminate the need for this > complication (and the stacks of interpreters....) I actually think that a stack of thread-local variables will turn out to be the best solution, but I'm a big fan of Common Lisp-style special variables. The alternative is to pass a reference to the appropriate Evaluator instance through every method call, which seems a bit inelegant. Something like AspectJ might help here, although I don't imagine that fits in with other goals of the project. Toby. |
From: Toby A. <tob...@pe...> - 2004-05-17 02:41:36
Attachments:
multiple_evaluators-3.patch.gz
|
Here is the patch updated for the CVS updates to 20040517. Complete files available on request. Toby. |