Simple Rock Paper Scissors in Erlang I'm very new to Erlang and I'm specifically interested in making my Erlang idiomatic (in other words, can you tell I don't know Erlang from this code?) and removing code duplication. I am not as interested in performance or the UI of the &quot;game.&quot;
This is a simple interactive Rock, Paper, Scissors game and I've been using erlc rps.erl &amp;&amp; ./rps-main.erl to run it.
rps.erl
-module(rps).
-export([play_game/1, get_random_symbol/0]).

get_symbol(1) -&gt; rock;
get_symbol(2) -&gt; paper;
get_symbol(3) -&gt; scissors.

get_random_symbol() -&gt;
    get_symbol(rand:uniform(3)).

play_game(InputFunctions) -&gt;
    Score = [{win, 0}, {loss, 0}, {tie, 0}],
    play_game(Score, InputFunctions).

play_game(ok, _) -&gt;
    ok;
play_game(Score, {Player1Input, Player2Input}) -&gt;
    display_score(Score),
    Input1 = Player1Input(),
    Continue = Input1 =/= quit,
    Input2 = Player2Input(Continue),
    NewScore = compare_results(Input1, Input2, Score),
    play_game(NewScore, {Player1Input, Player2Input}).

compare_results(quit, _, _) -&gt;
    ok;
compare_results(_, quit, _) -&gt;
    ok;
compare_results(Same, Same, [Wins, Losses, {tie, Ties}]) -&gt;
    [Wins, Losses, {tie, Ties+1}];
compare_results(rock, paper, [Wins, {loss, Losses}, Ties]) -&gt;
    [Wins, {loss, Losses+1}, Ties];
compare_results(paper, scissors, [Wins, {loss, Losses}, Ties]) -&gt;
    [Wins, {loss, Losses+1}, Ties];
compare_results(scissors, rock, [Wins, {loss, Losses}, Ties]) -&gt;
    [Wins, {loss, Losses+1}, Ties];
compare_results(rock, scissors, [{win, Wins}, Losses, Ties]) -&gt;
    [{win, Wins+1}, Losses, Ties];
compare_results(scissors, paper, [{win, Wins}, Losses, Ties]) -&gt;
    [{win, Wins+1}, Losses, Ties];
compare_results(paper, rock, [{win, Wins}, Losses, Ties]) -&gt;
    [{win, Wins+1}, Losses, Ties].

display_score([{win, Wins}, {loss, Losses}, {tie, Ties}]) -&gt;
    io:format(&quot;Player1 Wins: ~B~nPlayer2 Wins: ~B~nTies: ~B~n&quot;, [Wins, Losses, Ties]).

rpsgame.erl
#!/usr/bin/env escript
%% -*- erlang -*-
%%! -pa 'ebin/'
-import(rps, [play_game/1, get_random_symbol/0]).

main(_) -&gt; 
    GetPlayerInput = fun() -&gt;
        io:format(&quot;Enter rock, paper, scissors, or quit~n&quot;),
        case io:get_line(&quot;&gt; &quot;) of
            &quot;rock\n&quot; -&gt; rock;
            &quot;paper\n&quot; -&gt; paper;
            &quot;scissors\n&quot; -&gt; scissors;
            _ -&gt; quit
        end
    end,
    GetCompInput = fun(Continue) when Continue =:= false -&gt;
                        ok;
                    (_) -&gt;
                        Input = rps:get_random_symbol(),
                        io:format(&quot;Computer threw ~p~n&quot;, [Input]),
                        Input
                    end,
    play_game({GetPlayerInput, GetCompInput}).
In whole not bad, but something can be simplified.

1.
In short functions don't need to create separate variables, especially if it is just a wrapper over the call of inner function. So play game/1 from rps can be rewritten as:

play_game(InputFunctions) -&gt;
  play_game([{win, 0}, {loss, 0}, {tie, 0}], InputFunctions).


2.
Behavior of function for get result from player2 must not depend on result first player. Together with hint from 1 and giving an alias to the name of argument get

play_game(Score, {Player1Input, Player2Input} = P) -&gt;
  display_score(Score),
  case Player1Input() of
    quit -&gt; ok;
    Input -&gt; play_game(new_score(Input, Player2Input(), Score), P)
  end.


where Player2Input/0:

  GetCompInput = fun() -&gt;
    Input = rps:get_random_symbol(),
    io:format("Computer threw ~p~n", [Input]),
    Input
                 end,


new_score in my opinion, better captures the essence of the function than compare_results. This also allow delete first clause in new_score(compare_results)/3.

3.
Usage the symbol - in the name of the module is not very convenient,
 because you must wrap the name in ' ' when call function. Better use _ as delimiter.

4.
Not should use guard,when can use pattern matching. Compare

fun(Continue) when Continue =:= false -&gt;


and

fun(false) -&gt;


5.
Do not create an anonymous argument for a single function clause, in this case it is just an excess parameter.

 main(_) -&gt;


6.
Do not use the directive import since it can will only confuse. If you know 
C++, it is possible to draw an analogy with an indicate explicit namespace instead of using namespace.  

In addition I did not delete lines

play_game(ok, _) -&gt;
  ok;


and   

new_score(_, quit, _) -&gt;
  ok;


although when playing with the computer this function clause does not get called.