guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Transient environment with standard functions


From: Taylan Ulrich Bayırlı/Kammer
Subject: Re: Transient environment with standard functions
Date: Sat, 11 Jun 2016 02:08:36 +0300
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux)

Matthew Keeter <address@hidden> writes:

> However, if I make an empty environment with (null-environment), it
> doesn’t have useful functions like + and *; looks like (make-module)
> has the same issue.

Adding the (guile) module to the environment is going to provide a sane
base environment.

Let's implement something like R7RS's 'environment':

    (define (environment . modules)
      (let ((m (make-module)))
        (module-use-interfaces! m (map resolve-interface modules))
        m))

Now we can:

    (eval '(+ 1 2) (environment '(guile))) => 3

The environments returned from 'environment' are mutable, but unique:

    (define e1 (environment '(guile)))
    (eval '(define x 'x) e1)
    (eval 'x e1) => x
    
    (define e2 (environment '(guile)))
    (eval 'x e2) ;ERROR: Unbound variable: x

> I'm sure that this is possible in Guile, but I got tired of reading
> through the source files to hunt down undocumented function that do
> what I need [1].

I sympathize. :-) Racket has a ton of personpower behind it, which other
Scheme implementations often can't compete with...

> [1] Another recent incident: How do you programmatically list all of
> the variables in a module?  You search the web, find
> http://www.draketo.de/proj/guile-basics/#sec-3-2, see a a reference to
> module-map, which doesn’t exist in the documentation, dig it up in the
> source to see its arguments, etc…

Indeed, Guile's module API in particular is badly documented.  Maybe
I'll work on it in the coming weeks; I'll have some spare time.

In case you're still interested though, here's how I quickly found out
how to use module-map in Guile's REPL:

    scheme@(guile-user)> module-map
    $7 = #<procedure module-map (proc module)>

This tells me it takes two arguments: a procedure and a module.  Let's
see what arguments it passes to the procedure:

    scheme@(guile-user)> (module-map (lambda args 
                                       (display args)
                                       (newline))
                                     e1)
    ;; output:
    (x #<variable 1e45640 value: x>)

(Reusing the 'e1' from the previous example.)

So proc is called with a symbol that's the variable's name, and a
variable object.  Those are documented in: (info "(guile) Variables")

It's noteworthy also that imported modules' variables aren't listed;
otherwise all of (guile)'s variables would have been listed too.

Taylan



reply via email to

[Prev in Thread] Current Thread [Next in Thread]