Add pure function modifier, build Hoogle equivalent

It would be cool to allow pure function modifier that would guarantee that function can't modify its arguments and doesn't use anything from its closure.

Performance win is that you could nest function inside function without need to redefine?

Bigger win is that we could build a repo of all pure functions available in OSS and easily reuse these in different projects. One could build npm of functions instead of repos which would guarantee more flexibility and also would be easy to measure how often given function is used and propose it with tooling. Think about this and please implement. So something like https://hoogle.haskell.org/ but with suggestions from code editor ala copilot. Not to mention this data (pure functions) is needed to train Diffuser that can edit and modify code. Microsoft that's free idea for you to get money so please implement this. Thanks.

Do you really mean this?

e.g. I can't use an imported value, like this:

import { helperFn } from './elsewhere';

export pure function doThing(x, y) {
  return helperFn(x) + y; // Illegal - I'm using `helperFn()` from the closure.
}

And I can't reference other functions, like this:

pure function helperFn(x) {
  return x + 1;
}

pure function doThing(x, y) {
  return helperFn(x) + y; // Illegal - referencing helperFn(), which is found in the closure
}

I also can't use constants, like const MAGIC_NUMBER = 234, that could be found at the module level.

A constraint this tight would make these pure functions nearly useless, but it's also difficult to lighten this constraint, without allowing the pure function to do impure logic.

Sorry, for the noise, I was drafting a proposal to make this kind of ergonomic and statically checkable the first time a function is called, but this ignored that getters and proxy traps can be impure.

Yes, using other pure functions or constants(not const) should be fine.
Constant defined as basic value (not a string or object).

It could allow strings/object to make it more ergonomic but assumption would be that it auto deep-copies the object when it's used in pure function. (and takes value only from initialization, ignores further modifications).

BTW this repo might be of some help with implementation: GitHub - lukastaegert/eslint-plugin-tree-shaking: Marks side-effects in module initialization that would interfere with tree-shaking

1 Like

(p.s. strings are immutable, just like numbers, so they both could be made exceptions to the "don't access stuff from the closure" rule)

I notice that the link you point to defines a system where you can leave a comment stating "this specific import is pure, trust me". Would you propose that we add something similar?
pro: You can interop with any old JavaScript library that contains pure functions, but have simply not updated to mark themselves as pure.
pro: You can break restrictions if you have to, e.g. perhaps you use memoization for performance reasons which is technically impure, but you may still want outside users to think of your API as pure.
con: It would be easy to accidentally make your function impure while claiming it is pure.

Would you propose that we add something similar?

If that's doable then yes. If I was designing compiler/interpreter I would probably already have that (and would be surprised if V8 or other engines don't have that already to cache for JIT / AoT compilation / reduction to constant.

What I mean this tech probably exists but value isn't well distributed and Hoogle like addition to VSCode and Copilot would distribute it well.

But to not rely on BigCorps monopoly it's better to just add new keyword for that so everyone can built something similar. I mean best it would be to have something like in OCaml that by default stuff is pure but that's not realistic.

What I mean, is that this sort of "this is pure, trust me" comment is, well, built on trust. Someone could easily mark an impute function as pure, and that would allow anyone to use the impure function from a pure function. This means engines can't really know for sure if the import is pure or not, they just know that the end-user is claiming that it's pure (so, engines can't rely on this information for optimization purposes, because it's not necessarily trustworthy).

It's not that different from typescript, where you can say something is supposed to be one type, but at runtime, you give it a value of a different type, and it's perfectly ok with that.

Since you seem similarly minded on the importance of purity, you may like Command Syntax. It addresses the purity concern from the CQS principle perspective.