Abdulaziz Ghuloum writes:
> On May 19, 2009, at 11:29 PM, Jose A. Ortega Ruiz wrote: [...] >> Then there's a simple protocol between the Elisp side and the REPL, >> which is based on a set of procedures that are sent by Emacs to the >> Scheme process standard input. Again, the latter sees them just as if >> they were typed interactively. The values printed by the REPL to its >> standard output are captured back by Emacs and interpreted (they're >> formatted most of the time as alists). > > Why are these procedures sent over the repl instead of being in > some library that the underlying implementation loads? Sorry, i wasn't clear: that's precisely what geiser does. There's a library loaded at startup, and what the emacs side does is sending *calls* to these procedures, usually wrapped in geiser:eval top forms. > Can't these definitions interfere/collide with whatever the user is > doing at the repl? Ikarus does provide multiple interaction > environments so that, at the repl, you can create two interaction > environments: one for the user code and one for the geiser code is > necessary. That'd work, i think. >> Well, this is the basic idea. The actual implementation is a bit more >> complex because of the necessity of capturing errors. Once the basic >> communication procedures are working, I wrap them as evaluations >> (i.e., >> using eval) which in turn are wrapped using the exception handling >> mechanisim provided by the Scheme at hand (e.g. `with-handlers' in PLT >> or `catch' in Guile), so that any error is captured and reported >> back to >> emacs. That way, the user can get nicely formatted diagnostics and we >> preserved the integrity of the underlying Scheme process. > > In R6RS, this can be done in the same way for all implementations. Yes. >> This evaluation mechanism doubles as a way for the user to evaluate >> any >> form she wishes. A very nice thing about PLT and Guile (at least in my >> opinion) is that they provide ways of evaluating form in the context >> of >> a module namespace. Even when these evaluation imply re-defining >> exported identifiers: the system is aware of the new definitions, >> transitively. For example, in PLT scheme one has >> >> (eval <module-path> (module->namespace <module-path>)) > > This would be hard. Maybe the Ikarus back end would have to restrict > these forms to expressions, and no set!s to library variables. Sounds like a plan, yes. As an aside, is it possible to get at run time a graph of library dependencies, so that if the user wants to redefine one of them we can reload all affected ones? >> One has also the notion of 'current module' in the REPL, which >> complements nicely the above functionality: when you send an >> expression >> from a scheme buffer for evaluation, it gets evaluated in the buffer's >> module or, if no module (library) is associated with the buffer, in >> the >> 'current module'. > > Doable, modulo the restriction above. Excellent. I wasn't sure it was possible, even in the restricted send. [...] >> - ge:macroexpand (FORM MODULE FULL?) >> Expands the given FORM, recursively when FULL? is #t. > > How is this used from Geiser? You put your cursor inside the form you want to expand, press a key combination, and a window pops up containing the expansion. >> - ge:compile-file (PATH) >> - ge:load-file (PATH) >> Load, or compile and load, a file (possibly containing a module >> definition) given its path. In PLT and Guile this also means that >> all >> re-definitions are immediately seen by other modules importing the >> (re)loaded one (as in ge:eval/ge:compile) > > This is a hard one since the other modules too would have to be > recompiled and reloaded. And what about the values, say definitions > in the repl, that have been computed from the first definitions; > do they get re-evaluated too? In PLT and Guile, the pick up the new definitions. The top level works essentially as an open module in that regard. [...] >> - ge:module-completions (PREFIX) >> The same, but now we ask for a list of module paths starting with >> PREFIX. > > What's a module path? The module's (or library) name. [...] >> - ge:module-children (MODULE) >> >> Returns a list of identifiers exported by the given module, as a >> list >> of symbols. Geiser processes this list to actually classify the >> identifiers with the kind of value they're bound to (variables, >> procedures, syntactic forms...). > > Probably should be called "ge:module-exports", but fine. Agreed. I'll change that. [...] > I'll look into geiser to see how it works and see how to hook it to > Ikarus before attempting to implement anything. I'll let you know > how far I get. Excellent! It goes without saying that i'm available for any question regarding the implementation. Thanks, jao
