This is the mail archive of the kawa@sources.redhat.com mailing list for the Kawa project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Gargage collected top-level bindings?


I understand the dilemma, and I hope I didn't give the impression that
I was trivializing it, or disparaging the amount of thought and work
you've put into it so far.  I'd be quite surprised if anyone's thought 
about this more than you have.

Unfortunately I have a plane to catch soon, so I won't be able to give
it much thought until next week.  But my initial, hasty impression is
that name resolution in Kawa should eventually include:

  - searching the current lexical environment
  - searching the Java instance chain from "this" object through supers
  - searching the Java static class chain from this class to Object.class
  - searching the current dynamic environment
  - (possibly) searching some overall global environment

I feel like I'm missing at least one search path, but no matter.
My naive take on it is that you'd want to search all these environments
for any given binding, in some well-defined order.  Is that a reasonable
way to look at it?

One possible design might be to have both dynamic and static
environments inherit from a top-level environment.  Static environments
would inherit bindings from the current file (or lexical module; I'm
unfortunately not super clear on the file/module distinction in Scheme.)
Dynamic environments would inherit back up to the top-level environment
in the file where the thread or fluid binding was created.

So positing modules A and B, if I create thread T in A, and it invokes
a function defined in module B, then name resolution would search the
lexical environment chain up to B's top-level, and the dynamic environment
chain up to A's top-level.  I have no opinion as to whether the dynamic
or static chain would be searched first, as long as it's well-defined.

That may be an awful solution.  It's just a suggestion to give the
flavor of how I might approach figuring out the Right Thing in Kawa's
admittedly complicated situation.  I don't know whether top-level
bindings are generally shared in one global top-level environment, or
if they're separate "top-level" environments per file or module.  But
in either case, it seems like reasonable name-resolution semantics
could be defined, as long as you're willing to search more than one
environment chain.

If I'm barking up the wrong tree, please let me know.  Meantime, I'm
going to be late for my flight soon, so I have to run.  I just wanted
to reply to let folks know I'm willing to help figure out a solution,
but that I'm by no means an expert on this stuff.

Cheers,

-steve

p.s. I agree that any solution with different semantics for initialization
and assignment would probably be just as awkward.

On 5/5/05, Per Bothner <per@bothner.com> wrote:
> Steve Yegge wrote:
> > Java and Scheme programmers alike seem to expect top-level bindings to
> > act like Java instance variables, as if the file contents were contained
> > within a single Java class.
> 
> I don't think it's that simple.  The Scheme top-level environment is a
> *dynamic* environment.  Consider the opposite situation: when a module
> references a variable which is *not* statically visible.  Also, if a
> module does define a binding, when is it visible to other modules?
> 
> Also consider fluid bindings.  They are inherently dynamic.  And once
> you're using dynamic lookup, things are automatically thread-specific.
> 
> > Put another way, people expect them to be lexically scoped to that file
> > (or perhaps module).
> 
> People's expectations are not consistent.  They expect their code to
> "work" but they usually can't clearly specify what they want, or see
> the implications.  The situation is complicated by the lack of either
> threads or modules in R5RS, so we have to work out what makes most
> sense.
> 
> > This is the way it has worked historically in the
> > absence of multiple threads:  you can read and write the bindings from
> > any function defined in the file, e.g.:
> >
> > (define my-toplevel-var 10)
> >
> > (define (my-function)
> >   (set! my-toplevel-var
> >       (+ 1 my-toplevel-var)))
> >
> > Kawa recently changed so that the my-toplevel-var binding is not
> > accessible to another thread entering my-function.  That's confusing
> > and unintuitive.
> 
> It is accessible if the other thread inherits from the initial thread.
> 
> > And finally, as I mentioned before, it's not the way it works in
> > other languages.  So even if Kawa's current semantics for globals
> > are the "right thing" from some internal design perspective, it will
> > continue to be a source of confusion, bugs, and mailing list traffic
> > as long as it remains that way.
> 
> So what is your suggestion?  Note the solution needs to specify how
> fluid binds works.  Another complication is that (load ...) of a
> compiled module should behave similarly to loading a source file,
> and the latter is specified by R5RS.
> 
> > Sharing top-level bindings among threads will of course necessitate
> > user synchronization of those variables.  But Java programmers are
> > used to that, and java.util.concurrent.atomic provides some nice
> > wrappers to simplify the synchronization.
> 
> The issue isn't just synchronization, but what bindings are shared
> between what threads and what environments?
> 
> One possible solution is that initializing a top-level binding sets the
> default binding rather than the current thread's.  But that means that
> initialization and assignment behave very differently, which could
> leadto other weird behavior.  We could also make it easier to share
> environments.
> 
> I agree the current semantics are awkward.  But it's not easy figuring
> out the Right Thing.
> --
>         --Per Bothner
> per@bothner.com   http://per.bothner.com/
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]