Wednesday, June 28, 2023

Fails Static Type Check, but Runs Anyway

Here’s a function that fails a static type check, but has no runtime type error:

(defun foo ()
  (sqrt (if (static-type-check? #’foo)
        "bogus"
        2.0))

I suspect most people that favor static types will argue that this sort of program doesn’t count for some reason or other. I think this is more an example (albeit contrived) of the limitations of static type checking.

4 comments:

Paul Steckler said...

For some programs, it's obvious you won't hit the failing case.

What's worrisome is, for some other program, it's been running for 5 years, and you hit an error that a static type system would have caught. And then your nuclear power plant melts down.

Marten said...

Is this the halting problem for type checkers?

Joe Marshall said...

It isn't quite the halting problem, but you'll run into it quickly if you attempt to make your static type checker "sufficiently smart".

char said...

What exactly is static-type-check? supposed to do? A a sophisticated static type checker would infer that static-type-check? would always return nil.

If there is some definition elsewhere that could indeed return non-nil, then you would get a static type error.

If I assume that static-type-check? somehow actually analyzes the source code of foo, then when foo gets analyzed at type check time, you will be informed (via type error) that your program can be greatly simplified to

(defun foo ()
(sqrt 2.0))

From there you can further simplify to defconstant. Your code will be improved by static analysis whether you like it or not.