JEP draft: Scope Locals

Brian Goetz brian.goetz at oracle.com
Fri May 14 14:45:15 UTC 2021


Its simpler than you're making it.  Think of the motivating use cases 
for ThreadLocal, such as when a container calls into user code, and the 
user code calls back into the container, and we need to keep track of 
{transaction, security, etc} context, and it is impractical to pass them 
all through as parameters, or enumerate the possible callbacks.  The 
motivation here is the same; while the model is constrained, which 
eliminates some of the ways TLs are used today, these are "better TLs 
for better threads".  (If you believe that the motivation here is 
"poorly written libraries", then you believe that all libraries and 
frameworks that use TL are also poorly written.)

Where I think the JEP draft (the exposition, not the feature design) 
could be improved is to make the relationship to TL more clear.  IMO, 
this is a "more modern" TL design; it addresses the same primary use 
cases, without the unconstrained mutability of TLs.  The safety that 
comes from the immutability enables some new concurrent patterns (e.g., 
structured concurrency) and some nice optimizations.

On 5/14/2021 8:51 AM, Alan Snyder wrote:
> The essence of the example seems to be that the callback is supporting multiple client contexts and when called needs to act relative to the specific client context.
>
> The callback does not get a parameter identifying the client context because the library that calls it does not know anything about these client contexts.
>
> Effectively, the callback uses the calling thread as a way to identify the client context.
>
> That is not new. The ability to shadow/snapshot appears to be new, but it is still based on the thread as the ultimate context identifier.
>
> Did I get it right?
>
> If so, perhaps it would be less confusing if “Scope Locals” instead were called “Scoped Thread Locals”.
>
>
>
>
>
>> On May 14, 2021, at 1:28 AM, Andrew Haley <aph at redhat.com> wrote:
>>
>> On 5/13/21 4:59 PM, Alan Snyder wrote:
>>>
>>>> On May 13, 2021, at 2:03 AM, Andrew Haley <aph at redhat.com> wrote:
>>>>
>>>> On 5/12/21 8:12 PM, Alan Snyder wrote:
>>>>>  From the motivation section:
>>>>>
>>>>>> So you want to invoke a method |X| in a library that later calls back into your code. In your callback you need some context, perhaps a transaction ID or some |File| instances. However, |X| provides no way to pass a reference through their code into your callback. What are you to do?
>>>>> When I read this, my first thought was… pass a callback that is bound to the context.
>>>>>
>>>>> I suppose the example you have in mind has a fixed callback.
>>>> Fixed? It's a callback, of some form.
>>> What I meant was that the callback has a larger scope than the method call. Otherwise, you could bind the context to the callback object.
>> I don't know quite what you mean by "larger scope," but clearly, if you
>> can explicitly pass a callback created by a lambda, that's a more explicit
>> solution.
>>
>>>>> Is this a common practice? Doesn’t it point to a deficiency in the library API?
>>>> Not necessarily. For example, say you want to give access to a particular
>>>> resource (a log stream, say) to trusted callees. Nobody AFAIK passes a log
>>>> stream as an explicit argument through business logic because that's just
>>>> too much clutter.
>>> That sounds interesting, but I’m not following how scope locals would be used to solve this problem.
>> In the outer scope you bind a logger scope local, and all transitive callees
>> can use that.
>>
>> -- 
>> 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