unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: Andy Wingo <wingo@pobox.com>
Subject: Re: Req for help on objects and environments
Date: Fri, 03 Sep 2004 19:46:49 +0100	[thread overview]
Message-ID: <1094237209.3785.48.camel@lark> (raw)
In-Reply-To: <1094027329.4057.78.camel@kuzgun>

Hi Alp,

I know you've got a lot of answers already, but I think the environment
question is still not covered.

On Wed, 2004-09-01 at 11:28 +0300, Alp Öztarhan wrote:
> First, I want to play with the properties on objects.
> I want to be able to serialize an object along with its properties.
> I *can* make and retrieve properties of objects by use of
> (make-object-property). But how do I get a list of the properties of a
> given object?

In case you didn't figure it out, you can't, except from C with
scm_properties_whash.

> Second, I want to manipulate the environment in eval.
> I could not even do what the documentation tells.
> I could not get a handle on (null-environment) etc. (undefined symbol
> :-(
> Besides, I want to manipulate it, giving extra symbols etc.
> Could anybody give me any hint on these?

Sure. Scheme actually has two kinds of environments: toplevel and
lexical. The first is a simple association of names and values. The
concept is very similar to that of "modules", so in guile, toplevel
environments *are* modules[0]:

	(module? (null-environment 5)) => #t

By default, guile is not r5rs-compliant when it loads up. I think this
is because (ice-9 syncase) is very slow to load up. Anyway, using
(ice-9 r5rs) will give you everything in the report, including
null-environment.

Modules are what can be passed as the second argument to `eval'. They
should be accessed only with documented functions for maximum
portability between guile versions, and to other schemes. Unfortunately,
modules expose their guts too much because everyone sees boot-9.scm.

So, to opaquely add a:=5 to a module, you can say:

	(define env (null-environment 5))
	(eval '(define a 5) env)
	(eval 'a env) => 5

If you feel more dangerous, you can use module-define, module-defined?,
module-ref, module-variable, etc. See boot-9.scm for more. Dunno what
Marius thinks about this, but I like first-class modules :)

[0] This is complicated by the existence of environment SMOBs, from
environments.c / environment-*. I have no idea whether this code is on
the way in, or the way out. Marius, Dirk?

Lexical environments are a different beast. You cannot access them with
r5rs, I don't think. However, with guile you can, although it's
definitely not documented. I tried to be less hacky with the following
macro, but define-macro's memoizing behaviour caused guile 1.6 to
segfault, so I had to use low-level macros:

(define make-environment
  (procedure->syntax
   (lambda (exp env)
     (local-eval `(let* ,(let lp ((in (cdr exp)) (out '()))
                           (if (null? in)
                               (reverse out)
                               (lp (cddr in) (cons
                                              (list (car in) (cadr in)) 
                                              out))))
                    (the-environment))
                 env))))

;; e.g.
(make-environment a 5 b 6 c a)
=> <a lexical environment with a=5, b=6, c=5

This environment is created with let*, so later bindings can access the
values of previous ones. `the-environment' is a syntax that returns the
current lexical environment. local-eval is a form of eval that takes a
lexical environment instead of a toplevel. Indeed, the `env' argument to
a low-level macro is a lexical environment.

Then,

(define-macro (with-environment env . body)
  `(local-eval
    ,(list 'quote `(begin ,@body))
    ,env))

(with-environment (make-environment a 5)
   a) => 5

(define (bind sym val env)
  (if (defined? sym env)
      (begin (local-eval `(set! ,sym ',val) env)
             env)
      (local-eval `(let ((,sym ,val)) (the-environment)) env)))

There's more in (soundscrape environments), in my arch repository. I
wrote this when I just started with guile; the pattern of lexical
environments applied to a problem I had. Now I worry about the low-level
access. A problem for later, I guess...

Hope that helped,
-- 
Andy Wingo <wingo@pobox.com>
http://ambient.2y.net/wingo/


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user


  reply	other threads:[~2004-09-03 18:46 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-09-01  8:28 Req for help on objects and environments Alp Öztarhan
2004-09-03 18:46 ` Andy Wingo [this message]
2004-09-06  6:17   ` tomas
2004-09-21 20:47   ` Marius Vollmer
2004-09-22 17:07     ` Andy Wingo
  -- strict thread matches above, loose matches on Subject: below --
2004-09-02 11:09 [Fwd: Req for help on objects and environments] Alp Öztarhan
2004-09-02 11:53 ` tomas
2004-09-03 19:10   ` Req for help on objects and environments Andy Wingo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1094237209.3785.48.camel@lark \
    --to=wingo@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).