Hacker News new | ask | show | jobs
by __MatrixMan__ 445 days ago
Do you mean that you're allowed to only use types where you want to, which means maybe the type checker can't check in cases where you haven't hinted enough, or is there some problem with the type system itself?
1 comments

The type system itself is unsound. For example, this code passes `mypy --strict`, but prints `<class 'list'>` even though `bar` is annotated to return an `int`:

    i : int | list[int] = 0

    def foo() -> None:
        global i
        i = []

    def bar() -> int:
        if isinstance(i, int):
            foo()
            return i
        return 0

    print(type(bar()))
So don't do this then? The type system does not have to be sound to be useful; Typescript proves this.
> So don't do this then?

Don't do what?

- Don't write unsound code? There's no way to know until you run the program and find out your `int` is actually a `list`.

- Don't assume type annotations are correct? Then what's the point of all the extra code to appease the type checker if it doesn't provide any guarantees?

Don't do this stupid party trick with `global`.

You may as well argue that unit tests are pointless because you could cheat by making the implementations return just the hardcoded values from the test cases.

This isn't a "party trick" with `global`, it's a fundamental hole in the type system:

    class C:
        def __init__(self) -> None:
            self.i : int | list[int] = 0

        def foo(self) -> None:
            self.i = []
        
        def bar(self) -> int:
            if isinstance(self.i, int):
                self.foo()
                return self.i
            return 0

    print(type(C().bar()))
This seems to work in TypeScript too:

    class C {
        i: number | number[];

        constructor() {
            this.i = 0;
        }

        foo(): void {
            this.i = [];
        }

        bar(): number {
            if (typeof this.i === 'number') {
                this.foo();
                return this.i;
            }
            return 0;
        }
    }

    console.log(typeof new C().bar());
It seems to be a problem with "naked" type unions in general. It's unfortunate.