bruant.d at gmail.com
Tue Jan 22 13:34:32 PST 2013
Le 22/01/2013 15:59, Jason Orendorff a écrit :
> A) Are there more WeakMap applications that will want .clear() or
> applications that will want .clear() not to exist? Offhand I would bet
> on the former, by a landslide, but if you think otherwise, or if
> there's some other reason to privilege .clear() not existing, let's
> talk about that.
> Having said all that, I bet we could hack around the worst-case GC
> performance. It'll be a pain, but GC is like that sometimes. This
> decision should hinge on what provides the best API for developers. I
> think we mainly disagree on what developers want, which is a great
> thing to talk about. Let's talk about that.
I agree use case dominant is a crucially important answer. To date, I
honestly don't know which case of want-clear and don't-want-clear would
be dominant. I agree Allen showed a compelling use case but I can't
judge how important it is. In my experience, I've not had the need for a
.clear yet. I know that in some occurences, my code relies on the
weakmap not being emptied, but I've kept the weakmap well-encapsulated
in these cases so this experience is not that relevant (because
intrusive .clear can't happen).
I've written a whole paragraph which is the most factual I can say on
the topic, but doesn't help the debate much.
When it comes to feelings, I prefer prudence by default. I'd like to say
a few words about that. I understand that features shouldn't be seen
only with ocaps eyes, but I'd like to take a moment to describe what I
care about when it comes to ocaps and what we call "security".
Node.js is an interesting ecosystem. There are a lot of modules, it's
not unusual to use 10-20 modules in a project which can make 100+
modules when counting recursively. Because it costs a lot of time, it's
not possible to rewrite everything, it's not possible to contribute the
necessary test coverage to modules and it's not possible to do careful
security reviews of all used modules (and updates!).
However, it's possible to apply POLA (Principle Of Least Authority),
that is give to each module the information and capabilities it needs to
do its job and no more. If WeakMap.prototype.clear gets natively in the
language, it means *all* modules can have an irrevocable right to flush
any weakmap I hand them.
It's the same sort of problem than if a "free" operator was brought to
suggested once  (almost ironically by Node's lead?). Suddenly, a
module could free objects you hand out to them. A module thinks it's
freeing one of it's own objects but actually frees one of yours because
of a bug? Too bad, you'll be throwing a TypeError very soon and who
knows in which state it will leave your application.
Dave Herman made an equivalent case about coroutines . It provides
abusive authority: you call a module-imported function and for whatever
good or bad reason, it can suddenly stop the stack. It makes your code
harder to reason about because when you wrote the code, you probably
expected the function call to return (or throw).
Back to weakmaps, the issue here is not technical, but... cultural I
would say. I can decide to encapsulate my weakmap in a
WeakMapWithoutClear, but doing so, I cut myself from modules which take
.clear for granted. A module does rely on WeakMap clearbility? It will
hand me the weakmap I'm supposed to use and I know in advance anything
can happen, because I didn't create this object.
If weakmaps don't have a clear, modules using language weakmaps won't
take it for granted and you can be fearless about sharing your
weakmap... very much like you can be hand objects today without the
fear of them being free'd by mistake or malice using a free operator.
Since I'm on the topic of language-based abusive authority, I've come
across a case where a logging library would throw at my face  anytime
it would have to log about an object with a cycle in it . Logging
libraries are really not the one you'd expect to throw an error so we
didn't wrap the call in a try-catch. So logging some objects would make
the application crash.
I have come to think that error-throwing with stack-unwinding is an
abusive authority. Especially given that try-catch is an opt-in.
I understand now that silently swallowing errors is not a good idea and
the need to report errors in a different channel than return value, but
I don't think stack-unwinding is a good default for that. Promises show
an interesting model; to keep in mind for another language maybe.
The point I tried to make here is that POLA allows to build applications
using untrusted modules without fearing them and that's really an
excellent property, because we use constantly huge amounts code we don't
necessarily trust or have the time to review or test besides what we
test during the development period.
WeakMap.prototype.clear is at a different scale of "danger" and abusive
authority than a hypothetical free operator or coroutine or abusive
stack-unwinding, but it's an issue of the same family.
Whether the smaller scale of danger makes it acceptable is a good
question. I would answer "no" by default, but I can understand if others
say "yes" for this one. To be balanced with advantages that native
WeakMap.prototype.clear provide which are yet to be accurately determined.
More information about the es-discuss