As a library author, I am aware of my users having a good no-warning experience, and the current implementation of how warnings regarding gradual type checks are reported now drives me bonkers.
In my library Tempus
I have several guards allowing date(-time) comparison with calendars in mind. Let alone different calendars (which work to some extent,) it’s optimized for cases when both calendars are Calendar.ISO
.
To calculate the difference between two datetimes in a guard, I need to deal with leap years/seconds, and the only way to do so in a guard is to lookup the compile-time map for the elapsed amount of days.
The newly introduced type warnings blow in the face of my users with
[…]
:erlang.map_get(:erlang.map_get(:month, :erlang.map_get(:to, s2)), %{
1 => 0,
2 => 31,
3 => 59,
4 => 90,
5 => 120,
6 => 151,
7 => 181,
8 => 212,
9 => 243,
10 => 273,
11 => 304,
12 => 334
}) * 86400
Conflict found at
lib/guards.ex:637: Tempus.Guards.joint_in_delta?/3
warning: expected Kernel.*/2 to have signature:
dynamic(), true | false | float() | integer() -> integer() | float()
but it has signature:
integer(), integer() -> integer()
float(), integer() | float() -> float()
integer() | float(), float() -> float()
The values of this map are integers, the map itself is a compile-time beast, but the warning still exists.
So instead of providing a pull request to fix this case when the type might be easily derived from the set of map values, I wonder if library creators can explicitly tell the type checker, hey, I know what’s going there, please, don’t overreact.
Thanks!