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 #5234

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

Extending the pure annotation for functions #5234

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.

@alexlamsl
Copy link
Collaborator

That's what pure_funcs does:

$ cat test.js
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);
$ uglify-js test.js --compress toplevel,pure_funcs=addTwo --beautify
function addTwo(number) {
    return number + 2;
}

var y = addTwo(2);

export {
    y
};

@skyrpex
Copy link
Author

skyrpex commented Dec 24, 2021

Thanks for suggesting pure_funcs (didn't know it existed) although I find it lacking/unconvenient on several areas, specially for modern development (thinking about packages and modules). I'd love if we could discuss it further, even if it's just to talk about theoretical pros/cons. I'm pretty sure there's still lots of room for improvement nowadays.

Why I think reading a function annotation would be good:

  • It's more handy to be able to annotate your function rather than passing function names to the CLI. Whatever is written directly with the code is more reliable and less prone to become outdated
  • The CLI option uses raw function names. There's many corner cases for non-trivial examples: what about different functions that are named the same? What about functions that are enclosed in other scopes? What about functions from packages fom another authors? I don't know their codebases, but they do, and they can write some annotations on their own code

Now, I have no idea how hard would be to implement this annotation into UglifyJS, but it seems it shouldn't be a huge deal if it already produces an AST?

What do you think?

@skyrpex
Copy link
Author

skyrpex commented Jan 3, 2022

@alexlamsl mentioning you just in case you didn't see the notification

@aleclarson
Copy link

aleclarson commented Jun 4, 2022

Hey there, Uglify team! 👋

Please consider adding support for granular function purity (via @__PURE__ annotation). The pure_funcs option is an Uglify-specific solution, but both Rollup and Esbuild are deferring to you in regard to the @__PURE__ annotation feature. If you implement it, so will they.

Rollup's lead maintainer: rollup/rollup#2960 (comment)

The intention at the moment is to match what UglifyJS does as closely as possible, as it is basically an Uglify syntax we are using here. So if we extend semantics from our side, the annotations will only work for Rollup builds but not be respected by any other bundler or minifier.

Esbuild's creator: evanw/esbuild#1883 (comment)

There is no formal specification but I believe this convention was originally developed by UglifyJS: #1448. So it should work however they have made it work.

Fábio, a maintainer of Terser, also expressed interest in this extension of @__PURE__ annotations:
terser/terser#1130 (comment)

@jfmengels
Copy link

I made an other issue for this feature with a more detailed breakdown of motivation and benefits #5614.
(I don't think continuing the discussion in a closed issue will lend itself to the feature being re-evaluated)

@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.

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