[erlang-questions] why can't _ be passed around?

Richard Carlsson <>
Thu Sep 22 14:28:12 CEST 2011


On 09/22/2011 02:08 PM, Matthias Lang wrote:
> Hi,
>
> Idle curiosity: why can't I pass or send _?
>
> I can write:
>
>    f() ->
>      receive _ ->  ok
>      after 500 ->  exit(timeout) end.
>
> But I can't write
>
>    g(Pattern) ->
>      receive Pattern ->  ok
>      after 500 ->  exit(timeout) end.
>
>    f() ->
>      g(_).
>
> Nor can I write
>
>    f() ->
>      g({my_atom, 3, _}).
>
> Ok, I realise I'm not allowed to because _ isn't bound. But _ can't
> ever be bound (right? or is there another way of thinking about _?).

The way to think about _ is that it's a shorthand for "replace this 
underscore with some variable that doesn't occur anywhere else and will 
not be used again, not even for some other underscore". Which is really 
what the compiler will do with it (check out the generated Core Erlang 
code if you like: erlc +to_core foo.erl).

>  Thoughts? Am I asking for patterns to be first class?

You're basically asking for Prolog. I.e., passing around uninstantiated 
variables ("holes" as first class objects), and letting the called code 
fill in the holes (using unification). The holes can occur within a 
partially instantiated structure, as in your {my_atom, 3, _}. And the 
bindings propagate back to the caller, so you could do:

   f() ->
     g({my_atom, 3, Hole}),
     Hole + 1.

   g({my_atom, 3, 4}) ->
     ok.

and have f() return 5. (The above is a hypothetical example using Erlang 
syntax - it's not proper Prolog.)

Cool and mindbending things can be done this way (difference lists: see 
e.g. http://bulba.sdsu.edu/prolog/diff_list/diff_list.htm), but I'm not 
sure I want that kind of code in a 100+KLOC system.

     /Richard



More information about the erlang-questions mailing list