About Erlang function, especially the function's identifier - erlang

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.

Related

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.

Knowing the number of parameters of a passed function (erlang)

In ERLANG: Assume we have a function f() that takes F1 as inputs where F1 is a function. Is there a way to know the number of input parameters of F1.
I feel somehow there IS a solution, but I am not sure. for instance:
-module(high).
-compile(export_all).
f1() -> 1.
f2(X) -> X.
f3(X, Y) -> {X,Y}.
run(F) -> io:format("F ~p ~n", [F]).
So, is there any way for function run/1 to know information about the passed function [mainly the number of input parameters of the passed function].
Note: Please be informed that this is a theoretical question.
Note: is the code of apply(fun,[arguments]) available in open-source .. this may hep me I guess.
erlang:fun_info(Fun,arity).
For example
F = fun(A,B) -> A+B end.
#Fun<erl_eval.12.111823515>
3> erlang:fun_info(F,arity).
{arity,2}
You can use module_info/1 to get info about your module.
module_info/1
The call module_info(Key), where Key is an atom, returns a single piece of information about the module.
The following values are allowed for Key:
...
exports
Returns a list of {Name,Arity} tuples with all exported functions in the module.
functions
Returns a list of {Name,Arity} tuples with all functions in the module.
http://erlang.org/doc/reference_manual/modules.html
run(F) -> find_value(F,module_info(exports)).
find_value(Key, List) ->
case lists:keyfind(Key, 1, List) of
{Key, Result} -> {Key,Result};
false -> io:format("There is no function called ~w.~n", [Key])
end.

Convert a string into a fun

I'm trying to get around a problem with file:consult/1 not allowing tuples with fun in them like in this example:
{add_one, fun(X) -> X+1 end}.
To get around this I'm considering writing the fun inside a string and evaluating it
{add_one, "fun(X) -> X+1 end"}.
The question is. How do I convert the string into a fun?
parse_fun_expr(S) ->
{ok, Ts, _} = erl_scan:string(S),
{ok, Exprs} = erl_parse:parse_exprs(Ts),
{value, Fun, _} = erl_eval:exprs(Exprs, []),
Fun.
Note that you need a period at the end of your fun expression, e.g. S = "fun(X) -> X + 1 end.".
file:script/1 almost does what you want - it evaluates a series of erlang expressions from a file and returns the last result. You could use it in place of file:consult/1 but you'd need to change the format of the file from "term. term. term." giving [term, term ,term] to "[term, term , term]." giving [term, term, term] - place a single expression in the file instead of a sequence.
I'd like to point out that Zed's answer creates an interpreted fun. When the fun is called it enters the evaluator which starts to evaluates the abstract syntax tree returned by erl_parse:parse_exprs/1 that it has captured. Looking at the fun created:
11> erlang:fun_info(Fun, env).
{env,[[],none,none,
[{clause,1,
[{var,1,'X'}],
[],
[{op,1,'+',{var,1,'X'},{integer,1,1}}]}]]}
12> erlang:fun_info(Fun, module).
{module,erl_eval}
One can see that it has closed over the parsed abstract syntax tree as seen in the env info, and it is a fun created inside erlang_eval as seen in the module info.
It is possible to use the erlang compiler to create a compiled module at runtime, and a pointer toward that is compile:forms/2 and code:load_binary/3. But the details of that should probably go into another stackoverflow question.
Maybe by using the erl_eval module?
2> F =fun(Str,Binding) ->
{ok,Ts,_} = erl_scan:string(Str),
Ts1 = case lists:reverse(Ts) of
[{dot,_}|_] -> Ts;
TsR -> lists:reverse([{dot,1} | TsR])
end,
{ok,Expr} = erl_parse:parse_exprs(Ts1),
erl_eval:exprs(Expr, Binding) end.
#Fun<erl_eval.12.111823515>
3> F("A=23.",[]).
{value,23,[{'A',23}]}
5> F("12+B.",[{'B',23}]).
{value,35,[{'B',23}]}

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