Skip to content

Instantly share code, notes, and snippets.

YawarRaza7349 /
Created January 20, 2023 22:32
Function Subtyping Doesn't Necessarily Sabotage Parametricity

Three years ago, @hwayne posted A Totally Polished and not-at-all half-baked Take on Static vs Dynamic Typing to his email newsletter. When I first read it, I found it refreshing to read a more balanced programming-related post than I typically encounter, and I also learned some new ideas I'd never heard about before. However, this Gist is not really about all that; it's about one specific statement in the post that is incorrect. The error doesn't affect any of the arguments being made, nor am I criticizing Wayne for the error. Rather, correcting the statement allows me to explain some pretty interesting concepts that might be insightful to some people who read this.

Here is the statement I'll be talking about, along with the context of the statement:

Maybe a -> a is a subtype of a -> Maybe a: anything that typechecks with the latter should typecheck with the former.²

[...] >

The only reason you are able to call Function.prototype.snapshotFunction as Function.snapshotFunction is because Function is itself a function, as are Object, String, Number, and any other JavaScript "class". If you replaced Function with String, this would no longer work. You added a method to all functions and called it on the function instance Function. So if you tried using this, it would reference the built-in Function function. So yes, this should either be a free-standing function, or, if you wanted to make it a method (e.g. getPrimitive.snapshot(["testPrimitive", testPrimitive])), then remove the first parameter of the function, and replace all references to it in the function with this. Speaking of this, I can't think of all the use cases for your function involving this, but with code like this, it's pretty likely this will cause something to break. I found an example here.

IMO, the [string, value, string, value, ...] thing is bad API de