chicken-users
[Top][All Lists]
Advanced

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

Re: [Chicken-users] basic Scheme question


From: Shawn Rutledge
Subject: Re: [Chicken-users] basic Scheme question
Date: Fri, 24 Oct 2008 12:02:52 -0700

On Fri, Oct 24, 2008 at 10:48 AM, Drake Wilson <address@hidden> wrote:
> If you mean "later" as in "after the let", the v doesn't exist anymore.

Well it's not going to be garbage-collected if an accessor is created
inside the let, which can do destructive operations on it later.
Here's a way to make a counter:

#;1> (define (make-counter)
        (let ([v -1])
                (lambda ()
                        (set! v (+ 1 v))
                         v )))
#;2> (define c (make-counter))
#;3> (c)
0
#;4> (c)
1
#;5> (c)
2

Now you cannot access v from top-level, but you can simultaneously
increment and get its incremented value.  The trick is that
make-counter returns a function, as you suggested.  I'm asking why
can't you return a form of the name 'v which is valid only within the
context of the let?

Making an object system is related: again you have something which
encapsulates data, and allows access to the data only through
accessors.  But often this is done using an alist.  I could use an
alist too, but it would be less efficient, and why should I have to
re-create functionality which is one of the most basic features of
Scheme (being able to look up symbols and get values bound to them)
just to confine this functionality to a localized context?

Oh, maybe you are right though: maybe the symbol 'v doesn't exist
anymore, because in the counter example, the accessor only needs to
access the number to which 'v was bound.  So it can replace the symbol
with a reference to the number, and therefore the symbol lookup only
occurs when the lambda is eval'd (the s-expression is converted to a
procedure).  After the binding has been converted to a reference, the
symbol 'v cannot be looked up anymore.  Does that sound right?

> I suspect what you're looking for is something to the effect of thunking
> references between the sides, now; something that would let you do
>
>  (let ((v (client-do (make-thing))))
>      ;; Now v contains a token to an object on the other side.

The entire "let" block runs on the other side.  The server does not
need the object that was created on the client, it just needs a kind
of remote reference or name that can be used to refer to that object.

But, the concept of requiring the server to make up names in order to
be able to access remote objects after having created them may turn
out to be cumbersome, so I was thinking about serializable proxy
objects.  There could be a special writer which converts object
references into these proxies.  The client's REPL uses this writer for
its output, so when the server asks the client for a primitive it is
sent across, but when the server asks to eval something which returns
a non-immediate, it gets back a proxy instead.

That provoked further thought: the direction this is heading is that
destructive operations are to be preferred over pure functional
operations.  So maybe it's the wrong pattern: I was already familiar
with the concept of a proxy object, but there must be a more suitable
pattern for functional programming, so that one side can ask the other
to do functional operations on its behalf without having to always
send the results across the link.  Maybe the thing which is sent
across could be a kind of promise, a way to delay the sending of
results, to keep the results encapsulated on the opposite side as long
as possible until you actually need them to be returned.




reply via email to

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