New candidate JEP: 429: Extent-Local Variables (Incubator)

Andrew Haley aph-open at littlepinkcloud.com
Wed Aug 17 08:40:12 UTC 2022


On 8/16/22 20:22, John Rose wrote:
> I’m very glad to see this moving towards completion.
> Better threads richly deserve better thread locals!

Thanks, nice to know.

> I’d like to check my understanding of the intermediate
> type |Carrier|. Is it the case that the information content
> of a carrier made by |c=ExtentLocal.where(k,v)| is just exactly
> the pair |k,v|?

Yes.

> And then, after that, I suppose a carrier made
> by |c.where(k2,v2)| contains exactly |k,v,k2,v2|. (But if
> |k==k2| then the information content is just |k2,v2|.)

In effect yes, except for liveness.

> And if that is true, then I can store a |Carrier| in a global
> variable, even pass it to five other threads, and have each
> of them call |c.run(…)| with completely independent sets of
> bindings, except for the |k,v,k2,v2| mandated by the carrier’s
> information content.

That's the idea. There is some cost to creating a Carrier, so it might
make sense to share Carrier instances between related contexts.

> What I’m trying to exclude here is that a |Carrier| somehow
> threads in the ambient binding map for the current extent,
> as non-locally defined by all of the caller frames, plus
> whatever bindings might have been provided when the current
> thread was launched.

It doesn't do that: the Carrier doesn't inherit anything from the
environment.

> IIRC you have chosen not to provide general methods for working
> with binding maps. (There is no key/value iterator on |Carrier|.)
> And then reifying the very special binding map in the current
> extent is right out.

I did have that, and it could have been useful for (e.g.) general
inheritance by fork/join tasks, but it was taken out. That was because
it was thought useful to be able to guarantee that when a binding
extent ends, no other thread hangs on to the bindings. That is to
say, extent-local bindings are bounded in both time and space.
I still think it might be useful to be able to snapshot the current
state.

> I think this is fine, although maybe use
> cases will eventually call for map-like views on both local
> carrier multi-tuples and grand non-local binding maps. Those
> can be added later if needed.
> 
> So, my asking to confirm the very finite and local information
> content of the type |Carrier| is really me double-checking
> that no larger binding-map API sneaks through the current JEP
> API.

Worry not! It doesn't.

> A very different design would sneak in an reified map pointer
> into every result of |c=ExtentLocal.where(k,v)| such that
> bindings available in |c.run(…)| would come only from c
> and its uplevel pointer, completely blocking any bindings
> present at the call to |c.run|. I guess such bindings would
> no longer be properly called “extent-local”; only the binding
> map root would be extent local but it would be subject to
> radical editing on each call to |c.run(…)|.
> 
> Make sense?

I guess, but that sounds a little more complex.
  --
Andrew Haley  (he/him)
Java Platform Lead Engineer
Red Hat UK Ltd. <https://www.redhat.com>
https://keybase.io/andrewhaley
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671


More information about the loom-dev mailing list