Where I am wrong in this module code - erlang

I have created a module with the below code
-module('calc') .
-export([sum/2]) . (0)
sum(L) -> sum(L,0); (1)
sum([],N) -> N; (2)
sum([H|T], N) -> sum(T, H + N) (3) .
and in shell, when I compile it is returning me error like below
calc.erl:5: head mismatch
calc.erl:2: function sum/2 undefined
error
As per my understanding from the book, 1 clause will receive the list and will pass it to the (3). Then (3) will return the desired result.
But I don't know where I have committed the mistake. Please help me on this.
And please help me to understand what is /2 in export statement.

You have a syntax error at line (1). The functions sum/1 and sum/2 are different, so your code should look like:
sum(L) -> sum(L,0). %% notice the . instead of ;
sum([],N) -> N;
sum([H|T], N) -> sum(T, H + N).
The /2 is the arity of your function, that is, the number of arguments it takes. So, in your case, the function you want to export is sum/1.

Check this link
Write a function that calculate the sum of integers in a list in Erlang
/2 in export statement indicates the number of arguments to the function sum.

Related

What does (_,[]) mean?

I was given a question which was:
given a number N in the first argument selects only numbers greater than N in the list, so that
greater(2,[2,13,1,4,13]) = [13,4,13]
This was the solution provided:
member(_,[]) -> false;
member(H,[H|_]) -> true;
member(N,[_,T]) -> member(N,T).
I don't understand what "_" means. I understand it has something to do with pattern matching but I don't understand it completely. Could someone please explain this to me
This was the solution provided:
I think you are confused: the name of the solution function isn't even the same as the name of the function in the question. The member/2 function returns true when the first argument is an element of the list provided as the second argument, and it returns false otherwise.
I don't understand what "_" means. I understand it has something to do with pattern matching but I don't understand it completely. Could someone please explain this to me
_ is a variable name, and like any variable it will match anything. Here are some examples of pattern matching:
35> f(). %"Forget" or erase all variable bindings
ok
45> {X, Y} = {10, 20}.
{10,20}
46> X.
10
47> Y.
20
48> {X, Y} = {30, 20}.
** exception error: no match of right hand side value {30,
20}
Now why didn't line 48 match? X was already bound to 10 and Y to 20, so erlang replaces those variables with their values, which gives you:
48> {10, 20} = {30, 20}.
...and those tuples don't match.
Now lets try it with a variable named _:
49> f().
ok
50> {_, Y} = {10, 20}.
{10,20}
51> Y.
20
52> {_, Y} = {30, 20}.
{30,20}
53>
As you can see, the variable _ sort of works like the variable X, but notice that there is no error on line 52, like there was on line 48. That's because the _ variable works a little differently than X:
53> _.
* 1: variable '_' is unbound
In other words, _ is a variable name, so it will initially match anything, but unlike X, the variable _ is never bound/assigned a value, so you can use it over and over again without error to match anything.
The _ variable is also known as a don't care variable because you don't care what that variable matches because it's not important to your code, and you don't need to use its value.
Let's apply those lessons to your solution. This line:
member(N,[_,T]) -> member(N,T).
recursively calls the member function, namely member(N, T). And, the following function clause:
member(_,[]) -> false;
will match the function call member(N, T) whenever T is an empty list--no matter what the value of N is. In other words, once the given number N has not matched any element in the list, i.e. when the list is empty so there are no more elements to check, then the function clause:
member(_,[]) -> false;
will match and return false.
You could rewrite that function clause like this:
member(N, []) -> false;
but erlang will warn you that N is an unused variable in the body of the function, which is a way of saying: "Are you sure you didn't make a mistake in your function definition? You defined a variable named N, but then you didn't use it in the body of the function!" The way you tell erlang that the function definition is indeed correct is to change the variable name N to _ (or _N).
It means a variable you don't care to name. If you are never going to use a variable inside the function you can just use underscore.
% if the list is empty, it has no members
member(_, []) -> false.
% if the element I am searching for is the head of the list, it is a member
member(H,[H|_]) -> true.
% if the elem I am searching for is not the head of the list, and the list
% is not empty, lets recursively go look at the tail of the list to see if
% it is present there
member(H,[_|T]) -> member(H,T).
the above is pseudo code for what is happening. You can also have multiple '_' unnamed variables.
According to Documentation:
The anonymous variable is denoted by underscore (_) and can be used when a variable is required but its value can be ignored.
Example:
[H, _] = [1,2] % H will be 1
Also documentation says that:
Variables starting with underscore (_), for example, _Height, are normal variables, not anonymous. They are however ignored by the compiler in the sense that they do not generate any warnings for unused variables.
Sorry if this is repetitive...
What does (_,[]) mean?
That means (1) two parameters, (2) the first one matches anything and everything, yet I don't care about it (you're telling Erlang to just forget about its value via the underscore) and (3) the second parameter is an empty list.
Given that Erlang binds or matches values with variables (depending on the particular case), here you're basically looking to a match (like a conditional statement) of the second parameter with an empty list. If that match happens, the statement returns false. Otherwise, it tries to match the two parameters of the function call with one of the other two statements below it.

Erlang Doesn't Warn About Unused Function Argument

If I declare a function
test(A) -> 3.
Erlang generates a warning about variable A not being used. However the definition
isEqual(X,X) -> 1.
Doesn't produce any warning but
isEqual(X,X) -> 1;
isEqual(X,Y) -> 0.
again produces a warning but only for the second line.
The reason why that doesn't generate a warning is because in the second case you are asserting (through pattern matching), by using the same variable name, that the first and second arguments to isEqual/2 have the same value. So you are actually using the value of the argument.
It might help to understand better if we look at the Core Erlang code produced from is_equal/2. You can get .core source files by compiling your .erl file in the following way: erlc +to_core pattern.erl (see here for pattern.erl).
This will produce a pattern.core file that will look something like this (module_info/[0,1] functions removed):
module 'pattern' ['is_equal'/2]
attributes []
'is_equal'/2 = fun (_cor1,_cor0) ->
case <_cor1,_cor0> of
%% Line 5
<X,_cor4> when call 'erlang':'=:=' (_cor4, X) ->
1
%% Line 6
<X,Y> when 'true' ->
0
end
As you can see, each function clause from is_equal/2 in the .erl source code gets translated to a case clause in Core Erlang. X does get used in the first clause since it needs to be compared to the other argument. On the other hand neither X or Y are used in the second clause.

erlang an error occurred when evaluating an arithmetic expression

i am a beginner of erlang.
this is my code:
-module(squsum).
-export([main/0]).
ssum(1) -> 1;
ssum(N) -> N*N + ssum(N-1).
main() ->
{_,T} = io:fread("","~d"),
io:fwrite("~p~n",[ssum(T)]).
why will it have such a problem?
** exception error: an error occurred when evaluating an arithmetic expression
in function squsum:ssum/1 (squsum.erl, line 5)
in call from squsum:main/0 (squsum.erl, line 9)
T is a list containing the value, I guess it is the symmetric point of view of IO:fwrite. so simply use:
main() -> {ok,[T]} = io:fread("","~d"), io:fwrite("~p~n",[ssum(T)]).
I'm not too familiar with erlang, but if it is at all possible for T to be negative, then your recursive function would never end.
Similarly, if T=0, the function would never end.
This is really on comment on Pascal's answer: just to add that io:fread/2 returns a list of the terms specified in the format string --- even if the format string has just one term, it returns a list with one element.
The erlang documentation is quite good. io:fread/2 is at http://erlang.org/doc/man/io.html#fread-2

erlang for loop for queries

I have this function:
show_employee_table() ->
do(qlc:q([B || B <- mnesia:table(employee)])).
What it does is that it goes to a table called employee and prints the contents to the user.
Concept: I want to make another function say called show(times) -->, this function will take a table name and the number of times to call the show_table function.
If I input (employee,100), I want to have a for loop that runs 100 times, the idea is to measure the time taken to run the loop. In java I would do something like this:
Time t = time.now();
for ( I=0; I<N; I++){
show_employee_table() ->
do(qlc:q([B || B <- mnesia:table(employee)])).
}
Time t2 = time.now();
timetaken = t2 - t1;
That's how I want to do it, but in erlang. I just don't know the syntax in erlang and I would appreciate it if someone can help me.
For time measurement, use: timer:tc/1, timer:tc/2, timer:tc/3. So we will have a recursive function called loop which may be doing anything you want. Then we would measure the time it takes to loop by applying
{TimeTaken,Result} = timer:tc(?MODULE,loop,Args).
Args must be a list of arguments to the function say, a table and a number, like this
measureLoopTime()->
Args = [employee,100],
{TimeTaken,_Result} = timer:tc(?MODULE,loop,Args),
TimeTaken.
loop(_,0) -> done;
loop(Table,Number)->
%%% do something ....
loop(Table, Number - 1).
That's the correct erlang implementation of your java code. Follow the link to the timing function to see in which units the time is returned.
Erlang doesn't have loops like java. Instead you would be using recursion.
Eg:
show_employee_table(0) -> done;
show_employee_table(Times) ->
do(qlc:q([B || B <- mnesia:table(employee)])),
show_employee_table(Times - 1)
.
You would cont down for each step, and when you reach 0 you are done..
If you do this alot you could make a function for it:
times(_, 0) -> done;
times(Call, Times) ->
Call(),
times(Call, Times - 1)
.
Call it like this:
times(fun () -> show_employee_table() end, N).

Exception error in Erlang

So I've been using Erlang for the last eight hours, and I've spent two of those banging my head against the keyboard trying to figure out the exception error my console keeps returning.
I'm writing a dice program to learn erlang. I want it to be able to call from the console through the erlang interpreter. The program accepts a number of dice, and is supposed to generate a list of values. Each value is supposed to be between one and six.
I won't bore you with the dozens of individual micro-changes I made to try and fix the problem (random engineering) but I'll post my code and the error.
The Source:
-module(dice2).
-export([d6/1]).
d6(1) ->
random:uniform(6);
d6(Numdice) ->
Result = [],
d6(Numdice, [Result]).
d6(0, [Finalresult]) ->
{ok, [Finalresult]};
d6(Numdice, [Result]) ->
d6(Numdice - 1, [random:uniform(6) | Result]).
When I run the program from my console like so...
dice2:d6(1).
...I get a random number between one and six like expected.
However when I run the same function with any number higher than one as an argument I get the following exception...
**exception error: no function clause matching dice2:d6(1, [4|3])
... I know I I don't have a function with matching arguments but I don't know how to write a function with variable arguments, and a variable number of arguments.
I tried modifying the function in question like so....
d6(Numdice, [Result]) ->
Newresult = [random:uniform(6) | Result],
d6(Numdice - 1, Newresult).
... but I got essentially the same error. Anyone know what is going on here?
This is basically a type error. When Result is a list, [Result] is a list with one element. E.g., if your function worked, it would always return a list with one element: Finalresult.
This is what happens (using ==> for "reduces to"):
d6(2) ==> %% Result == []
d6(2, [[]]) ==> %% Result == [], let's say random:uniform(6) gives us 3
d6(1, [3]) ==> %% Result == 3, let's say random:uniform(6) gives us 4
d6(0, [4|3]) ==> %% fails, since [Result] can only match one-element lists
Presumably, you don't want [[]] in the first call, and you don't want Result to be 3 in the third call. So this should fix it:
d6(Numdice) -> Result = [], d6(Numdice, Result). %% or just d6(Numdice, []).
d6(0, Finalresult) -> {ok, Finalresult};
d6(Numdice, Result) -> d6(Numdice - 1, [random:uniform(6) | Result]).
Lesson: if a language is dynamically typed, this doesn't mean you can avoid getting the types correct. On the contrary, it means that the compiler won't help you in doing this as much as it could.

Resources