Erlang compiler error - erlang

I have the following code
loop(Data) ->
receive
{Key, Value} ->
[{Key, Value}|Data];
{Key} ->
member(Key, Data);
14 loop(Data);
stop ->
io:format("server_stopped"),
ok
end .
and I get the following error (I put the line number 14 in the code)
./dist_erlang.erl:14: syntax error before: ';'
./dist_erlang.erl:2: function loop/1 undefined
./dist_erlang.erl:28: Warning: function member/2 is unused
I am not sure what the syntax problem is with the above code. I have a method called member which is giving the error because of a different syntax error on line 14 I am sure.
Any help is appreciated thanks.

In Erlang, expressions are separated by commas (and clauses are separated by semicolons). Try:
loop(Data) ->
receive
{Key, Value} ->
loop([{Key, Value}|Data]);
{Key} ->
member(Key, Data),
loop(Data);
stop ->
io:format("server_stopped"),
ok
end.

Related

How can I get Dialyzer to accept a call to a function that intentionally throws?

I have a function that intentionally throws when its first argument is the atom throw.
A simplified version of this code is:
-module(sample).
-export([main/1, throw_or_ok/1]).
main(_Args) ->
throw_or_ok(throw).
throw_or_ok(Action) ->
case Action of
throw -> throw("throwing");
ok -> ok
end.
Dialyzer errors on the call to throw_or_ok:
sample.erl:7: The call sample:throw_or_ok
('throw') will never return since it differs in the 1st argument from the success typing arguments:
('ok')
Adding specs doesn't help, the error message is the same:
-module(sample).
-export([main/1, throw_or_ok/1]).
-spec main(_) -> no_return().
main(_Args) ->
throw_or_ok(throw).
-spec throw_or_ok(throw) -> no_return(); (ok) -> ok.
throw_or_ok(Action) ->
case Action of
throw -> throw("throwing");
ok -> ok
end.
How can I get Dialyzer to accept calls to throw_or_ok/1 that are guaranteed to throw?
Unfortunately there is currently no clean way to mark this as acceptable for Dialyzer via specs.
Perhaps you can use an ignore warning annotation, however.
Looks like if will put throw it will never return, if will put ok the pattern will never match with throw. See topic with similar issue. The logic of main/1 need to change, eg:
main(Args) ->
MaybeOk = case Args of
0 -> throw;
_ -> ok
end,
throw_or_ok(MaybeOk).
OR
main(_Args) ->
throw_or_ok(_Args).

erlang tuples to list to maps from a text file

I am trying to read data from text file put the tuples from the file into a list and then map them the code is as follows I am new to erlang and dont know what I am doing wrong:
-module(exchange).
-export([start/0]).
start()->
A= file:consult("calls.txt"),
B=tuple_to_list(A),
io:fwrite("~p~n",[maps:from_list([B])]).
It gives me the error :
5> c(exchange).
{ok,exchange}
26> exchange:start().
** exception error: bad argument
in function maps:from_list/1
called as maps:from_list([[ok,
[{john,[jill,joe,bob]},
{jill,[bob,joe,bob]},
{sue,[jill,jill,jill,bob,jill]},
{bob,[john]},
{joe,[sue]}]]])
in call from exchange:start/0 (exchange.erl, line 10)
Please help me here . Thank you .
file:consult/2 returns {ok, Terms} on success so this should work:
{ok, A} = file:consult("calls.txt"),
io:fwrite("~p~n", [maps:from_list(A)]).

Can you specify a type for function argument in erlang using apply(M, F, A)?

In the example below, I would like to specify a type for argument in the apply(M, F, A) call, but I can't figure how. Here, dialyzer doesn't complain for type mismatch between {event, "something append !"} and {anyevent, string()} type definition in callback_function spec :
-module(erl_test).
-export([
callback_function/1,
test_it/0
]).
-spec callback_function(
Event::{anyevent, string()}) -> ok.
callback_function(Event) ->
io:format("event received: ~p~n", [Event]),
ok.
-spec notify_something(CbMod::module(), CbFun::atom()) -> ok.
notify_something(CbMod, CbFun) ->
apply(CbMod, CbFun, [{event, "something append !"}]),
ok.
test_it() ->
notify_something(?MODULE, callback_function).
Or do you have any other design proposition that I could use to do type checking on a callback function ?
Thank you !
Using apply/3 as it is, I believe you are out of luck.
However, you could change the line:
apply(CbMod, CbFun, [{event, "something append !"}]),
to:
CbMod:CbFun([{event, "something append !"}]),
This would make Dialyzer aware of the specified argument type.

spawn function in erlang using function in another module

I have been learning erlang for the past week and am going through Joe Armstrong's Pragmatic erlang book . I was writing some code to spawn processes and have come across a situation
I have a function in module myatom.erl which looks like this
start(anatom,Fun) ->
case whereis(anatom) of
undefined ->
Pid = spawn(Fun),
try register(anatom,Pid) of
true -> true
catch
error:Reason ->
Reason
end;
Other -> {error,already_defined}
end.
There is a function in another module named tloop.erl
loop() ->
receive
{ From , No } -> From ! { self(), No*4};
Other -> void
end.
if I am to use start() to spawn loop in the erlang shell , how can I do it ?
I get the following error when I do
anatom:start(atomname,tloop:loop).
Thanks in advance !
anatom:start(myatom,fun tloop:loop).
* 2: syntax error before: ')
You must write the following
anatom:start(myatom, fun tloop:loop/0).
You have to specify the arity (number of arguments) of the function, as in erlang functions with the same name but different arity are not considered to be the same function.

Thrift/Erlang string

I'm trying to write a simple Thrift server in Erlang that takes a string and returns a string.
Everything seems to be working up to the point of calling my function:
handle_function(Function, Args) when is_atom(Function), is_tuple(Args) ->
case apply(?MODULE, Function, tuple_to_list(Args)) of
ok -> ok;
Reply -> {reply, Reply}
end.
test([X]) ->
"You sent: " ++ X.
I'm getting a function_clause. The stack trace shows the following:
{function_clause, [{server, test,
[<<"w00t">>]},
{server,handle_function, 2}, ...
My handle_function is copied from the tutorial file so I won't be surprised if I need to tweak it. Any ideas?
That last argument of apply should be a list of arguments to 'test', e.g., if tuple_to_list(Args) resulted in:
[1]
...then:
test(1)
If tuple_to_list(Args) resulted in:
[1,2]
...then:
test(1,2)
So, if {<<"woot">>} is being passed to tuple_to_list, that's going to be:
[<<"woot">>]
...so:
test(<<"woot">>)
...but test's signature asks for a list as the argument, so there's a mismatch.

Resources