> The optimal solution, then, is for the compiler to be smart enough to recognize that there's a guard and to preemptively enforce it at each callsite.
It sounds to me like you are describing static typing. As far as I know, type inference from patterns and guards is one of the features of the static type system being developed for Elixir right now [1].
> Hell, the even-more-optimal solution would be to not need the guard in the first place, since the * operator already implies an is_number(num) constraint.
The most optimal solution in my opinion would be a type annotation for the function, so that you do not need to write a guard which adds a runtime overhead just to verify a type that you know you want to always be the same anyways is correct.
Type inference from the `*` operator sounds interesting, unfortunately unlike other languages (like Gleam which has *. +. etc.) Elixir does not have a separate set of operators for floats and integers, so you would not be able to infer which type of number the variable needs to be.
If it were up to me, Elixir would not have pattern matching via functions and instead allowed for type annotation in the function head, I think the matching with multiple function clauses is a lot less readable than just having one function with a big case statement at the top level – of course no way that will change, it is how it is.
> Elixir does not have a separate set of operators for floats and integers, so you would not be able to infer which type of number the variable needs to be.
Elixir doesn't care; it'll convert to a float if necessary (namely, if one of the arguments is a float):
iex(1)> 1 * 1.0
1.0
This is identical to the behavior of e.g. Julia:
julia> 1 * 1.0
1.0
> The most optimal solution in my opinion would be a type annotation for the function
My point is that the type annotations are redundant, at least in this particular case; the acceptable types are already obvious from the function definition itself.
It sounds to me like you are describing static typing. As far as I know, type inference from patterns and guards is one of the features of the static type system being developed for Elixir right now [1].
> Hell, the even-more-optimal solution would be to not need the guard in the first place, since the * operator already implies an is_number(num) constraint.
The most optimal solution in my opinion would be a type annotation for the function, so that you do not need to write a guard which adds a runtime overhead just to verify a type that you know you want to always be the same anyways is correct.
Type inference from the `*` operator sounds interesting, unfortunately unlike other languages (like Gleam which has *. +. etc.) Elixir does not have a separate set of operators for floats and integers, so you would not be able to infer which type of number the variable needs to be.
If it were up to me, Elixir would not have pattern matching via functions and instead allowed for type annotation in the function head, I think the matching with multiple function clauses is a lot less readable than just having one function with a big case statement at the top level – of course no way that will change, it is how it is.
[1] https://elixirforum.com/t/full-static-type-inference-of-set-...