Skip to content
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

Extending the pure annotation for functions #1130

Open
skyrpex opened this issue Dec 24, 2021 · 6 comments
Open

Extending the pure annotation for functions #1130

skyrpex opened this issue Dec 24, 2021 · 6 comments

Comments

@skyrpex
Copy link

skyrpex commented Dec 24, 2021

Currently, the /* @__PURE__ */ annotation must be used individually on every returned value for a given call.

Could it be possible to allow using the annotation on a function, so all its executions and returned values are considered pure? Like in the following.

/**
 * The function is pure, so if the result is not used, it can be removed.
 * 
 * @__PURE__
 */
function addTwo(number) {
    return number + 2;
}

// Will be removed
addTwo(4);

// Will be removed
const x = addTwo(3);

// This will be kept
export const y = addTwo(2);

I started the same discussion on the esbuild repository, which leaded me here since @evanw prefers not to do any takes unless they are a standarised feature.

Also, there's the same discussion in the UglifyJS repository.

@fabiosantoscode
Copy link
Collaborator

I've had the plan to do this for a while, but it has to be done carefully so as to not confuse other software using this. These annotations have caused a bunch of problems WRT parentheses and other inconsistencies.

IMO it wouldn't be humans actually writing this, but instead compilers.

For this to be implemented safely, it needs to precede a function statement or variable assignment with a function as its sole value. export function and export const/var/let would be acceptable too. Additionally it could precede an imported symbol.

Any other case would get quite hairy.

@aleclarson
Copy link

aleclarson commented Jun 4, 2022

to not confuse other software using this

How would it confuse other software? For bundlers like Rollup that support pure annotations, it's a no-op when you use a pure annotation on anything but a CallExpression or property access.

Additionally it could precede an imported symbol.

Seems unnecessary to me. Let's keep the scope as small as possible so other tools can implement it easier.

See mishoo/UglifyJS#5234 (comment) for more details.

@skyrpex
Copy link
Author

skyrpex commented Jun 2, 2023

Google Closure has a better solution for this problem than a pure annotation for functions. They do have a @nosideeffects annotation.

@nosideeffects indicates that a call to the declared function has no side effects. This annotation allows the compiler to remove calls to the function if the return value is not used. This is not a signal that the function is "pure": it may still read mutable global state.

@fabiosantoscode
Copy link
Collaborator

Note: This is being called @__NO_SIDE_EFFECTS__ over at rollup rollup/rollup#5024, Terser should use the same syntax if it implements a similar thing.

@ehoogeveen-medweb
Copy link

Note for anyone wondering (like me): They talk mostly about #__NO_SIDE_EFFECTS__ rather than @__NO_SIDE_EFFECTS__, but terser supports both prefixes (of course, not __NO_SIDE_EFFECTS__ itself yet).

@skyrpex
Copy link
Author

skyrpex commented Jun 7, 2023

Note for anyone wondering (like me): They talk mostly about #__NO_SIDE_EFFECTS__ rather than @__NO_SIDE_EFFECTS__, but terser supports both prefixes (of course, not __NO_SIDE_EFFECTS__ itself yet).

The feature in Rollup includes both # and @ prefixes 👍🏻

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants