What is Pattern Matching in Erlang - erlang

I'm learning Erlang and came across Pattern Matching.
Could someone kindly explain to me what is Pattern Matching using a simple explanation.
An explanation in which anybody could understand.
I have read multiple sources but still can't grasp the concept.

Could someone kindly explain to me what is Pattern Matching using a
simple explanation. An explanation in which anybody could understand.
Pattern matching is how assignment is instigated in erlang. In other languages, the = sign is the assignment operator, e.g. x = 10. However, in erlang, the = sign is the pattern match operator. When erlang sees an = sign, it looks at the term on the right hand side of the = sign, then tries to give values to the variables on the left hand side of the equals sign, so that both sides of the = sign are identical, i.e. they match.
In the simple case, e.g. X = 1, it looks like the = sign performs assignment in erlang. And in fact, X will have the value 1 after that statement is evaluated. However, you can't write the following in other languages:
{Y, 10} = {20, 10}
In other languages you can't have constants on the left hand side of the assignment operator. In erlang, however, specifying constants on the left of the pattern match operator is perfectly normal. After that statement is evaluated, Y will have the value 20 because in order for both sides of the = sign to be identical, erlang has to assign the value 20 to Y.
How does erlang perform that assignment? It doesn't really matter, but you can think of the assignment operator in erlang as the three characters !*!. When erlang sees the pattern match operator in the example above, in order to get things to match up, erlang uses the assignment operator !*! to assign the value 20 to Y, i.e. Y !*! 20.
When you write = in erlang, you are asking, "Please try to get these things to match!". The knock on effect is that erlang will perform some assignments (!*!) to make both sides match. You can't do assignment directly yourself, all you can do is ask erlang to make things match. If that is too confusing, then just think of the pattern match operator as a trick assignment operator, which is more powerful than the assignment operator in other languages. It doesn't matter what you call the = sign in erlang, you just need to know how it works.
In erlang, pattern matching can be used in a lot of different ways:
1) To extract positional values from a data structure:
15> [X, {Y, _}] = [10, {1, hello}].
[10,{1,hello}]
16> X.
10
17> Y.
1
2) To determine which function clause executes in a function definition:
my.erl:
go(X, hello) ->
io:format("Do stuff: ~w~n", [X*2]);
go(X, goodbye) ->
io:format("Do other stuff: ~w~n", [X-2]);
go(_, _) ->
io:format("Okay.~n").
In the shell:
7> c(my).
my.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,my}
8> my:go(3, 4).
Okay
ok
9> my:go(2, goodbye).
Do other stuff: 0
ok
10> my:go(10, hello).
Do stuff: 20
ok
In the first function call, erlang performs the following pattern match:
{X, hello} = {3, 4}
...which fails because no value that erlang can assign(!*!) to X will make both sides match. So, erlang continues on to the next function clause and performs the match:
{X, goodbye} = {3, 4}
which also fails; finally the third function clause matches, so the statements in the body of that function clause execute.
3) Case statements, list comprehensions, etc.

Consider this example of pattern matching in a function:
Eshell V8.2.1 (abort with ^G)
1> F = fun(1, X) -> "hello f1";
1> (2, X) -> "hello f2"
1> end.
#Fun<erl_eval.12.52032458>
2> F(1, 33).
"hello f1"
3> F(2, some_token).
"hello f2"
4> F(3, "...").
** exception error: no function clause matching erl_eval:'-inside-an-interpreted-fun-'(3,"...")
5>
The pattern matching against the first argument of function F enables to execute a branch of code or another.
Pattern matching is a way to:
guarantee that some conditions are met
have the code go into some specific branches (like if-then-else)
raise an error if an execution path is invalid
See also the official documentation page:
http://erlang.org/doc/reference_manual/patterns.html

Related

Flattening a tuple in Erlang

I am trying to turn a tuple of the form:
{{A,B,{C,A,{neg,A}}},{A,B,{neg,A}}}
Into
{{A,B,C,A,{neg,A}},{A,B,{neg,A}}
I'm quite new to Erlang so I would appreciate any hints. It makes no difference if the final structure is a list or a tuple, as long as any letter preceded by neg stays as a tuple/list.
A simple solution:
convert({{A,B,{C,D,E}},F}) -> {{A,B,C,D,E},F}.
If why this works is puzzling, consider:
1> YourTuple = {{a, b, {c, a, {neg, a}}}, {a, b, {neg, a}}}.
{{a,b,{c,a,{neg,a}}},{a,b,{neg,a}}}
2> Convert = fun({{A,B,{C,D,E}},F}) -> {{A,B,C,D,E},F} end.
#Fun<erl_eval.6.54118792>
3> Convert(YourTuple).
{{a,b,c,a,{neg,a}},{a,b,{neg,a}}}
The reason this happens is because we are matching over entire values based on the shape of the data. That's the whole point of matching, and also why its super useful in so many cases (and also why we want to use tuples in more specific circumstances in a language with matching VS a language where "everything is an iterable"). We can substitute the details with anything and they will be matched and returned accordingly:
4> MyTuple = {{"foo", bar, {<<"baz">>, balls, {ugh, "HURR!"}}}, {"Fee", "fi", "fo", "fum"}}.
{{"foo",bar,{<<"baz">>,balls,{ugh,"HURR!"}}},
{"Fee","fi","fo","fum"}}
5> Convert(MyTuple).
{{"foo",bar,<<"baz">>,balls,{ugh,"HURR!"}},
{"Fee","fi","fo","fum"}}
Why did this work when the last element of the top-level pair was so different in shape than the first one? Because everything about that second element was bound to the symbol F in the function represented by Convert (note that in the shell I named an anonymous function for convenience, this would be exactly the same as using convert/1 that I wrote at the top of this answer). We don't care what that second element was -- in fact we don't want to have to care about the details of that. The freedom to selectively not care about the shape of a given element of data is one of the key abstractions we use in Erlang.
"But those were just atoms 'a', 'b', 'c' etc. I have different things in there!"
Just to make it look superficially like your example above (and reinforce what I was saying about not caring about exactly what we bound to a given variable):
6> A = 1.
1
7> B = 2.
2
8> C = 3.
3
9> AnotherTuple = {{A, B, {C, A, {neg, A}}}, {A, B, {neg, A}}}.
{{1,2,{3,1,{neg,1}}},{1,2,{neg,1}}}
10> Convert(AnotherTuple).
{{1,2,3,1,{neg,1}},{1,2,{neg,1}}}
Needing to do this is not usually optimal, though. Generally speaking the other parts of the program that are producing that data in the first place should be returning useful data types for you. If not you can certainly hide them behind a conversion function such as the one above (especially when you're dealing with APIs that are out of your control), but generally speaking the need for this is a code smell.
And moving on
The more general case of "needing to flatten a tuple" is a bit different.
Tuples are tuples because each location within it has a meaning. So you don't usually hear of people needing to "flatten a tuple" because that fundamentally changes the meaning of the data you are dealing with. If you have this problem, you should not be using tuples to begin with.
That said, we can convert a tuple to a list, and we can check the shape of a data element. With these two operations in hand we could write a procedure that moves through a tuplish structure, building a list out of whatever it finds inside as it goes. A naive implementation might look like this:
-module(tuplish).
-export([flatten/1]).
-spec flatten(list() | tuple()) -> list().
flatten(Thing) ->
lists:flatten(flatten(Thing, [])).
flatten(Thing, A) when is_tuple(Thing) ->
flatten(tuple_to_list(Thing), A);
flatten([], A) ->
lists:reverse(A);
flatten([H | T], A) when is_tuple(H) ->
flatten(T, [flatten(H) | A]);
flatten([H | T], A) when is_list(H) ->
flatten(T, [flatten(H) | A]);
flatten([H | T], A) ->
flatten(T, [H | A]).
Keep in mind that after several years of writing Erlang code I have never needed to actually do this. Remember: tuples mean something different than lists.
All that said, the problem you are facing is almost certainly handled better by using records.

Erlang pass-by-reference nuances

9> A = lists:seq(1,10).
[1,2,3,4,5,6,7,8,9,10]
13> Fn = fun (L) -> [0|L] end.
#Fun<erl_eval.6.90072148>
14> Fn(A).
[0,1,2,3,4,5,6,7,8,9,10]
15> A.
[1,2,3,4,5,6,7,8,9,10]
If erlang internally passes by reference (see this), why does the value of A not reflect the change?
What fundamental am I missing about passing-by-reference or erlang?
a list is a recursive construction of the form L=[Head|Tail] where Head is any valid erlang term and Tail should be a list (if it is something else L is called an improper list, out of the scope of this discussion).
Saying that L is passed as a reference means that:
it is not necessary to make a copy of the list in the function parameters (good for the process stack :o);
the function returns a value, it never modify any parameter;
and in your particular case, it is even not necessary to make a copy of A to create the returned list. As the variable are not mutable, if you write B = Fn(A), then B will contain A, it will be exactly [0|A].

Is it possible to create an unbound variable in Erlang?

I'm a completely new to erlang. As an exercise to learn the language, I'm trying to implement the function sublist using tail recursion and without using reverse. Here's the function that I took from this site http://learnyousomeerlang.com/recursion:
tail_sublist(L, N) -> reverse(tail_sublist(L, N, [])).
tail_sublist(_, 0, SubList) -> SubList;
tail_sublist([], _, SubList) -> SubList;
tail_sublist([H|T], N, SubList) when N > 0 ->
tail_sublist(T, N-1, [H|SubList]).
It seems the use of reverse in erlang is very frequent.
In Mozart/Oz, it's very easy to create such the function using unbound variables:
proc {Sublist Xs N R}
if N>0 then
case Xs
of nil then
R = nil
[] X|Xr then
Unbound
in
R = X|Unbound
{Sublist Xr N-1 Unbound}
end
else
R=nil
end
end
Is it possible to create a similar code in erlang? If not, why?
Edit:
I want to clarify something about the question. The function in Oz doesn't use any auxiliary function (no append, no reverse, no anything external or BIF). It's also built using tail recursion.
When I ask if it's possible to create something similar in erlang, I'm asking if it's possible to implement a function or set of functions in erlang using tail recursion, and iterating over the initial list only once.
At this point, after reading your comments and answers, I'm doubtful that it can be done, because erlang doesn't seem to support unbound variables. It seems that all variables need to be assigned to value.
Short Version
No, you can't have a similar code in Erlang. The reason is because in Erlang variables are Single assignment variables.
Unbound Variables are simply not allowed in Erlang.
Long Version
I can't imagine a tail recursive function similar to the one you presenting above due to differences at paradigm level of the two languages you are trying to compare.
But nevertheless it also depends of what you mean by similar code.
So, correct me if I am wrong, the following
R = X|Unbound
{Sublist Xr N-1 Unbound}
Means that the attribution (R=X|Unbound) will not be executed until the recursive call returns the value of Unbound.
This to me looks a lot like the following:
sublist(_,0) -> [];
sublist([],_) -> [];
sublist([H|T],N)
when is_integer(N) ->
NewTail = sublist(T,N-1),
[H|NewTail].
%% or
%%sublist([H|T],N)
%% when is_integer(N) -> [H|sublist(T,N-1)].
But this code isn't tail recursive.
Here's a version that uses appends along the way instead of a reverse at the end.
subl(L, N) -> subl(L, N, []).
subl(_, 0, Accumulator) ->
Accumulator;
subl([], _, Accumulator) ->
Accumulator;
subl([H|T], N, Accumulator) ->
subl(T, N-1, Accumulator ++ [H]).
I would not say that "the use of reverse in Erlang is very frequent". I would say that the use of reverse is very common in toy problems in functional languages where lists are a significant data type.
I'm not sure how close to your Oz code you're trying to get with your "is it possible to create a similar code in Erlang? If not, why?" They are two different languages and have made many different syntax choices.

Erlang adding userdefined Symbols like ** or <*

I wanted to add some more symbols to my Erlang library. Example
For a matrix library A**B could mean matrix multiplication etc.
I could not find any help for the same.
Also anyone knows how to apply functions like + - or % using erlang:apply()
You can use any atom as function name. If you have specail symbols in atom you have to use its quoted form '**':
-module(operator).
-export(['**'/2]).
'**'(A, B) ->
{'**', A, B}.
There is no syntactic sugar to use such operators though. All the default operators are functions defined in module erlang and can be accessed like that:
1> operator:'**'(a, b).
{'**',a,b}
2> F0 = fun operator:'**'/2.
#Fun<operator.**.2>
3> F0(c, d).
{'**',c,d}
4> F1 = fun erlang:'+'/2.
#Fun<erlang.+.2>
5> F1(1, 2).
3
6> F2 = fun erlang:'rem'/2.
#Fun<erlang.rem.2>
7> F2(5, 3).
2
If you really, really want this you can use a parse transform but your code has to be syntactically correct before the transform. So for example your parse transform can rewrite A *_* B into exp(A, B) because A *_* B will be parsed as something like (A * _) * B. However you will not be able to transform A ** B.
Also, using parse transforms for something so frivolous is a really bad idea.

How do I know if a function is tail recursive in F#

I wrote the follwing function:
let str2lst str =
let rec f s acc =
match s with
| "" -> acc
| _ -> f (s.Substring 1) (s.[0]::acc)
f str []
How can I know if the F# compiler turned it into a loop? Is there a way to find out without using Reflector (I have no experience with Reflector and I Don't know C#)?
Edit: Also, is it possible to write a tail recursive function without using an inner function, or is it necessary for the loop to reside in?
Also, Is there a function in F# std lib to run a given function a number of times, each time giving it the last output as input? Lets say I have a string, I want to run a function over the string then run it again over the resultant string and so on...
Unfortunately there is no trivial way.
It is not too hard to read the source code and use the types and determine whether something is a tail call by inspection (is it 'the last thing', and not in a 'try' block), but people second-guess themselves and make mistakes. There's no simple automated way (other than e.g. inspecting the generated code).
Of course, you can just try your function on a large piece of test data and see if it blows up or not.
The F# compiler will generate .tail IL instructions for all tail calls (unless the compiler flags to turn them off is used - used for when you want to keep stack frames for debugging), with the exception that directly tail-recursive functions will be optimized into loops. (EDIT: I think nowadays the F# compiler also fails to emit .tail in cases where it can prove there are no recursive loops through this call site; this is an optimization given that the .tail opcode is a little slower on many platforms.)
'tailcall' is a reserved keyword, with the idea that a future version of F# may allow you to write e.g.
tailcall func args
and then get a warning/error if it's not a tail call.
Only functions that are not naturally tail-recursive (and thus need an extra accumulator parameter) will 'force' you into the 'inner function' idiom.
Here's a code sample of what you asked:
let rec nTimes n f x =
if n = 0 then
x
else
nTimes (n-1) f (f x)
let r = nTimes 3 (fun s -> s ^ " is a rose") "A rose"
printfn "%s" r
I like the rule of thumb Paul Graham formulates in On Lisp: if there is work left to do, e.g. manipulating the recursive call output, then the call is not tail recursive.

Resources