I am new to Erlang and trying to pass the result from one function to another using message passing. However, I am encountering badarg
errors when using main ! {numbers, 1, 100}
. Despite trying different changes, the message still isn’t passed correctly, especially when using From
.
In the code provided, the line main ! {numbers, 1, 100}
might fail because the main
process is expected to be registered, and if it is not properly registered or the process has exited, Erlang will raise a badarg
error. To fix this, ensure that the process main
is correctly registered by calling register(main, Pid)
and that the process is alive when trying to send messages. Additionally, the use of message passing with From
commented out in the proc
function could prevent responses from being delivered to the correct sender, further contributing to the error. Double-checking the registration of the main
process and ensuring it is running when sending messages should help resolve the issue.
Erlang Code (with Errors):
code-module(numbers).
-export([start_main/0,main/2,proc/0,sumNumbers/2]).
main(Total, N) ->
if
N == 0 ->
io:format("Total: ~p ~n", [Total]);
true ->
true
end,
receive
{numbers, Low, High} ->
Half = round(High/2),
Pid1 = spawn(numbers, proc, []),
Pid2 = spawn(numbers, proc, []),
Pid1 ! {work, Low, Half},
Pid2 ! {work, Half+1, High};
%% Pid1 ! {work, self(), Low, Half},
%% Pid2 ! {work, self(), Half+1, High},
{return, Result} ->
io:format("Received ~p ~n", [Result]),
main(Total+Result, N-1)
end.
proc() ->
receive
{work, Low, High} ->
io:format("Processing ~p to ~p ~n", [Low, High]),
Res = sumNumbers(Low,High),
main ! {return, Res},
proc()
%% {work, From, Low, High} ->
%% io:format("Processing ~p to ~p ~n", [Low, High]),
%% Res = sumNumbers(Low,High),
%% From ! {return, Res},
%% proc()
end.
sumNumbers(Low, High) ->
Lst = lists:seq(Low,High),
lists:sum(Lst).
start_main() ->
register(main, spawn(numbers, main, [0,2])).
Changes made:
- Correct message format in
proc
:- Added the sender process (
self()
) when sending thework
message toproc
. - This ensures that the worker process knows which process to send the result (
{return, Res}
) back to.
- Added the sender process (
- Handling responses in
main
:main
now expects responses from the two worker processes and reduces the counterN
accordingly once it receives each result.
- Fixed message sending in
proc
:- In the
proc
function, we send the result back to the calling process (From
) usingFrom ! {return, Res}
.
- In the
This corrected code now properly handles message passing between processes in Erlang without triggering the badarg
error. The main
function will correctly coordinate the workers, collect results, and print the total.
Correct Code:
code-module(numbers).
-export([start_main/0, main/2, proc/0, sumNumbers/2]).
main(Total, N) ->
if
N == 0 ->
io:format("Total: ~p ~n", [Total]);
true ->
true
end,
receive
{numbers, Low, High} ->
Half = round(High/2),
Pid1 = spawn(numbers, proc, []),
Pid2 = spawn(numbers, proc, []),
Pid1 ! {work, Low, Half, self()},
Pid2 ! {work, Half+1, High, self()},
main(Total, 2); %% Expecting two responses, so keeping N as 2.
{return, Result} ->
io:format("Received ~p ~n", [Result]),
main(Total+Result, N-1)
end.
proc() ->
receive
{work, Low, High, From} ->
io:format("Processing ~p to ~p ~n", [Low, High]),
Res = sumNumbers(Low, High),
From ! {return, Res}, %% Send the result back to the calling process
proc()
end.
sumNumbers(Low, High) ->
Lst = lists:seq(Low, High),
lists:sum(Lst).
start_main() ->
register(main, spawn(numbers, main, [0, 2])).
Fixing the badarg
Error in Erlang
When learning Erlang, you might encounter the badarg
error when passing messages between processes. This error typically occurs when a process is not registered or when an invalid argument is passed. Let’s break down the common causes of this error and how to resolve it.
In the provided code, the goal is to calculate the sum of a range of numbers using multiple processes. The function proc
handles the actual work, while the main
function coordinates the flow of the program.
The error stems from two primary issues:
- Unregistered or exited process: The
main
process needs to be registered before other processes can send messages to it. Without this registration, trying to send a message tomain
results in abadarg
error. - Message handling flow: The original
main
function doesn’t properly handle multiple responses from the spawned processes. The function should remain active to receive both results.
Fixes:
- Registering the
main
process: Thestart_main
function correctly registers themain
process usingregister(main, Pid)
, allowing other processes to send messages to it. - Correct message flow: A recursive call to
main
is added after spawning the worker processes. This ensures thatmain
stays active and is ready to receive messages from the worker processes.
By addressing these issues, the badarg
error can be resolved, and the code will execute as intended.