unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* Multiple parallel environments
@ 2009-07-29 17:34 Peter Brett
  2009-07-30 13:14 ` Ludovic Courtès
  0 siblings, 1 reply; 6+ messages in thread
From: Peter Brett @ 2009-07-29 17:34 UTC (permalink / raw)
  To: guile-user

Hi folks,

I've got an interesting problem I need some help with.  I'm
implementing an editor which permits per-directory configuration
files, written in Guile Scheme. (There is also a system and user
configuration, as usual).  Quite a lot of the editing actions are
implemented as Scheme procedures, etc.

What I'd like to do is something like the following:

  * Load system config
  * Load user config
  * Save environment ==> [0]

  * User opens /path/to/a/file
  * Load config from /path/to/a/editor.conf
  * Edit, edit, hack, hack.

  * User opens /path/to/another/file
  * Save environment ==> [1]
  * Restore environment <== [0]
  * Load config from /path/to/another/editor.conf
  * Edit, edit, hack, hack.

  * User switches back to editing /path/to/a/file
  * Save environment ==> [2]
  * Restore environment <== [1]
  * Edit, edit, hack, hack.

  ... etc.

Is such a thing possible with Guile?

Thanks in advance,

                               Peter

-- 
Peter Brett <peter@peter-b.co.uk>
Remote Sensing Research Group
Surrey Space Centre





^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Multiple parallel environments
  2009-07-29 17:34 Multiple parallel environments Peter Brett
@ 2009-07-30 13:14 ` Ludovic Courtès
  2009-07-30 14:12   ` Peter Brett
  0 siblings, 1 reply; 6+ messages in thread
From: Ludovic Courtès @ 2009-07-30 13:14 UTC (permalink / raw)
  To: guile-user

Hello,

Peter Brett <peter@peter-b.co.uk> writes:

> What I'd like to do is something like the following:
>
>   * Load system config
>   * Load user config
>   * Save environment ==> [0]
>
>   * User opens /path/to/a/file
>   * Load config from /path/to/a/editor.conf
>   * Edit, edit, hack, hack.
>
>   * User opens /path/to/another/file
>   * Save environment ==> [1]
>   * Restore environment <== [0]
>   * Load config from /path/to/another/editor.conf
>   * Edit, edit, hack, hack.

Before answering, I'd like to make sure I understand what you want to
achieve.

What do you mean by "environment"?  All the global variables associated
with a given file in the editor?

What do you mean by "save"?  Serialize to a file the "environment"
associated with a file (or the difference compared to the initial
environment)?

Thanks,
Ludo'.





^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Multiple parallel environments
  2009-07-30 13:14 ` Ludovic Courtès
@ 2009-07-30 14:12   ` Peter Brett
  2009-07-30 14:45     ` Ludovic Courtès
  0 siblings, 1 reply; 6+ messages in thread
From: Peter Brett @ 2009-07-30 14:12 UTC (permalink / raw)
  To: guile-user

ludo@gnu.org (Ludovic Courtès) writes:

> Hello,
>
> Peter Brett <peter@peter-b.co.uk> writes:
>
>> What I'd like to do is something like the following:
>>
>>   * Load system config
>>   * Load user config
>>   * Save environment ==> [0]
>>
>>   * User opens /path/to/a/file
>>   * Load config from /path/to/a/editor.conf
>>   * Edit, edit, hack, hack.
>>
>>   * User opens /path/to/another/file
>>   * Save environment ==> [1]
>>   * Restore environment <== [0]
>>   * Load config from /path/to/another/editor.conf
>>   * Edit, edit, hack, hack.
>
> Before answering, I'd like to make sure I understand what you want to
> achieve.

Okay. Just to clarify, this is an instance where Guile is being used
as an extension language for an application written predominantly in C
and GTK+2.0.

> What do you mean by "environment"?  All the global variables associated
> with a given file in the editor?

Sort of.  The whole of Guile's top level bindings at that point.  (The
per-directory config is literally loaded as a Scheme script, so it
could define and redefine functions and variables at will).

> What do you mean by "save"?  Serialize to a file the "environment"
> associated with a file (or the difference compared to the initial
> environment)?

It doesn't need to be serialised -- I don't even need to be able to
get a C pointer to it! -- it just needs to be "stashed" somewhere so
that I can "rewind" Guile's toplevel bindings to that point at a later
time.

Essentially, I want each directory/"project" to be able to define its
own functions, include its own modules etc. without stomping over
another project that happens to be loaded into the application at the
same time.

I hope that makes the problem clear as mud. ;-)

[ One horrible idea was to abuse scm_from_locale_symbol() and
  scm_c_call_with_current_module() in some horrendous way. How likely
  would this be to break cataclysmically in Guile > 1.8.x? ]

Best wishes,

                              Peter

-- 
Peter Brett <peter@peter-b.co.uk>
Remote Sensing Research Group
Surrey Space Centre





^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Multiple parallel environments
  2009-07-30 14:12   ` Peter Brett
@ 2009-07-30 14:45     ` Ludovic Courtès
  2009-07-30 15:19       ` Peter Brett
  0 siblings, 1 reply; 6+ messages in thread
From: Ludovic Courtès @ 2009-07-30 14:45 UTC (permalink / raw)
  To: guile-user

Hello!

Peter Brett <peter@peter-b.co.uk> writes:

> ludo@gnu.org (Ludovic Courtès) writes:

[...]

>> What do you mean by "environment"?  All the global variables associated
>> with a given file in the editor?
>
> Sort of.  The whole of Guile's top level bindings at that point.  (The
> per-directory config is literally loaded as a Scheme script, so it
> could define and redefine functions and variables at will).

Then you are looking for Guile's nifty first-class modules.  The module
API is unfortunately lightly documented (info "(guile) Module System
Reflection").

>> What do you mean by "save"?  Serialize to a file the "environment"
>> associated with a file (or the difference compared to the initial
>> environment)?
>
> It doesn't need to be serialised -- I don't even need to be able to
> get a C pointer to it! -- it just needs to be "stashed" somewhere so
> that I can "rewind" Guile's toplevel bindings to that point at a later
> time.
>
> Essentially, I want each directory/"project" to be able to define its
> own functions, include its own modules etc. without stomping over
> another project that happens to be loaded into the application at the
> same time.

Easy!  :-)

What you would do is create one module for each file/project/directory:

  (define (make-per-file-module name)
    (let ((m (make-module)))
      (set-module-name! m name) ;; give the module an optional name
      (beautify-user-module! m) ;; populate the module with the
                                ;; default bindings
      m))

Then you create one such module for each file/directory/etc. and somehow
associate it with said file/directory/etc. (with an alist, a hash table,
or something similar).  When entering a file associated with that
module, you just have to make it current:

  (define (enter-file-buffer file)
    (set-current-module! (lookup-per-file-module file)))

And voilà!  :-)

Hope this helps,
Ludo'.





^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Multiple parallel environments
  2009-07-30 14:45     ` Ludovic Courtès
@ 2009-07-30 15:19       ` Peter Brett
  2009-07-30 15:45         ` Ludovic Courtès
  0 siblings, 1 reply; 6+ messages in thread
From: Peter Brett @ 2009-07-30 15:19 UTC (permalink / raw)
  To: guile-user

ludo@gnu.org (Ludovic Courtès) writes:

> Hello!
>
> Peter Brett <peter@peter-b.co.uk> writes:
>
>> ludo@gnu.org (Ludovic Courtès) writes:
>
> [...]
>
>>> What do you mean by "environment"?  All the global variables associated
>>> with a given file in the editor?
>>
>> Sort of.  The whole of Guile's top level bindings at that point.  (The
>> per-directory config is literally loaded as a Scheme script, so it
>> could define and redefine functions and variables at will).
>
> Then you are looking for Guile's nifty first-class modules.  The module
> API is unfortunately lightly documented (info "(guile) Module System
> Reflection").

Indeed.  Should I file a feature request for "more useful
documentation of the Guile module system"?  IMHO, examples like
my use case would be very useful and informative.

How much will the way they work be changing in the next stable series
of Guile releases?  How will they work w.r.t. R6RS modules?

>>> What do you mean by "save"?  Serialize to a file the "environment"
>>> associated with a file (or the difference compared to the initial
>>> environment)?
>>
>> It doesn't need to be serialised -- I don't even need to be able to
>> get a C pointer to it! -- it just needs to be "stashed" somewhere so
>> that I can "rewind" Guile's toplevel bindings to that point at a later
>> time.
>>
>> Essentially, I want each directory/"project" to be able to define its
>> own functions, include its own modules etc. without stomping over
>> another project that happens to be loaded into the application at the
>> same time.
>
> Easy!  :-)
>
> What you would do is create one module for each file/project/directory:
>
>   (define (make-per-file-module name)
>     (let ((m (make-module)))
>       (set-module-name! m name) ;; give the module an optional name
>       (beautify-user-module! m) ;; populate the module with the
>                                 ;; default bindings
>       m))

Something like the following?

  SCM
  create_module_for_dir (char *c_path) /* Path is a UTF-8 string */
  {
    SCM magic = scm_from_locale_symbol ("*magic-dir-module*");
    SCM path  = scm_from_locale_symbol (c_path);
    SCM module = scm_resolve_module (scm_list_2 (magic, path));
    scm_remember_upto_here_2 (magic, path);
    return module;
  }

Not entirely sure how to emulate "beautify-user-module!" in C... any ideas?

> Then you create one such module for each file/directory/etc. and somehow
> associate it with said file/directory/etc. (with an alist, a hash table,
> or something similar).  When entering a file associated with that
> module, you just have to make it current:
>
>   (define (enter-file-buffer file)
>     (set-current-module! (lookup-per-file-module file)))
>
> And voilà!  :-)
>
> Hope this helps,

This does help, thanks!

                               Peter :-)

-- 
Peter Brett <peter@peter-b.co.uk>
Remote Sensing Research Group
Surrey Space Centre





^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Multiple parallel environments
  2009-07-30 15:19       ` Peter Brett
@ 2009-07-30 15:45         ` Ludovic Courtès
  0 siblings, 0 replies; 6+ messages in thread
From: Ludovic Courtès @ 2009-07-30 15:45 UTC (permalink / raw)
  To: guile-user

Peter Brett <peter@peter-b.co.uk> writes:

> ludo@gnu.org (Ludovic Courtès) writes:

[...]

>> Then you are looking for Guile's nifty first-class modules.  The module
>> API is unfortunately lightly documented (info "(guile) Module System
>> Reflection").
>
> Indeed.  Should I file a feature request for "more useful
> documentation of the Guile module system"?

You can indeed at this to the bug tracker at
http://savannah.gnu.org/bugs/?group=guile, preferably along with a
patch.  :-)

[...]

> How much will the way they work be changing in the next stable series
> of Guile releases?

There should not be any user-visible changes (you can already try out
the 1.9 releases to see by yourself).

> How will they work w.r.t. R6RS modules?

It's unclear whether R6RS module support will be part of the forthcoming
2.0 release series; Julian Graham is working on it, though.

>> What you would do is create one module for each file/project/directory:
>>
>>   (define (make-per-file-module name)
>>     (let ((m (make-module)))
>>       (set-module-name! m name) ;; give the module an optional name
>>       (beautify-user-module! m) ;; populate the module with the
>>                                 ;; default bindings
>>       m))
>
> Something like the following?
>
>   SCM
>   create_module_for_dir (char *c_path) /* Path is a UTF-8 string */
>   {
>     SCM magic = scm_from_locale_symbol ("*magic-dir-module*");
>     SCM path  = scm_from_locale_symbol (c_path);
>     SCM module = scm_resolve_module (scm_list_2 (magic, path));
>     scm_remember_upto_here_2 (magic, path);
>     return module;
>   }
>
> Not entirely sure how to emulate "beautify-user-module!" in C... any ideas?

`resolve-module' returns a new empty module (as with `make-module') if
no module of that name exist, so you really need the effect of
`beautify-user-module!'.

The best way is to invoke it:

  SCM beautify = scm_c_lookup ("beautify-user-module!");

  scm_call_1 (beautify, module);

Thanks,
Ludo'.





^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2009-07-30 15:45 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-29 17:34 Multiple parallel environments Peter Brett
2009-07-30 13:14 ` Ludovic Courtès
2009-07-30 14:12   ` Peter Brett
2009-07-30 14:45     ` Ludovic Courtès
2009-07-30 15:19       ` Peter Brett
2009-07-30 15:45         ` Ludovic Courtès

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).