Erlang pass-by-reference nuances - erlang

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].

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.

Understanding '_' variable in Erlang

Erlang newbie here. I am from a Java background and am finding Erlan rather interesting. Am following the excellent book "Learn You some Erlang".
Here's an example for recursion as given in the book for reversing the order of a List:
tail_reverse(L) -> tail_reverse(L,[]).
tail_reverse([],Acc) -> Acc;
tail_reverse([H|T],Acc) -> tail_reverse(T, [H|Acc]).
This works as expected. However, if I changed the code to:
tail_reverse(L) -> tail_reverse(L,[]).
tail_reverse([],_) -> [];
tail_reverse([H|T],Acc) -> tail_reverse(T, [H|Acc]).
this now always returns [] irrespective of the contents of the List passed. So it seems that the line tail_reverse([],_) -> []; is the one getting called. However, my understanding is that it should be called only if the first parameter is empty and _ is just a placeholder.
What am I missing here?
This line:
tail_reverse([], Acc) -> Acc
is supposed to return the accumulating argument Acc when the processed list becomes empty. You replaced it with:
tail_reverse([], _) -> []
which is executed in the same case (the bottom of the recursion), but ignores the previously done work and returns the empty list.
As for the _ variable, it has not much to do with your problem, but it's explained in this answer.
#bereal's answer is correct. However, I am going to provide my own answer to general question of "How does the _ variable work in Erlang. I recently wrote a blog post on the _ variable:
The anonymous variable is denoted by a single underscore (_). The anonymous variable is used when a variable is required but the value needs to be ignored. The anonymous variable never actually has the value bound to it. Since the value is never bound it can be used multiple times in a pattern and each time it is allowed to match a different value. Example:
1> {_, _} = {foo, bar}.
{foo, bar}
2> _.
* 1: variable '_' is unbound
4> {_, Second} = {foo, bar}.
{foo, bar}
5> _.
* 1: variable '_' is unbound
6> Second.
bar
More is available here:
http://stratus3d.com/blog/2014/11/05/everything-you-need-to-know-about-erlangs-magic-variable/

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.

About Erlang function, especially the function's identifier

I have a question about Erlang function. See the code in Erlang shell:
1> F1 = fun() -> timer:sleep(1000) end.
#Fun<erl_eval.20.111823515>
2> F2 = fun() -> io:format("hello world~n", []) end.
#Fun<erl_eval.20.111823515>
F1 and F2 are different, but why are they both having an identifier #Fun<erl_eval.20.111823515>? And what do these magic numbers mean?
There is a paragraph in ERTS Manual, says:
When interpreting the data for a process, it is helpful to know that anonymous
function objects (funs) are given a name constructed from the name of the
function in which they are created, and a number (starting with 0) indicating
the number of that fun within that function.
I also can not catch the meaning of this paragraph, can you please explain it?
Don't read too much meaning into the names of anonymous functions. All you can safely get out of it is the name of the module in which they were created. You can try counting funs in the module to find which one but I wouldn't bother.
That being said, there is a reason why both of the funs have the same name. Expressions entered in the shell are not compiled but are evaluated by the interpreter in the module erl_eval. This module has one fun for interpreting funs of each arity. So there is one fun in erl_eval for funs of arity 1, #Fun<erl_eval.20.111823515>. Hacky, but it works.
Consider the same functions in a module (lets not think of shell right now)
-module(fun_test).
-export([test/0]).
test() ->
F1 = fun() -> timer:sleep(1000) end,
F2 = fun() -> io:format("hello world~n", []) end,
{F1,F2}.
Output is as follows
1> fun_test:test().
{#Fun<fun_test.0.78536365>,#Fun<fun_test.1.78536365>}
In the above example the anonymous function objects F1 and F2 names are constructed using the name of the module fun_test, unique identifier 0 and 1 (incremental for each function in the module), return addresses etc. as defined in the ERTS Manual. This explains the paragraph mentioned in the manual. Though not very useful, the function numbering is handy during debugging as -test/0-fun-1- in the trace will tell you that anonymous function 1 in test/0 function is the source of the error.
For the functions defined in the shell use erl_eval module as explained by rvirding. The result of function object declaration is the return of erl_eval for that arity. So always the same value is returned for that arity.

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