Skip to main content

W0071 - Redundant Fun Wrapper

Information

use_fun(L) ->
lists:map(fun(X) -> foo(X) end, L).
%% ^^^^^^^^^^^^^^^^^^^^ 💡 information: W0071: A reference to `fun foo/1` can be taken directly.

Explanation

This diagnostic detects anonymous functions that are redundant wrappers around another function call with the same arguments in the same order. These wrappers can be replaced with direct fun references, making the code cleaner and more efficient.

Patterns Detected

The linter identifies three types of redundant wrappers:

Local Function Calls

% Before - redundant wrapper
lists:map(fun(X) -> foo(X) end, L).
lists:foldl(fun(X, Y) -> add(X, Y) end, 0, L).

% After - direct fun reference
lists:map(fun foo/1, L).
lists:foldl(fun add/2, 0, L).

Remote Function Calls

% Before - redundant wrapper
lists:map(fun(X) -> erlang:abs(X) end, L).
lists:foldl(fun(X, Y) -> erlang:max(X, Y) end, 0, L).

% After - direct fun reference
lists:map(fun erlang:abs/1, L).
lists:foldl(fun erlang:max/2, 0, L).

Fun Variables

% Before - redundant wrapper (F is already a fun)
apply_fun(F, L) ->
lists:map(fun(X) -> F(X) end, L).

% After - use F directly
apply_fun(F, L) ->
lists:map(F, L).

Why This Matters

  1. Readability: Direct fun references are more concise and clearly express intent
  2. Performance: Eliminates an unnecessary function call wrapper
  3. Maintainability: Less code means fewer places for bugs to hide

When NOT to Simplify

The linter correctly ignores cases where the anonymous function is NOT a simple wrapper:

  • Arguments are reordered: fun(X, Y) -> foo(Y, X) end
  • Extra arguments are captured: fun(X) -> foo(X, Captured) end
  • Nested calls: fun(X) -> foo(bar(X)) end
  • Body is not a call: fun(X) -> X + 1 end
  • Pattern matching in parameters: fun({X, Y}) -> foo(X, Y) end
  • Guards are present: fun(X) when X > 0 -> foo(X) end
  • Multiple clauses: fun(0) -> zero; (X) -> X end
  • Named funs: fun Loop(X) -> foo(X) end

Auto-Fix

This diagnostic includes an auto-fix that replaces the redundant wrapper with the appropriate fun reference or variable.

See Also