<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Oct 16, 2017 at 9:11 AM, Yury Selivanov <span dir="ltr"><<a href="mailto:yselivanov.ml@gmail.com" target="_blank">yselivanov.ml@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Mon, Oct 16, 2017 at 11:49 AM, Guido van Rossum <<a href="mailto:guido@python.org">guido@python.org</a>> wrote:<br>
> On Sun, Oct 15, 2017 at 10:26 PM, Nathaniel Smith <<a href="mailto:njs@pobox.com">njs@pobox.com</a>> wrote:<br>
>> We don't need it to be abstract (it's fine to have a single concrete<br>
>> mapping type that we always use internally), but I think we do want it<br>
>> to be opaque (instead of exposing the MutableMapping interface, the<br>
>> only way to get/set specific values should be through the ContextVar<br>
>> interface). The advantages are:<br>
>><br>
>> - This allows C level caching of values in ContextVar objects (in<br>
>> particular, funneling mutations through a limited API makes cache<br>
>> invalidation *much* easier)<br><br>
> Well the MutableMapping could still be a proxy or something that invalidates<br>
> the cache when mutated. That's why I said it should be a single concrete<br>
> mapping type. (It also doesn't have to derive from MutableMapping -- it's<br>
> sufficient for it to be a duck type for one, or perhaps some Python-level<br>
> code could `register()` it.<br>
<br>
</div></div>Yeah, we can do a proxy.<br>
<span class=""><br>
>> - It gives us flexibility to change the underlying data structure<br>
>> without breaking API, or for different implementations to make<br>
>> different choices -- in particular, it's not clear whether a dict or<br>
>> HAMT is better, and it's not clear whether a regular dict or<br>
>> WeakKeyDict is better.<br><br>
> I would keep it simple and supid, but WeakKeyDict is a subtype of<br>
> MutableMapping, and I'm sure we can find a way to implement the full<br>
> MutableMapping interface on top of HAMT as well.<br>
<br>
</span>Correct.<br>
<span class=""><br>
>> The first point (caching) I think is the really compelling one: in<br>
>> practice decimal and numpy are already using tricky caching code to<br>
>> reduce the overhead of accessing the ThreadState dict, and this gets<br>
>> even trickier with context-local state which has more cache<br>
>> invalidation points, so if we don't do this in the interpreter then it<br>
>> could actually become a blocker for adoption. OTOH it's easy for the<br>
>> interpreter itself to do this caching, and it makes everyone faster.<br><br>
> I agree, but I don't see how making the type a subtype (or duck type) of<br>
> MutableMapping prevents any of those strategies. (Maybe you were equating<br>
> MutableMapping with "subtype of dict"?)<br>
<br>
</span>Question: why do we want EC objects to be mappings?  I'd rather make<br>
them opaque, which will result in less code and make it more<br>
future-proof.<br></blockquote><div><br></div><div>I'd rather have them mappings, since that's what they represent. It helps users understand what's going on behind the scenes, just like modules, classes and (most) instances have a `__dict__` that you can look at and (in most cases) manipulate.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The key arguments for keeping ContextVar abstraction:<br></blockquote><div><br></div><div>To be clear, I do want to keep ContextVar!<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
* Naturally avoids name clashes.<br>
<br>
* Allows to implement efficient caching.  This is important if we want<br>
libraries like decimal/numpy to start using it.<br>
<br>
* Abstracts away the actual implementation of the EC.  This is a<br>
future-proof solution, with which we can enable EC support for<br>
generators in the future.  We already know two possible solutions (PEP<br>
550 v1, PEP 550 current), and ContextVar is a good enough abstraction<br>
to support both of them.<br>
<br>
IMO ContextVar.set() and ContextVar.get() is a simple and nice API to<br>
work with the EC.  Most people (aside framework authors) won't even<br>
need to work with EC objects directly anyways.<span class="HOEnZb"></span><br></blockquote></div></div><div class="gmail_extra"><br></div><div class="gmail_extra">Sure. But (unlike you, it seems) I find it important that users can understand their actions in terms of operations on the mapping representing the context. Its type should be a specific class that inherits from `MutableMapping[ContextVar, object]`.<br clear="all"></div><div class="gmail_extra"><br>-- <br><div class="gmail_signature" data-smartmail="gmail_signature">--Guido van Rossum (<a href="http://python.org/~guido" target="_blank">python.org/~guido</a>)</div>
</div></div>