--- Begin Message ---
On May 19, 2009, at 11:29 PM, Jose A. Ortega Ruiz wrote:
>
> Hi Aziz,
>
> Thanks for your interest in supporting Geiser, that's really great.
> And
> thanks a lot to Eduardo for the plug! :)
>
> Abdulaziz Ghuloum <[email protected]>
> writes:
>
>>
>> I need more information about how he hooks things up. I presume that
>> geiser would be communicating with an inferior ikarus process (how?)
>> to ask about these things.
>
> That's correct: Geiser spawns an interactive Scheme REPL and
> communicates (using comint-mode for those in the know) by redirecting
> the standard i/o. From the point of view of the Scheme process, it
> looks
> just like an interactive session, although a server Scheme process
> providing a REPL through a socket is also supported.
>
> 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).
>
> 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.
>
> 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>))
>
> 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'.
>
> For what i've read about R6RS, this form of operation is actually not
> possible in a strictly standard implementation (and actually i know
> for
> a fact that i'm using extensions beyond R6RS to implement it in
> both PLT
> and Guile). To me, that cuts half of the fun from a hypothetical
> R6RS-Geiser, but there's still the other half, that can be uselful.
>
>> I think it would be a great service to all R6RS implementors if it's
>> formally specified what the implementation needs to provide.
>
> The procedures used by Geiser are listed, for instance, in
>
> <http://git.hacks-galore.org/gitweb/jao?
> p=geiser.git;a=blob;f=scheme/guile/geiser/emacs.scm;hb=HEAD>
>
> Here's what they do:
>
> - ge:eval (FORM MODULE)
> Evaluates the given FORM (a sexp) in the context of MODULE
>
> - ge:compile (FORM MODULE)
> For systems providing JIT compilation; usually just an alias for
> ge:eval.
>
> - ge:macroexpand (FORM MODULE FULL?)
> Expands the given FORM, recursively when FULL? is #t.
>
> - 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)
>
> - ge:autodoc (IDENTIFIER MODULE)
> When IDENTIFER (a symbol) is bound in MODULE, and the bound value
> corresponds to a procedure, a list of arities is returned. Each
> arity
> consists of a list of required, optional and keyword arguments,
> ideally with the argument names that were used during its
> definition.
> (In PLT i read the corresponding module definition as syntax, and
> manually grab the arguments' names from the definition's formals,
> because they're not stored anywhere else by the system; while
> this is
> kludgy, it has the benefit that i can get also (sometimes) argument
> names for macros).
>
> - ge:completions (PREFIX MODULE)
> Returns a list of all identifiers visible in MODULE's namespace
> whose
> string rep starts with PREFIX. Of course, here just returning a list
> of all visible identifiers is enough; the filtering is easy to
> implement.
>
> - ge:module-completions (PREFIX)
> The same, but now we ask for a list of module paths starting with
> PREFIX.
>
> - ge:symbol-location (SYMBOL MODULE)
> Given a symbol (probably this should be called
> ge:identifier-location), when it's bound in MODULE returns the full
> path and line number of the source file where it's defined.
> Returning
> only the file's path is OK, provided that the original name of the
> value is returned too.
>
> - ge:module-location (MODULE)
> Given a module name, returns the full path to the file where's it's
> implemented.
>
> - 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...).
>
> - ge:callers (PROC-NAME MODULE)
> - ge:callees (PROC-NAME MODULE)
> Given a procedure defined in MODULE, produce a list of symbols
> listing
> its callers and callees, to some degree of approximation. Of course,
> an exact list is not computable in general, but in Guile we're happy
> providing partial list--it's better than nothing.
>
> - ge:generic-methods
> - ge:symbol-documentation
> These are specific to schemes providing OO a la CLOS and docstrings,
> although if the system has any kind of built-in documentation
> facility
> that can be accessed programmatically, the latter hooks on that.
>
> These are actually high-level procedures, as seen by Emacs, which are
> implemented in terms of more primitive ones (for one thing, they wrap
> the actual results in the protocol understood by the Elisp side), but
> i'd say that a proper interface for an R6RS 'standard' library
> (describing the 'primitive procedures') can be readily derived from
> them. It goes without saying that i'll help as much as i can towards
> that goal, in case you feel that a substantial enough subset of the
> procedures above is implementable in Ikarus or R6RS in general (if the
> functionality is in there, i'm perfectly happy with implementing an
> Ikarus-specific version of Geiser's backend, even if it's not
> R6RS-compliant).
>
> Thanks again for your interest!
>
> Cheers,
> jao
> --
> I always pass on good advice. It's the only thing to do with it. It is
> never any use to oneself.
> -Oscar Wilde
--- End Message ---