Questions for Geiser

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

Questions for Geiser

Dan Leslie

I began efforts to add support for Kawa to Geiser while on my way home
from work. A bit of forewarning: due to day job and family constraints
most of my FOSS efforts are in those moments where I can find some time
on the train to hack.

Anyhow, I've several questions I'd like to raise:

1. Is there a way to define new top level methods? Or rather, are
top level methods a thing in Kawa? Not that this is a blocker, I'm
simply curious.

2. What reflection and completion utilities are available, if any? I
noticed that SchemeWay effectively overrides relevant binding routines
in order to keep a dictionary for reflection; that doesn't seem like
an approach that would be reasonable to maintain or one that I'd like to mimic.

3. Geiser is very module-centric, and supports behaviours wherein its
aware of the R7RS-library or implementation-specific module in which a
symbol lays and will rebind it appropriately when a relevant region or
other is evaluated. What tools does Kawa provide for, say, declaring the
library/module/namespace in which a block is to be evaluated?

I hope that wasn't to abrupt of me. I'm rather curious about this scheme
of which I haven't a whole lot of experience. :)

Thanks!

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

Re: Questions for Geiser

Per Bothner


On 04/06/2015 10:23 PM, Dan Leslie wrote:

>
> I began efforts to add support for Kawa to Geiser while on my way home
> from work. A bit of forewarning: due to day job and family constraints
> most of my FOSS efforts are in those moments where I can find some time
> on the train to hack.
>
> Anyhow, I've several questions I'd like to raise:
>
> 1. Is there a way to define new top level methods? Or rather, are
> top level methods a thing in Kawa? Not that this is a blocker, I'm
> simply curious.

Not sure what you mean.  You can certainly define top-level functions.
Or rather module-level functions - and those are implicitly added to the
top-level environment when you load a module.

(I use "module" similarly to R7RS uses the term library.)

A named top-level function is compiled a primary method that implements it,
possibly some helper methods (that I'll ignore for now), and a field
that holds the function as a value.

> 2. What reflection and completion utilities are available, if any? I
> noticed that SchemeWay effectively overrides relevant binding routines
> in order to keep a dictionary for reflection; that doesn't seem like
> an approach that would be reasonable to maintain or one that I'd like to mimic.

The Kawa compiler and run-time do quite a bit of reflection.  For example you can
import a plain-old-Java-class with static fields (using the R7RS import
command), and the static fields become bindings in the importing scope.
When you import a module/library, Kawa basically resolves the module to a Java class,
and then just looks at the public fields of the class, figuring out the bindings
from those.

> 3. Geiser is very module-centric, and supports behaviours wherein its
> aware of the R7RS-library or implementation-specific module in which a
> symbol lays and will rebind it appropriately when a relevant region or
> other is evaluated. What tools does Kawa provide for, say, declaring the
> library/module/namespace in which a block is to be evaluated?

Kawa does support R7RS eval and load, where you can specify an environment to use,
in the form of R7RS environment specifiers.  See:

http://www.gnu.org/software/kawa/Eval-and-Environments.html
 
> I hope that wasn't to abrupt of me. I'm rather curious about this scheme
> of which I haven't a whole lot of experience. :)

Kawa is also very module-centric.  I suggest reading this:

http://www.gnu.org/software/kawa/Module-classes.html
http://www.gnu.org/software/kawa/Importing.html
--
        --Per Bothner
[hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: Questions for Geiser

Helmut Eller-2
On Mon, Apr 06 2015, Per Bothner wrote:

> On 04/06/2015 10:23 PM, Dan Leslie wrote:
>> 2. What reflection and completion utilities are available, if any?

One possibility is to enumerate the locations in an environment:

(import (only (kawa regex) regex-match))

(define (completions regex env :: gnu.mapping.InheritingEnvironment)
  (let ((result '()))
    ((env:enumerateAllLocations):forEachRemaining
     (lambda (loc)
       (cond ((instance? loc gnu.mapping.NamedLocation)
              (let* ((sym (loc:getKeySymbol))
                     (name (sym:getName)))
                (cond ((regex-match regex name)
                       (set! result (cons name result)))))))))
    result))

(completions #/^con/ (interaction-environment))
 => ("constant-fold" "cond-expand" "cons" "cond")

Another approach would be to only use "static" analyses ie. use the
compiler to parse source files and work with gnu.expr.Expression trees
without actually loading code.  I think the "static" approach is what
Per prefers/recommends and it's also what Eclipse and the like do.  If
you want to do sophisticated dependency management and type based
refactoring it's the way to go but for simple things like symbol
completions of top-level bindings it requires much more work than to
inspect the runtime directly.

>> 3. Geiser is very module-centric, and supports behaviours wherein its
>> aware of the R7RS-library or implementation-specific module in which a
>> symbol lays and will rebind it appropriately when a relevant region or
>> other is evaluated. What tools does Kawa provide for, say, declaring the
>> library/module/namespace in which a block is to be evaluated?
>
> Kawa does support R7RS eval and load, where you can specify an
> environment to use,

I think what Dan needs/wants is something like

 (eval '(define (my-function x) ...) (environment '(my own module)))

but Kawa doesn't support this.

Correct me if I'm wrong, but I think once a module is defined it can't
be changed because it's essentially compiled down to a JVM class.

Helmut

Reply | Threaded
Open this post in threaded view
|

Re: Questions for Geiser

Dan Leslie
In reply to this post by Per Bothner

Per Bothner <[hidden email]> writes:
> Not sure what you mean.  You can certainly define top-level functions.
> Or rather module-level functions - and those are implicitly added to the
> top-level environment when you load a module.

Heh, I had a feeling I should have been clearer. Nomenclature can
often be a point of confusion when it's not shared. :)

In Guile, Chicken and others there are various actions that are only
available at the REPL, like setting breakpoints and whatnot. Generally a
comma precedes the method name in order to differentiate it from a
symbol that could be found in the active environment.

Geiser exploits the ability to define new functions of this sort in
order to avoid polluting the active environment with geiser-specific
methods. There are perhaps other ways I can avoid name collisions and
other concerns, but my first inclination was to attempt to describe new
toplevel functions of this form.

> The Kawa compiler and run-time do quite a bit of reflection.  For example you can
> import a plain-old-Java-class with static fields (using the R7RS import
> command), and the static fields become bindings in the importing scope.
> When you import a module/library, Kawa basically resolves the module to a Java class,
> and then just looks at the public fields of the class, figuring out the bindings
> from those.

Very interesting! Are these utilities documented? I was digging through
the info docs and website yesterday, but I readily accept that I may
have overlooked it.

> Kawa does support R7RS eval and load, where you can specify an environment to use,
> in the form of R7RS environment specifiers.  See:
>
> http://www.gnu.org/software/kawa/Eval-and-Environments.html
>  
>> I hope that wasn't to abrupt of me. I'm rather curious about this scheme
>> of which I haven't a whole lot of experience. :)
>
> Kawa is also very module-centric.  I suggest reading this:
>
> http://www.gnu.org/software/kawa/Module-classes.html
> http://www.gnu.org/software/kawa/Importing.html

Ah yes, I read that. I take it that unless a R7RS define-library
expression is used that a "module" consists of all definitions found
within a given file, with visibility determined by the documented export
expressions?

I am absolutely green to Kawa; if that wasn't obvious. :)

-Dan

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

Re: Questions for Geiser

Dan Leslie
In reply to this post by Helmut Eller-2

Helmut Eller <[hidden email]> writes:

> One possibility is to enumerate the locations in an environment:
>
> (import (only (kawa regex) regex-match))
>
> (define (completions regex env :: gnu.mapping.InheritingEnvironment)
>   (let ((result '()))
>     ((env:enumerateAllLocations):forEachRemaining
>      (lambda (loc)
>        (cond ((instance? loc gnu.mapping.NamedLocation)
>      (let* ((sym (loc:getKeySymbol))
>     (name (sym:getName)))
> (cond ((regex-match regex name)
>       (set! result (cons name result)))))))))
>     result))
>
> (completions #/^con/ (interaction-environment))
>  => ("constant-fold" "cond-expand" "cons" "cond")

This is exactly what I was looking for.

> Another approach would be to only use "static" analyses ie. use the
> compiler to parse source files and work with gnu.expr.Expression trees
> without actually loading code.  I think the "static" approach is what
> Per prefers/recommends and it's also what Eclipse and the like do.  If
> you want to do sophisticated dependency management and type based
> refactoring it's the way to go but for simple things like symbol
> completions of top-level bindings it requires much more work than to
> inspect the runtime directly.

That's not an approach that's quite in-line with how Geiser is tailored;
it's more of a suite of tools to extend the REPL into your editing
buffers. The act of repeatedly injecting sexps into the REPL and so
modifying the active environment is central.

Type-based refactoring and dependency management isn't within the scope
of the mode, just yet.

> I think what Dan needs/wants is something like
>
>  (eval '(define (my-function x) ...) (environment '(my own module)))
>
> but Kawa doesn't support this.

Hmm, that's what I was looking for. No matter, we've already set
precedent for enabling/disabling features on a per-scheme basis.

Thanks!

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

Re: Questions for Geiser

Per Bothner
In reply to this post by Helmut Eller-2


On 04/07/2015 12:58 AM, Helmut Eller wrote:
> On Mon, Apr 06 2015, Per Bothner wrote:
>
>> On 04/06/2015 10:23 PM, Dan Leslie wrote:

>>> 3. Geiser is very module-centric, and supports behaviours wherein its
>>> aware of the R7RS-library or implementation-specific module in which a
>>> symbol lays and will rebind it appropriately when a relevant region or
>>> other is evaluated. What tools does Kawa provide for, say, declaring the
>>> library/module/namespace in which a block is to be evaluated?
>>
>> Kawa does support R7RS eval and load, where you can specify an
>> environment to use,
>
> I think what Dan needs/wants is something like
>
>   (eval '(define (my-function x) ...) (environment '(my own module)))
>
> but Kawa doesn't support this.

Kawa does support (eval '(....) (environment '(my own module)), which satisfies
the need for "declaring the library/module/namespace in which a block
is to be evaluated" as I understand the question.

However, you're right in that eval-ing a define will only work for the
interaction-environment.  That is as specified by r7rs.

> Correct me if I'm wrong, but I think once a module is defined it can't
> be changed because it's essentially compiled down to a JVM class.

Right.  We'd like to support some patching/re-definition of exiting modules;
it's likely the best way to do that is a combination of automatic re-compilation
with some extra indirection.

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

Re: Questions for Geiser

Per Bothner
In reply to this post by Dan Leslie


On 04/07/2015 10:03 AM, Dan Leslie wrote:
> In Guile, Chicken and others there are various actions that are only
> available at the REPL, like setting breakpoints and whatnot. Generally a
> comma precedes the method name in order to differentiate it from a
> symbol that could be found in the active environment.

Yes - and I think that is quite ugly.

> Geiser exploits the ability to define new functions of this sort in
> order to avoid polluting the active environment with geiser-specific
> methods. There are perhaps other ways I can avoid name collisions and
> other concerns, but my first inclination was to attempt to describe new
> toplevel functions of this form.

Kawa has compound names and namespaces, which IMO is cleaner:

(geiser:set-breakpoint "foo.scm" 96)

If that is too verbose, a user can define their own prefix:

(define-namespace g geiser:namespace-uri)
(g:set-breakpoint "foo.scm" 96)

>> The Kawa compiler and run-time do quite a bit of reflection.  For example you can
>> import a plain-old-Java-class with static fields (using the R7RS import
>> command), and the static fields become bindings in the importing scope.
>> When you import a module/library, Kawa basically resolves the module to a Java class,
>> and then just looks at the public fields of the class, figuring out the bindings
>> from those.
>
> Very interesting! Are these utilities documented? I was digging through
> the info docs and website yesterday, but I readily accept that I may
> have overlooked it.

At this point, there is no documented/public API.

I've started on a (kawa expressions) library (see the source in
kawa/lib/kawa/expressions.scm).  This is currently primarily used for writing
custom optimization hooks (see kawa/lib/compile_map.scm, which optimizes
map and for-each).  It could be the start of a general expression-reflection API.
It's not documented, as it's fairly recent and a work-in-progress.
--
        --Per Bothner
[hidden email]   http://per.bothner.com/