profile
viewpoint

Ask questionsRefinements should be invalidated by side effects

const a:  { a: string | number } = { a: 'foo' };

function foo() {
  a.a = 1;
}

function test(x: { a: string | number }) {
    if (typeof x.a === 'string') {
      foo(); // this invalidates the refinement
      const a: string = x.a.toUpperCase(); // runtime error
    }
}

 test(a);
JSMonk/hegel

Answer questions vkurchatkin

You are right. There are a couple of thing that can be done

  1. Purity tracking. Functions that are free of side effects should be marked as such. Properties that are definitely not getters.

  2. Visibilty tracking. This is probably very convoluted in practice. The idea is to prove that a given statement can't possible affect a given refinement, because it doesn't see the refined binding or value.

Simple example:

import { foo } from 'foo';

export function test(x: string | number) {
    if (typeof x === 'string') {
       foo(); // foo is from outer scope, so there is no way it can affect x
    }
}

But this will become convoluted very quickly:

import { foo, bar } from 'foo';

export function test(x: string | number) {
    bar(() => x = 1);

    if (typeof x === 'string') {
       foo(); // foo is from outer scope, but current scope has leaked through `bar`
    }
}


useful!

Related questions

No questions were found.
Github User Rank List