stdlib-js / stdlib

✨ Standard library for JavaScript and Node.js. ✨
https://stdlib.io
Apache License 2.0
4.33k stars 441 forks source link

RFC: add support for creating project builds which do not include runtime assertions #208

Open kgryte opened 6 years ago

kgryte commented 6 years ago

Checklist

Please ensure the following tasks are completed before submitting a feature request.

Description

Description of the feature request.

This RFC proposes adding support for creating project builds (most likely "bundles" for use in browser environments) which do not include runtime assertions. Situations where such a build would be beneficial:

In general, runtime assertions should be the default. Their importance in development, testing, and scripting cannot be overstated. However, in certain situations, such as heavily tested applications, removing runtime assertions can be considered permitted and can be beneficial in order to achieve marginal gains in ops/sec.

This RFC proposes to explore

  1. the feasibility of creating such builds
  2. how the process of creating such builds would work
  3. the requisite tooling involved
  4. whether modifications would be required of source implementations

Of note, naive approaches such as, e.g., swapping assertion functions with no-op functions are not feasible due to the variety of uses for assertion functionality (both positive and negative conditionals). However, other, more nuanced (and careful), approaches may be more feasible. For example,

In order to test that runtime behavior is not affected by assertion removal, unit tests should be run over generated builds. However, one will not be able to run the unit tests as is, due to the presence of tests which verify runtime assertion behavior. For testing a generated build, assertion behavior tests must be either disabled or removed altogether.

One possible mechanism for disabling assertion behavior unit tests is via an environment variable, e.g., STDLIB_RUNTIME_ASSERTIONS={0,1}. Then, in unit test files,

var opts = {
    'skip': env.STDLIB_RUNTIME_ASSERTIONS === 1
};

Related Issues

Does this feature request have any related issues?

No.

Questions

Any questions for reviewers?

No.

Other

Any other information relevant to this feature request? This may include screenshots, references, sample output, and/or implementation notes.

No.

rreusser commented 6 years ago

Too much automation seems risky. It seems nearly unavoidable to require a possibly-comment-annotation-based approach anyway, even if only as a fallback (but if it's there anyway, why not always use annotations?)

What do you think of the browserify/envify/uglify approach of process.env substitutions that result in very naively statically analyzable code (e.g if ("foo" === "bar") { ... })? Of course it seems undesirable to couple assertion removal to the build process, but maybe it's not too undesirable to reinvent the wheel a bit to avoid coupling this approach to the build process. Unfortunately that seems to result in custom build tools you'd need to run, but I can imagine that either being exposed as browserify transforms and webpack loaders or just being done internally via rollup, for example, to produce a checked and unchecked dist version.

One note I'll add is that regl adds some custom magic to thread the needle and try to select the best options, but it's been met with a bit of consternation when people realize what's really going on and that it doesn't follow a more predictable pattern. Of course there are Reasons, but since people will no doubt, frankly, probably either be looking to use the dist version or will bundle stdlib via webpack (and its yet-unborn descendants), it's worth considering whether the dev process is reasonable. Which probably means dist/stdlib-unchecked.min.js and dist/stdlib.min.js or something, as well as exposing some tools to produce your own checked/unchecked bundle in realistic use-cases.

rreusser commented 6 years ago

Summarizing more succinctly: this is a user-facing concern so that I think it's more important to consider what end-users need to do to take advantage of it rather than what internal developers need to do to accomplish it (though this should of course be more or less simple and reasonable).