Author: James Hague Status: Draft Type: Standards Track Created: 18-Feb-2009 Post-History: **** EEP 27: Multi-Parameter Typechecking BIFs ---- Abstract ======== 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. Specification ============= 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`). Motivation ========== 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. Rationale ========= 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. Backwards Compatibility ======================= 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. Reference Implementation ======================== None. Copyright ========= This document has been placed in the public domain. [EmacsVar]: <> "Local Variables:" [EmacsVar]: <> "mode: indented-text" [EmacsVar]: <> "indent-tabs-mode: nil" [EmacsVar]: <> "sentence-end-double-space: t" [EmacsVar]: <> "fill-column: 70" [EmacsVar]: <> "coding: utf-8" [EmacsVar]: <> "End:"