# Is it a bug how the compiler treats fun params?

**URL:** <https://erlangforums.com/t/is-it-a-bug-how-the-compiler-treats-fun-params/1155>\
**Category:** Questions / Help\
**Tags:** fun, pattern-matching\
**Created:** [March 2, 2022, 12:27pm UTC](https://erlangforums.com/t/is-it-a-bug-how-the-compiler-treats-fun-params/1155 "2022-03-02T12:27:12Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![bsanyi](https://erlangforums.com/letter_avatar_proxy/v4/letter/b/7c8e57/32.png) [@bsanyi](https://erlangforums.com/u/bsanyi)\
**Post date:** [March 2, 2022, 12:27pm UTC](https://erlangforums.com/t/is-it-a-bug-how-the-compiler-treats-fun-params/1155/1 "2022-03-02T12:27:12Z")

</div>

Hi! Here’s a simple function that’s goal is to find certain tuples in a `List`, based on the param `Attr`:

```erlang
find_items(List, Attr) ->
  lists:filter(
    fun
      ({_, Attr, _}) -> true;
      (_) -> false
    end,
    List
  ).

```

Unfortunately the compiler says **Warning: variable ‘Attr’ is unused** for both lines where the variable appears (1st and 4th in the example above). It seems like the inner fun is shadowing the **Attr** variable even when it is already bound in the outer scope, and so it is not used in the pattern matching.

The way around it is simple. When I introduce a case statement in the fun, and try to do the pattern match in it, all of a sudden everything’s just fine:

```erlang
find_items(List, Attr) ->
  lists:filter(
    fun
      (X) ->
        case X of
          {_, Attr, _} -> true;
          _ -> false
        end
    end,
    List
  ).

```

Is this deliberate? If so, what is the explanation of this strange behavior? Why are params of a fun handled differently?

---

<div class="post-metadata">

**Author:** ![jhogberg](https://erlangforums.com/user_avatar/erlangforums.com/jhogberg/32/179_2.png) [@jhogberg](https://erlangforums.com/u/jhogberg)\
**Post date:** [March 2, 2022, 12:43pm UTC](https://erlangforums.com/t/is-it-a-bug-how-the-compiler-treats-fun-params/1155/2 "2022-03-02T12:43:23Z")

</div>

Hi!

This is deliberate, function parameters [shadow](https://en.wikipedia.org/wiki/Variable_shadowing) variables defined in outer scopes, and you should have gotten a warning saying that. I personally wish that shadowing wasn’t a thing at all, but that ship sailed long ago.

Here’s a proposal that touches on the subject, introducing a new operator `^` that can disable shadowing:

> <https://github.com/erlang/eep/blob/master/eeps/eep-0055.md>

---

<div class="post-metadata">

**Author:** ![bsanyi](https://erlangforums.com/letter_avatar_proxy/v4/letter/b/7c8e57/32.png) [@bsanyi](https://erlangforums.com/u/bsanyi)\
**Post date:** [March 9, 2022, 2:48pm UTC](https://erlangforums.com/t/is-it-a-bug-how-the-compiler-treats-fun-params/1155/3 "2022-03-09T14:48:51Z")

</div>

Thanks for the answer. Do you think EEP-55 is gonna be implemented in mainstream Erlang/OTP ever?

If not, do you think that the pin operator could be part of Erlang just to solve the problem I mentioned in this question? (What I mean by that is, `fun ({_, ^Attr, _}) -> ... end` could mean that I want to use the outer `Attr` value in the pattern, and I don’t want a new `Attr` variable inside, but without the pin operator things work just like they did before.)

---

<div class="post-metadata">

**Author:** ![jhogberg](https://erlangforums.com/user_avatar/erlangforums.com/jhogberg/32/179_2.png) [@jhogberg](https://erlangforums.com/u/jhogberg)\
**Post date:** [March 9, 2022, 3:06pm UTC](https://erlangforums.com/t/is-it-a-bug-how-the-compiler-treats-fun-params/1155/4 "2022-03-09T15:06:13Z")

</div>

It’s not up to me, but I’m personally in favor of trying it out through the [experimental features](https://erlangforums.com/t/eep-60-add-support-for-experimental-features/1138) framework in OTP 26 or 27. 🙂
