Thanks, Carl. I appreciate you taking the time to provide such a comprehensive response. Your explantion definitely helps me better understand the nature of this change. I see that more than one static type checker will leverage this, and there is precident (`cast`), so I withdraw my objection. I suspect that `reveal_type` will see very little (if any) use at runtime, and will likely be removed by developers when static type debugging is completed to avoid console noise. If this is not true (if `reveal_type` may be retained in code after debugging) then I think it would actually be better for it to have no runtime behavior (e.g. like `cast`). On Sun, 2022-01-30 at 10:56 -0700, Carl Meyer wrote:
On Sat, Jan 22, 2022 at 3:39 PM Paul Bryan <pbryan@anode.ca> wrote:
FWIW, my objection to adding these to stdlib stands.
Hi Paul,
I reviewed previous threads to try to better understand your objection; I don't want you to feel that it's been ignored. It seems to me that your objection may be based on some misunderstandings of what the proposal is or how it will be implemented. You refer several times to the idea that each type-checker will need to "monkeypatch" the version added to the typing module; this is not the case. Static type checkers don't run the code so they don't need to monkeypatch anything; they will simply provide some static type-checking behavior when they see these functions in analyzing the code (e.g. when they see `reveal_type(x)` during static type-checking they will print the statically-known type of the variable `x`.) In fact they already do this, but the problem is the function doesn't exist anywhere at runtime, so people have to delete the call to `reveal_type()` before they can run the code, and if they want to go back and forth between running the code and static-checking it, but they also want this debug information about the type of `x` in their static check, they are constantly having to add and delete the `reveal_type()` call.
This problem can be solved by placing a common implementation of `reveal_type()` (which in fact has a useful standard runtime behavior -- it will print the runtime type of the variable!) into the `typing` module. Now people can import `typing.reveal_type`, call it in their code, and get useful debugging information both from running the code and from type-checking it.
This is very much in-line with the existing contents and usage of the `typing` module. E.g. `typing.cast()` does nothing at all at runtime, but static type-checkers give it special meaning to change the static type of some expression. Similarly `typing.NewType()` does nothing at runtime, but it's a standardized interface that is given special meaning by type checkers. If your concern is that the contents of the `typing` module should also be useful at runtime, then you should be more pleased with `typing.reveal_type()` than you are with the existing `typing.cast` and `typing.NewType` -- at least `typing.reveal_type` has a useful and obvious runtime behavior that parallels its static-typing-checking behavior!
Please let me know if I've missed something important about your objection. If you still feel there is a problem here, it might help clarify if you can give a specific example of how the addition of e.g. `typing.reveal_type` to the stdlib will harm a use case that you care about.
Carl