Author: James Hague <james(dot)hague(at)gmail(dot)com>
Status: Draft
Type: Standards Track
Created: 18-Feb-2009
Post-History:
Typechecking guards (e.g., is_float/1
) are useful for a number of
reasons, but they're verbose. I propose allowing multiple
parameters to the is_
famility of functions, which
significantly reduces source code bulk in common cases.
Where is_type
represents any of the is_
family of functions,
such as is_float
:
is_type(A, B, C, ...)
is equivalent to (is_type(A) andalso
is_type(B) andalso is_type(C)...)
.
The is_type functions can now take from 1 to N parameters, where N is the implementation defined limit on function arity.
The old-style guards (e.g., float/1
) would not change, as some of
those serve double duty as typecasts.
Direct references to these functions in the erlang module are for
the single parameter versions only (such as fun
erlang:is_float/1
).
I find myself adding typechecking guards not only for safety, but
to improve code generation quality, especially when using floats.
Writing three or four element vector math functions in Erlang,
with is_float
guards, is verbose. The is_float
checks dwarf what
would otherwise be a single-line function by adding multiple lines
of guards.
Here's an example from the Wings3D project:
cross({V10,V11,V12}, {V20,V21,V22})
when is_float(V10), is_float(V11), is_float(V12),
is_float(V20), is_float(V21), is_float(V22) ->
{V11*V22-V12*V21,V12*V20-V10*V22,V10*V21-V11*V20}.
The is_float
checks significantly improve the quality of the
generated code, allowing floats to be kept in virtual machine
registers instead of allocated on the heap. If multiple
parameters to is_float
were allowed, this code could be
rewritten as:
cross({V10,V11,V12}, {V20,V21,V22})
when is_float(V10,V11,V12,V20,V21,V22) ->
{V11*V22-V12*V21,V12*V20-V10*V22,V10*V21-V11*V20}.
In the second version, the intent is clearer at a glance, and the source-level weight of adding typechecking doesn't overwhelm the function.
Over the years the the Erlang system has become more reliant on typechecking. There are the dialyzer and typer tools. The compiler can statically infer types and generate better code as a result. Making typechecking guards be lighter-weight at the source code level encourages their use and is more in-line with the overall syntactic density of the language.
All uses of the is_type/1
functions will still work if this
proposal were implemented. Direct references to
erlang:is_float
, erlang:is_atom
, etc., as funs will still work
as originally intended.
None.
This document has been placed in the public domain.