-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
meta annotation request: sideEffects #35513
Comments
I have to question the value of this. Even if this annotation existed, I don't think analyzer could reasonably assume that all existing code had been updated to mark all getters that have side effects with this annotation. And no, users can't necessarily add the annotation because they might not own the code to which the annotation would need to be added. How often are users running into this issue? |
I think the only case where we've run into this in real life is when examining unnecessary_statements for internal use. I haven't seen specific calls for this otherwise. If this annotation existed, then anyone running into a false positive in their own code, wanting to avoid it, has a path to success: add the // TODO(user): Remove this directive when `bar.getThing` is marked as having @sideEffects.
// https://github-url
// ignore: unnecessary_statements
bar.getThing; And that comment can be removed in your code and other code which calls It would be a shame to block helpful analysis (in, for example, unnecessary_statements, join_assignment_with_return, cascadable_invocations, prefer_conditional_assignment) for the <1% of getters with side-effects (@davidmorgan I think analyzed internal code against the unnecessary_statements rule... and found very few affected intentional side effects). |
To echo an internal thread: the concept of a side-effect is somewhat debatable. For example, is pure memoization on top of immutable values a side-effect? To most users it's not, and annotating a getter with Or consider something like MobX, where memoization leaves an outside trace of it being a dependent of other values. It would also have to be transient. If I depend on something that has Overall, I think an // ignore comment with a proper justification at the call site is better than this annotation at the source. |
I'm also fine with the idea of having a policy in the linter that says all property access is assumed to be pure, without side effects, and users just have to |
To make sure we're all on the same page: The request is not to make I do think that the definition is the right place to document this. It's an expression that the API is intended to be used for it's side effects. If the author did not intend for the getter to be called for it's side effects then an We currently (hopefully) express the side effects of a getter in the doc comment. An annotation that the linter can understand seems like a strict improvement to me.
That's certainly true but I don't think it should stop us from using it on the code where we can control whether the annotation is added. |
If I saw this annotation with the proposed name I would assume that the analyzer would fail on getters with a side effect that don't have the annotation. If that's not the intent, I think it should have a different name. |
SIde-effects in a getter is an anti-pattern (most people assume they won't modify the object or mutable state), so why not just discourage it even more, rather than enable it like this? I'd rather change the getter to a function with a name that documents its side-effect, than have even more annotations to mark this as a deliberate bad design. |
When we looked at getters across google3 in the context of The obvious question is, if the side effects are not visible, why would you want to trigger just the side effect in a way which would trigger a lint? The answer, which we did see in practice, is for precaching/loading, testing and benchmarking. As Sam mentions there is a general feeling that to get the most value from lints we should have it be possible to have them be enforced 100% without needing At first glance I don't think So how about a |
I think @natebosch and @davidmorgan make good points that it is not common to depend on the side effects of a rare getter with side effects. So the cases we saw were not that a caller always depended on a getter for its side effects, but that, in a small number of case, it did. So the only times a In which case I like @davidmorgan's suggestion to put a |
If no objections to a |
SG, let's discuss over there. Thanks!
…On Wed, 9 Jan 2019 at 23:12 Sam Rawlins ***@***.***> wrote:
If no objections to a justForSideEffects in pedantic, I'll go ahead and
close this in favor of that.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#35513 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AFR8mMYeKUAQ2XLU5QFwQfJty01TmCK7ks5vBmlQgaJpZM4ZkPo1>
.
|
Opened googlearchive/pedantic#13 |
I'd like a new class in the meta package, SideEffects, and a new top-level const instance of that class, sideEffects.
This fellow could be used to annotate a getter [1], indicating when a getter has side effects. Any static analysis rules (including lint rules), can then be written to "safely" assume that any property access or prefixed identifier has no side effects. I say "safely" because any time a confused developer sees a static analysis report and says "oh that's not right at all," they can add this
@sideEffects
annotation to a getter, which the rule can use to not generate false positive reports.For example:
Each of these four lint reports are incorrect, as
get A.b
has side effects. We've seen real code in, e.g. caching modules that have to ignore these reports.[1] why just a getter? Meh, I'd be happy to open this up to more node types, but I've only thought of uses for getters for now.
The text was updated successfully, but these errors were encountered: