kawa paid support

classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

kawa paid support

Per Bothner
A reminder: I currently have no regular paying jobs, and I'm
basically working full-time on Kawa.  At this point I'm not
making any money on Kawa.  It would be nice to change that ...

I can offer paid support for Kawa.  That means guaranteed
priority response if you have questions, need help, or run into bugs.

I can also do custom development and enhancements - if there is
something you're missing in Kawa, let me know!

I will also accept a plain "tip" if you just want to send me money.
--
        --Per Bothner
[hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: kawa paid support

Alcides Flores Pineda
Hello Per:

Do you have a PayPal account or something alike?
If you do, please, let us know.
Maybe you can put a link to it in your blog or somewhere.
I'm thinking about possible ways you can begin making money through
Kawa... I don't know maybe also trying to do something more or less what
Xah Lee is doing in his blog (http://www.ergoemacs.org/emacs/blog.html 
selling his writings/tutorials) or maybe is time for us, the Kawa
community to start getting more formally organized and begin to
financially contribute to the project, search for sponsors, setup a
wiki, collect and share our experiencies using Kawa, compile/write an
e-book, write an emacs kawa-mode, speak & blog about Kawa, port
libraries from other Schemes, and so on... well just some thoughts.. and
my 2 cents...

Thank you very much for creating Kawa and for all the great work you
have done with this project.

Sincerely.
--
Alcides Flores Pineda.

El 30/03/15 a las 17:04, Per Bothner escibiĆ³:

> A reminder: I currently have no regular paying jobs, and I'm
> basically working full-time on Kawa.  At this point I'm not
> making any money on Kawa.  It would be nice to change that ...
>
> I can offer paid support for Kawa.  That means guaranteed
> priority response if you have questions, need help, or run into bugs.
>
> I can also do custom development and enhancements - if there is
> something you're missing in Kawa, let me know!
>
> I will also accept a plain "tip" if you just want to send me money.

Reply | Threaded
Open this post in threaded view
|

Re: kawa paid support

Per Bothner


On 04/04/2015 10:01 PM, Alcides Flores Pineda wrote:
> Hello Per:
>
> Do you have a PayPal account or something alike? If you do, please,
> let us know.

I do have a PayPal account, linked to [hidden email]

I don't want to mislead anyone: I'm far from destitute, and I could
probably afford to retire with some modest belt-tightening and/or selling
of assets.  But some of these assets (properties) have emotional
attachment. My husband and I would feel more comfortable if money was
coming in at least approaching the rate of money going out ...  (For example
property taxes and health insurance are substantial fixed expenses.)

> Maybe you can put a link to it in your blog or somewhere. I'm
> thinking about possible ways you can begin making money through
> Kawa... I don't know maybe also trying to do something more or less
> what Xah Lee is doing in his blog
> (http://www.ergoemacs.org/emacs/blog.html selling his
> writings/tutorials) or maybe is time for us, the Kawa community to
> start getting more formally organized and begin to financially
> contribute to the project, search for sponsors, setup a wiki, collect
> and share our experiencies using Kawa, compile/write an e-book, write
> an emacs kawa-mode, speak & blog about Kawa, port libraries from
> other Schemes, and so on... well just some thoughts.. and my 2
> cents...

It would be nice if Kawa wasn't a mostly-one-man project.
Of course other people contribute in various ways, and that is
very much appreciated, but 90% of the source code and documentation is mine.
Much of that is my own fault - I have some control-freak tendencies, and
I'm not very good at publicity.  But I think we're getting better:
Multiple people have contributed code, documentation, and tests; multiple
people are writing about Kawa, and using Kawa in interesting ways,

> Thank you very much for creating Kawa and for all the great work you
> have done with this project.

You're all welcome.
--
        --Per Bothner
[hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: kawa paid support

Dan Leslie

FWIW, I've just opened a bug in Geiser noting the absence of Kawa
support, and have begun local changes to endeavour to resolve the
bug. Kawa strikes me as an under-appreciated Scheme, and a suitable
competitor to the likes of Clojure, and so I'd like to bring in
compatibility to my favourite tool set.

https://github.com/jaor/geiser/issues/55

-Dan

Per Bothner <[hidden email]> writes:

> On 04/04/2015 10:01 PM, Alcides Flores Pineda wrote:
>> Hello Per:
>>
>> Do you have a PayPal account or something alike? If you do, please,
>> let us know.
>
> I do have a PayPal account, linked to [hidden email]
>
> I don't want to mislead anyone: I'm far from destitute, and I could
> probably afford to retire with some modest belt-tightening and/or selling
> of assets.  But some of these assets (properties) have emotional
> attachment. My husband and I would feel more comfortable if money was
> coming in at least approaching the rate of money going out ...  (For example
> property taxes and health insurance are substantial fixed expenses.)
>
>> Maybe you can put a link to it in your blog or somewhere. I'm
>> thinking about possible ways you can begin making money through
>> Kawa... I don't know maybe also trying to do something more or less
>> what Xah Lee is doing in his blog
>> (http://www.ergoemacs.org/emacs/blog.html selling his
>> writings/tutorials) or maybe is time for us, the Kawa community to
>> start getting more formally organized and begin to financially
>> contribute to the project, search for sponsors, setup a wiki, collect
>> and share our experiencies using Kawa, compile/write an e-book, write
>> an emacs kawa-mode, speak & blog about Kawa, port libraries from
>> other Schemes, and so on... well just some thoughts.. and my 2
>> cents...
>
> It would be nice if Kawa wasn't a mostly-one-man project.
> Of course other people contribute in various ways, and that is
> very much appreciated, but 90% of the source code and documentation is mine.
> Much of that is my own fault - I have some control-freak tendencies, and
> I'm not very good at publicity.  But I think we're getting better:
> Multiple people have contributed code, documentation, and tests; multiple
> people are writing about Kawa, and using Kawa in interesting ways,
>
>> Thank you very much for creating Kawa and for all the great work you
>> have done with this project.
>
> You're all welcome.

--
-Dan Leslie
Reply | Threaded
Open this post in threaded view
|

Re: kawa paid support

Per Bothner


On 04/05/2015 10:11 AM, Dan Leslie wrote:
>
> FWIW, I've just opened a bug in Geiser noting the absence of Kawa
> support, and have begun local changes to endeavour to resolve the
> bug. Kawa strikes me as an under-appreciated Scheme, and a suitable
> competitor to the likes of Clojure, and so I'd like to bring in
> compatibility to my favourite tool set.
>
> https://github.com/jaor/geiser/issues/55

That is the kind of tooling help that would be extremely welcome.

It would also be nice to improve Emacs's syntax highlighting
and indentation handling of Kawa:  Emacs doesn't know about various
Kawa syntax extensions (both reader syntax and standard forms),
so it sometimes gets confused.
--
        --Per Bothner
[hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: kawa paid support

Per Bothner
In reply to this post by Dan Leslie


On 04/05/2015 10:11 AM, Dan Leslie wrote:
>
> FWIW, I've just opened a bug in Geiser noting the absence of Kawa
> support, and have begun local changes to endeavour to resolve the
> bug. Kawa strikes me as an under-appreciated Scheme, and a suitable
> competitor to the likes of Clojure, and so I'd like to bring in
> compatibility to my favourite tool set.
>
> https://github.com/jaor/geiser/issues/55

FWIW: Kawa right now is a bit rough when it comes to re-loading
definitions of existing functions without confusing other functions.
Improving this is quite high on the Kawa priority list, but until
this is done Kawa may run a bit rough under Geiser.  As a work-around
try running Kawa with --no-inline.

Also, Kawa does have some support for "images as values":
http://per.bothner.com/blog/2007/ReplPane/
I'm working on a JavaScript-based terminal emulator/console
that will support embedding HTML in the console output.
Here is a prototype - I'm working on re-writing the Java to JavaScript:
https://github.com/PerBothner/JWebTerminal
--
        --Per Bothner
[hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: kawa paid support

mikel evins
In reply to this post by Per Bothner

> On Apr 5, 2015, at 1:51 AM, Per Bothner <[hidden email]> wrote:
>
> It would be nice if Kawa wasn't a mostly-one-man project.
> Of course other people contribute in various ways, and that is
> very much appreciated, but 90% of the source code and documentation is mine.
> Much of that is my own fault - I have some control-freak tendencies, and
> I'm not very good at publicity.  But I think we're getting better:
> Multiple people have contributed code, documentation, and tests; multiple
> people are writing about Kawa, and using Kawa in interesting ways,

You've mentioned the two great weaknesses with Kawa right now: lack of support for redefinitions, and lack of tooling support. I guess the first one is pretty much up to you, but other folks who want to support Kawa could help with tooling.

Speaking as someone who is using Kawa on a large project, I agree that these are the most important weaknesses. Lack of redefinition support kind of kills the Lispiness of working with Kawa. Because any given reload or eval can cause the JVM to become confused, it's basically impossible to have the kind of ongoing interactive conversation with code that is the hallmark of Lisp development. I learned long ago to simply kill the Kawa repl and restart it every time I make a significant edit. That works fine, and Kawa's startup is so fast that the time it takes to restart is no issue. What is an issue is that every restart throws away my working context, making it impossible to carry on the kind of conversation with my code that is normal for me. It means that working with Kawa is less like Lisp programming and more like a particularly fast version of the batch-oriented development cycle of working with C or Java. It's still faster and better than actually using C or Java, but it's not like using Lisp.

There are some tools out there to support Kawa, but a lot of them are pretty old and unmaintained. swank-kawa does still seem to be maintained, but it's been quite a while since I've been able to make it work. If anyone has it working, I'd be grateful to learn what you did. Without it, debugging Kawa code is pretty much down to reading Java stack traces and inserting print statements.

But that's an area where we, the users of Kawa should be able to help. It's pretty much up to Per to address the redefinition issue when he reasonably can, but Kawa users can help each other with tools. Tell me how to get swank-kawa to work, for example, and that will benefit everyone else who wants to use it. Or make a Netbeans addon to support Kawa--something I've considered doing, even though I'm not particularly a fan of Netbeans. Or even do what the Clojure community did and make a new and distinct Emacs mode to support interactive Kawa development (hmmm...).




Reply | Threaded
Open this post in threaded view
|

Redefinition/re-loading [was: kawa paid support]

Per Bothner


On 04/05/2015 01:02 PM, mikel evins wrote:
> Lack of redefinition
> support kind of kills the Lispiness of working with Kawa. Because any
> given reload or eval can cause the JVM to become confused, ...

Have you tried using --no-inline ?  This should reduce the confusion
on redefinition.  Using --no-inline could cause subtle changes in behavior,
and of course it does hurt performance.  In any case, it's only a partial
solution, since if you change the type of a function you want to re-do
the type inference and date flow of code that depends on the changed function.

It would be useful to have a design document for what *should* happen
on re-definition/re-loading.  Replacing a function with an updated one is
relatively easy, and maybe that should be the priority.  But what about
top-level expressions and variable definitions?  When should they get re-evaluated?
And what about changing class definitions - if there are existing objects
of the "old" class in the heap?  If you only support changing the body of
method (and not its parameter or return types), and don't support changing
fields, we can support that using indirection: Compile the method to indirectly
call a function that we can update.
--
        --Per Bothner
[hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: Redefinition/re-loading [was: kawa paid support]

mikel evins

> On Apr 5, 2015, at 3:36 PM, Per Bothner <[hidden email]> wrote:
>
>
>
> On 04/05/2015 01:02 PM, mikel evins wrote:
>> Lack of redefinition
>> support kind of kills the Lispiness of working with Kawa. Because any
>> given reload or eval can cause the JVM to become confused, ...
>
> Have you tried using --no-inline ?  This should reduce the confusion
> on redefinition.  Using --no-inline could cause subtle changes in behavior,
> and of course it does hurt performance.  In any case, it's only a partial
> solution, since if you change the type of a function you want to re-do
> the type inference and date flow of code that depends on the changed function.

I haven't tried it, on the possibly-wrong theory that making the time gaps larger between problems occurring would make things worse rather than better. Why worse? Because if such problems are still common, but uncommon enough that I don't immediately realize what's happening, then I might spend more unproductive time trying to solve nonexistent issues.

That's all purely speculative, though, since I haven't actually tried it. I should and I will. I don't think performance is an issue for the interactive-development case, anyway.

> It would be useful to have a design document for what *should* happen
> on re-definition/re-loading.  Replacing a function with an updated one is
> relatively easy, and maybe that should be the priority.  But what about
> top-level expressions and variable definitions?  When should they get re-evaluated?
> And what about changing class definitions - if there are existing objects
> of the "old" class in the heap?  If you only support changing the body of
> method (and not its parameter or return types), and don't support changing
> fields, we can support that using indirection: Compile the method to indirectly
> call a function that we can update.

Yeah, you're right; there should be a design document.

My point of reference for interactive development is basically Common Lisp environments, but Common Lisp has well defined semantics for redefinition, and special forms (EVAL-WHEN) for controlling what gets evaluated when.

Yeah, I'd want a function redefinition to replace the defined function. I'd want toplevel expressions to get redefined, and toplevel variables, too.

I would *want* classes to be redefined as well, but, as you mention, there's a can of worms there. In a Common Lisp environment when you redefine a class, existing instances are updated as-needed to reflect the new class definition, but I'm not claiming that's an easy thing to support. CLOS has a whole suite of features designed specifically to support that (see section 7.2 of the spec, "Changing the class of an instance," or http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/sec_7-2.html), and I'm not going to claim it's reasonable to expect you to add all of that.



Reply | Threaded
Open this post in threaded view
|

Re: Redefinition/re-loading [was: kawa paid support]

Per Bothner
In reply to this post by Per Bothner
Kawa does have "smart" re-loading when you do a require or import.
This can support the kind of dynamic re-loading you want, though
you might have to slightly re-organize your code.

To see how it works consider this:

$ cat /tmp/bar.scm
(define (g x) (+ x x 3))
(format #t "loading bar~%")

$ cat /tmp/foo.scm
(require "/tmp/bar.scm")
(define (f x) (list x  (g x)))
(format #t "loading foo~%")

$ kawa
#|kawa:1|# (require "/tmp/foo.scm")
loading bar
loading foo
#|kawa:2|# (f 4)
(4 11)
#|kawa:3|# (f 4)
(4 11)

;; Now edit /tmp/bar.scm

#|kawa:5|# (f 4)
(4 11)
#|kawa:6|# (require "/tmp/foo.scm")
loading bar
loading foo
#|kawa:7|# (f 4)
(4 13)

;; Now edit "/tmp/foo.scm"

#|kawa:8|# (require "/tmp/foo.scm")
loading foo
#|kawa:9|# (f 4)
(4 10 13)

It's semi-automatic, and module-level.

A require will a load a module if it hasn't been loaded yet,
*or* if it is out-of-date (based on file time-stamps).  If the
module depends on some other module that is out-of-date,
that gets re-loaded, as do all modules that depend on the out-of-date
module.

You don't have to hard-wire in file paths as in the above example.
Instead you can use the module search mechanism:
http://www.gnu.org/software/kawa/Importing.html

The tricky part is structuring your code so that any state you
don't want re-loaded is in modules that don't "depend" on a
module that is automatically reloaded.  One possible approach
is to put that in a file that you load with the load function,
instead of require.  Or we can add some mechanism to disable
re-loading certain modules.  Or you can use the define-variable
form for you "fixed state": It is similar to Common Lisp's
defvar form in that it doesn't re-evaluate the init form if there
is an existing binding.

The existing mechanism can do the job, I think, but it's not
as friendly as we'd like: It should work at finer grain (top-level
definitions rather than entire modules), and generally be smarter.
For example we need a mechanism to handle edits to a define-class.

There are also no doubt minor fixable bugs.  Try it out.
--
        --Per Bothner
[hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: Redefinition/re-loading [was: kawa paid support]

mikel evins

> On Apr 5, 2015, at 4:08 PM, Per Bothner <[hidden email]> wrote:
>
> Kawa does have "smart" re-loading when you do a require or import.
> This can support the kind of dynamic re-loading you want, though
> you might have to slightly re-organize your code.
>
> To see how it works consider this:

Yeah, this is already how I do things. I still need to restart Kawa on pretty much any significant edit, or I get stack traces that disappear when I do restart it.

I don't pretend to understand the problem deeply, because I've simply done what I needed to do to make the stack traces disappear. If you want me to examine things more closely, I'd be happy to do so. We just need to talk about what you'd like me to try.

Reply | Threaded
Open this post in threaded view
|

Re: Redefinition/re-loading [was: kawa paid support]

Per Bothner


On 04/05/2015 02:53 PM, mikel evins wrote:
> Yeah, this is already how I do things. I still need to restart Kawa
> on pretty much any significant edit, or I get stack traces that
> disappear when I do restart it.
>
> I don't pretend to understand the problem deeply, because I've simply
> done what I needed to do to make the stack traces disappear. If you
> want me to examine things more closely, I'd be happy to do so. We
> just need to talk about what you'd like me to try.

Yes, it would be useful to know where the stack trace is coming from.

It would be useful to in each foo.scm add a
   (format #t "loading foo.scm~%")
That will help see which modules are loaded and when.

If you modify function f, you want all modules that depend on f
(directly and indirectly) to get re-loaded.  The exception is f
is used as an untyped procedure value - for example stached somewhere
and then used as the argument to apply.

As a check: I hope you're using require or import, not load to load
your modules.
--
        --Per Bothner
[hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: Redefinition/re-loading [was: kawa paid support]

mikel evins

> On Apr 5, 2015, at 5:15 PM, Per Bothner <[hidden email]> wrote:
>
>
>
> On 04/05/2015 02:53 PM, mikel evins wrote:
>> Yeah, this is already how I do things. I still need to restart Kawa
>> on pretty much any significant edit, or I get stack traces that
>> disappear when I do restart it.
>>
>> I don't pretend to understand the problem deeply, because I've simply
>> done what I needed to do to make the stack traces disappear. If you
>> want me to examine things more closely, I'd be happy to do so. We
>> just need to talk about what you'd like me to try.
>
> Yes, it would be useful to know where the stack trace is coming from.
>
> It would be useful to in each foo.scm add a
>  (format #t "loading foo.scm~%")
> That will help see which modules are loaded and when.
>
> If you modify function f, you want all modules that depend on f
> (directly and indirectly) to get re-loaded.  The exception is f
> is used as an untyped procedure value - for example stached somewhere
> and then used as the argument to apply.
>
> As a check: I hope you're using require or import, not load to load
> your modules.

This is a convenient moment to test this stuff out, as I'm right at the beginning of a refactoring phase. The previous iteration of the project is nicely stashed and I'm working in a fresh src directory, so following whatever instructions you think wise will be pretty easy for me. I will, for example, do just as you've suggested above.

Here are a few notes on the organization of the previous iteration, in case they're helpful for you.

The project is currently about five thousand lines of Scheme in around 55 source files. the load function never appears in any file. Interactive loading of the client app occurs when I manually load LOAD-CLIENT.scm, which, in addition to a few handy forms stored in comments, has only the following line in it:

  (require "client-main.scm")

All of the other files are loaded transitively and implicitly by additional requires in client-main and its transitive dependencies.

Both client and server depend on the JMonkeyEngine game engine, which is written entirely in Java. JME's architecture is such that many common tasks can be accomplished only by subclassing JME-provided abstract classes, or JME classes with abstract methods. This is one feature of JME, by the way, that makes Kawa a much better choice than, say, ABCL or Clojure; Kawa can easily define subclasses of JME classes, and ABCL and Clojure cannot. (Before someone objects, yes, both ABCL and Clojure provide workarounds, but they are clearly workarounds, and nowhere near as simple or straightforward as Kawa's direct support for subclassing Java classes.)

The overall architecture of the project is a set of classes and functions that use JME objects to create a multiuser networked game in an immersive 3D space. It works very very well. For the curious, here's a brief test video I made last summer of an avatar in the game moving around near a terraformed Venus:

  https://dl.dropboxusercontent.com/u/6638724/fabric-venus-1080p.mov

The client launches quickly. The framerate is high and the game is very responsive. I don't see any roadblocks at all in the way of bringing it all the way to launch using JME and Kawa. My issues are all in the nature of quality-of-life issues for developers, not serious problems with development.

As I mentioned, all loading is done through transitive requires. In all cases I use requires of the form (require "foo.scm"). I'm aware that I'm supposed to be able to do (require foo), but that has never worked in the interactive case. Requiring the source-file name always works in both interactive and ahead-of-time-compiled cases.

It's been a while since I saw a stack trace, because the habit of restarting is deeply ingrained at this point. Indeed, I'm going to have to fight conditioned reflexes at this point in order to avoid it--every time I save and edit my hands automatically kill and restart Kawa. But I'll try to suppress the conditioned reflex to get you the information you want.

Since I can't tell you yet the specific circumstances that cause stacktraces, I'll briefly describe my typical development cycle.

I generally start by loading the last commit and running the game to confirm for myself that things work the way I remember. I may run through the various screens of the game--login, character creator, character-picker, play, transit. I have things set up so that I can swap these states with a single expression, to make interactive testing as easy as possible.

Having decided what feature to work on, I'll open the relevant source files and make the simplest possible version of some new feature or supporting data structure or function, require that file or eval the new expression in order to see the new definition, and then eval some likely expressions in the repl to test whether things work the way I intend. If I were working in another Lisp, I would build up some test data structures in the toplevel environment and feed them to new functions to see what happens. I would inspect the data structures between function calls to compare to my expectations. I would gradually flesh out the new definitions toward completeness.

In some cases, when using a Common Lisp environment, I'll use the old idiom of writing a toplevel function whose subfunctions are undefined, then execute it. When an undefined function is enocuntered, the Lisp enters a breakloop, where I can examine the dynamic state to see whether it's what I expect. If so, I can then define the next undefined subfunction and restart the function call, proceeding in this way until the toplevel feature in implemented.

Obviously, that style of working doesn't really work in Kawa at the moment, so instead I'll kill Kawa as soon as I've done a test run, write a simple primitive version of whatever I'm trying to implement, restart Kawa and load everything, then eval something that will cause the new code to be executed. I'll then examine the results to determine whether things worked as intended, kill Kawa, and move to the next iteration.

As I say, I'm doing a refactor right now in order to simplify one of the subsystems, so it's an especially good moment to suggest things I might try. The first thing I'll try to do is just skip the kill-and-restart step and see if I can gather some info for you about what stacktraces I end up seeing.


Reply | Threaded
Open this post in threaded view
|

Re: Redefinition/re-loading [was: kawa paid support]

mikel evins

> On Apr 5, 2015, at 5:58 PM, mikel evins <[hidden email]> wrote:
>
> As I say, I'm doing a refactor right now in order to simplify one of the subsystems, so it's an especially good moment to suggest things I might try. The first thing I'll try to do is just skip the kill-and-restart step and see if I can gather some info for you about what stacktraces I end up seeing.

First example. Here's the context:

I started with a subset of my sources, 8 source files, loaded in the way I described before, with a single require in the main file, and transitive loads handled by requires in the subsidiary files. Those eight files loaded with out error and ran the app code as expected.

Next I add a new file which defines a new class, a subclass of a JME class. On first load, I find that I neglected to define private aliases for two Java types that the source file uses. So I add the missing private aliases and reload. The reload results in the stack trace below. Killing and restarting kawa enables me to load the code without error, and the client app runs without incident.

#|kawa:3|# Exception in thread "main" java.lang.Error: internal error: cannot take location of Declaration[FabricClient/1013]
        at gnu.expr.Declaration.load(Declaration.java:300)
        at gnu.expr.ReferenceExp.compile(ReferenceExp.java:175)
        at gnu.expr.Expression.compileWithPosition(Expression.java:132)
        at gnu.expr.BindingInitializer.emit(BindingInitializer.java:109)
        at gnu.expr.Compilation.dumpInitializers(Compilation.java:716)
        at gnu.expr.Compilation.generateBytecode(Compilation.java:2169)
        at gnu.expr.Compilation.process(Compilation.java:2001)
        at gnu.expr.ModuleInfo.loadByStages(ModuleInfo.java:290)
        at gnu.expr.ModuleExp.evalToClass(ModuleExp.java:69)
        at gnu.expr.ModuleExp.evalModule1(ModuleExp.java:259)
        at gnu.expr.ModuleExp.evalModule(ModuleExp.java:214)
        at kawa.Shell.run(Shell.java:291)
        at kawa.Shell.runFile(Shell.java:523)
        at kawa.standard.load.apply2(load.java:67)
        at kawa.standard.load.apply1(load.java:27)
        at gnu.mapping.Procedure.apply(Procedure.java:135)
        at gnu.mapping.Procedure.apply(Procedure.java:118)
        at gnu.mapping.CallContext.runUntilDone(CallContext.java:234)
        at gnu.expr.ModuleExp.evalModule2(ModuleExp.java:381)
        at gnu.expr.ModuleExp.evalModule(ModuleExp.java:219)
        at kawa.Shell.run(Shell.java:291)
        at kawa.Shell.run(Shell.java:203)
        at kawa.Shell.run(Shell.java:184)
        at kawa.repl.main(repl.java:892)

Process scheme exited abnormally with code 1