Erlang BIFs inside lists module - erlang

Inspired from this question, I was curious to see how lists:reverse/2 is implemented in the source code inside lists.erl module.
I found out that there is no implementation for lists:reverse/2 inside lists.erl, but there is an implementation for lists:reverse/1 that uses lists:reverse/2:
reverse([] = L) ->
L;
reverse([_] = L) ->
L;
reverse([A, B]) ->
[B, A];
reverse([A, B | L]) ->
lists:reverse(L, [B, A]).
At the top of the file there are some lines that tells that lists:reverse/2 (and some other functions) are BIFs:
%%% BIFs
-export([keyfind/3, keymember/3, keysearch/3, member/2, reverse/2]).
...
%% Shadowed by erl_bif_types: lists:reverse/2
-spec reverse(List1, Tail) -> List2 when
List1 :: [T],
Tail :: term(),
List2 :: [T],
T :: term().
reverse(_, _) ->
erlang:nif_error(undef).
Question: First, I couldn't find the actual implementations of those BIFs. Where can I find them? Second, If someone also knows to explain why is it organized that way?

The lists BIFs are implemented in erts/emulator/beam/erl_bif_lists.c. Parts of heavily-used standard modules such as lists are implemented as BIFs for efficiency and performance.

Related

Concatenate list of lists

I'm trying to solve a problem (for practice) in which I have to write a function that concatenates all the elements in a given list of lists. In other words, if the input to this function is [[1,2], [3,4]], then the output should be [1,2,3,4] (order is not important).
I was able to achieve it by using the code below, but I'm wondering if it's inefficient or can be made more elegant.
%% To achieve this, we use a helper function and an accumulator %%
% Append elements of Src list into Dest list
append_list([], Dest) -> Dest;
append_list([H|T], Dest) -> append_list(T, [H|Dest]).
concatenate_acc([H|T], FinalList) ->
FinalList1 = append_list(H, FinalList),
concatenate_acc(T, FinalList1);
concatenate_acc([], FinalList) -> FinalList.
concatenate(L) -> concatenate_acc(L, []).
Sample output:
exercises2:concatenate([[1,2], [3,4]]).
[2,1,3,4]
Please comment on this!
Looking at the source code of lists:append/1 gives exactly what you need but in a simpler way I guess.
append([E]) -> E;
append([H|T]) -> H ++ append(T);
append([]) -> [].
It is always a good practice to take a look at the source code if there is already an implemented function in Erlang modules.
You may make a small modification to make it a tail recursion. Note that the accumulator Acc is on the right hand side of the ++ operator.
append2(List) -> append2(List,[]).
append2([], Acc) -> Acc;
append2([H|T],Acc) -> append2(T, H ++ Acc).

Our own tuple_to_list() function

I'm required to write my own tuple_to_list() function (yes, from the book) and came up with this in my erl file:
%% Our very own tuple_to_list function! %%
% First, the accumulator function
my_tuple_to_list_acc(T, L) -> [element(1, T) | L];
my_tuple_to_list_acc({}, L) -> L;
% Finally, the public face of the function
my_tuple_to_list(T) -> my_tuple_to_list_acc(T, []).
When I compile this, however, I get the following error in the shell:
28> c(lib_misc).
lib_misc.erl:34: head mismatch
lib_misc.erl:2: function my_tuple_to_list/1 undefined
error
I have no clue what "head mismatch" there is, and why is the function undefined (I've added it to the module export statement, though I doubt this has much to do with export statements)?
The other answer explains how to fix this, but not the reason. So: ; after a function definition clause means the next clause continues the definition, just like as for case and if branches. head mismatch means you have function clauses with different names and/or number of arguments in one definition. For the same reason, it is an error to have a clause ending with . followed by another clause with the same name and argument count.
Changing the order of the clauses is needed for a different reason, not because of the error. Clauses are always checked in order (again, same as for case and if) and your first clause already matches any two arguments. So the second would never be used.
Those errors mean that you didn't end definition of my_tuple_to_list_acc/2.
You should change order of first two code lines and add dot after them.
my_tuple_to_list_acc({}, L) -> L;
my_tuple_to_list_acc(T, L) -> [element(1, T) | L].
When you are interested in working tuple_to_list/1 implementation
1> T2L = fun (T) -> (fun F(_, 0, Acc) -> Acc; F(T, N, Acc) -> F(T, N-1, [element(N, T)|Acc]) end)(T, tuple_size(T), []) end.
#Fun<erl_eval.6.50752066>
2> T2L({}).
[]
3> T2L({a,b,c}).
[a,b,c]
Or in module
my_typle_to_list(_, 0, Acc) -> Acc;
my_typle_to_list(T, N, Acc) ->
my_typle_to_list(T, N-1, [element(N, T)|Acc]).
my_typle_to_list(T) ->
my_typle_to_list(T, tuple_size(T), []).
Note how I use decreasing index for tail recursive function.

Matching Patterns of Objects in F#

I have zero experience with F#. I started reading F# for C# Developers this weekend.
I had a problem recently (C# Code) where I had to search a list of .NET objects for subsets of objects that matched a certain pattern.
I described it as "regex style matching for objects" in the question. And I did get a great solution that I was happy with, and which seems to perform quite well.
But my recent interest in F# lead me to wonder whether functional programming might have an even better solution.
How would you solve this problem in F#?
Regex Style Pattern Matching in .NET Object Lists
One interesting functional concept that might be useful here is parser combinators. The idea is that you use composable functions that describe how to read some input and then compose parsers for complex patterns from a couple of primitives.
Parsers normally work over strings, but there is no reason why you couldn't use the same method to read a sequence of chromosomes.
With parser combinators, you would rewrite the "regex" as a composition of F# functions. Something like:
sequence [
zeroOrMore (chromosomeType R)
repeat 3 (chromosomeType B)
zeroOrMore (chromosomeType D) ]
This would give you a function that takes a list of chromosome objects and returns the parsed result - the subset of the list. The idea is that functions like zeroOrMore build parsers that detect certain patterns and you compose functions to build a parser - you get a function that you can just run on the input to parse it.
Explaining parser combinators is a bit too long for a SO answer, but it would probably be the most idiomatic F# approach to solving the problem.
This is a comment posted as an answer because it is to long for a comment.
Since it seems that Regular Expressions are working for your problem and that you might suspect that F# pattern matching or active patterns might be a better solution I will add some understanding.
The input R+B{3}D+ as I see it is a formal grammar, and as such will require a parser and evaluation engine, or the creation of something like a finite state machine. Since you know already that .Net Regex can solve this problem, why go through all of the trouble to recreate this with F#. Even using F# pattern matching and active patterns will not be easier than using RegEx.
Thus the problem is basically to convert the C# code to F# code and make use of RegEx. So you are asking us to translate your C# to F# and that is not a valid SO question.
EDIT
As Mark Seemann noted in a comment the only input we have is R+B{3}D+. So if your actual grammar is more complicated than what RegEx can handle then there might be a better solution in F#.
Hopefully this helps you understand what you are asking.
Building on the other answers: Start by implementing a parser combinator allowing composition of the type Parser<'a list>. Add parsers for the minimal grammar required by R+B{3}D+.
type Result<'T> = Success of 'T | Failure
type Parser<'T> = Parser of ('T -> Result<'T * 'T>)
module ListParser =
let (.>>.) (Parser f1) (Parser f2) =
Parser <| fun input ->
match f1 input with
| Failure -> Failure
| Success(value1, rest1) ->
match f2 rest1 with
| Failure -> Failure
| Success(value2, rest2) ->
Success(value1 # value2, rest2)
let oneOrMore what =
let rec aux gotOne acc = function
| x::xs when what = x -> aux true (x::acc) xs
| xss when gotOne -> Success(List.rev acc, xss)
| _ -> Failure
Parser <| aux false []
let exactly what n =
let rec aux i acc = function
| xss when i = 0 -> Success(List.rev acc, xss)
| x::xs when what = x -> aux (i - 1) (x::acc) xs
| _ -> Failure
Parser <| aux n []
Finally create a function which will run the parser repeatedly until the input list is exhausted.
open ListParser
let runForall (Parser f) xss =
let rec aux n acc xss =
match xss, f xss with
| [], _ -> List.rev acc
| _::xs, Failure -> aux (n + 1) acc xs
| _, Success(value, rest) ->
aux (n + List.length value) ((n + 1, value)::acc) rest
aux 0 [] xss
type ChromosomeType = R | B | D
[D;R;R;B;B;B;D;D;B;R;R;B;B;B;D;D;R;R;B;B;B;D;D]
|> runForall (oneOrMore R .>>. exactly B 3 .>>. oneOrMore D)
// val it : (int * ChromosomeType list) list =
// [(2, [R; R; B; B; B; D; D]); (10, [R; R; B; B; B; D; D]);
// (17, [R; R; B; B; B; D; D])]

Erlang ++ operator. Syntactic sugar, or separate operation?

Is Erlang's ++ operator simply syntactic sugar for lists:concat or is it a different operation altogether? I've tried searching this, but it's impossible to Google for "++" and get anything useful.
This is how the lists:concat/1 is implemented in the stdlib/lists module:
concat(List) ->
flatmap(fun thing_to_list/1, List).
Where:
flatmap(F, [Hd|Tail]) ->
F(Hd) ++ flatmap(F, Tail);
flatmap(F, []) when is_function(F, 1) -> [].
and:
thing_to_list(X) when is_integer(X) -> integer_to_list(X);
thing_to_list(X) when is_float(X) -> float_to_list(X);
thing_to_list(X) when is_atom(X) -> atom_to_list(X);
thing_to_list(X) when is_list(X) -> X. %Assumed to be a string
So, lists:concat/1 actually uses the '++' operator.
X ++ Y is in fact syntactic sugar for lists:append(X, Y).
http://www.erlang.org/doc/man/lists.html#append-2
The function lists:concat/2 is a different beast. The documentation describes it as follows: "Concatenates the text representation of the elements of Things. The elements of Things can be atoms, integers, floats or strings."
One important use of ++ has not been mentioned yet: In pattern matching. For example:
handle_url(URL = "http://" ++ _) ->
http_handler(URL);
handle_url(URL = "ftp://" ++ _) ->
ftp_handler(URL).
It's an entirely different operation. ++ is ordinary list appending. lists:concat takes a single argument (which must be a list), stringifies its elements, and concatenates the strings.
++ : http://www.erlang.org/doc/reference_manual/expressions.html
lists:concat : http://www.erlang.org/doc/man/lists.html
Most list functions actually uses the '++' operator:
for example the list:append/2:
The source code defines it as follows:
-spec append(List1, List2) -> List3 when
List1 :: [T],
List2 :: [T],
List3 :: [T],
T :: term().
append(L1, L2) -> L1 ++ L2.

What is the difference between the `fun` and `function` keywords?

Sometimes I see code like
let (alt : recognizer -> recognizer -> recognizer) =
fun a b p -> union (a p) (b p)
Or like:
let hd = function
Cons(x,xf) -> x
| Nil -> raise Empty
What is the difference between fun and function?
The semantics for this is the same as in F# (probably because F# is based on OCaml):
function allows the use of pattern matching (i.e. |), but consequently it can be passed only one argument.
function p_1 -> exp_1 | … | p_n -> exp_n
is equivalent to
fun exp -> match exp with p_1 -> exp_1 | … | p_n -> exp_n
fun does not allow pattern matching, but can be passed multiple arguments, e.g.
fun x y -> x + y
When either of the two forms can be used, fun is generally preferred due to its compactness.
See also OCaml documentation on Functions.
The way I think about it
function patterns
is shorthand for
(fun x -> match x with patterns)
where 'patterns' is e.g.
| Some(x) -> yadda | None -> blah
(And
fun args -> expr
is how you define a lambda.)
Russ Cam is correct in his answer.
Here is a posting on the OCaml list talking about it
http://caml.inria.fr/pub/ml-archives/ocaml-beginners/2003/11/b8036b7a0c1d082111d7a83c8f6dbfbb.en.html
function only allows for one argument but allows for pattern matching, while fun is the more general and flexible way to define a function.
I generally use fun unless there is a good reason to use function.
You can see this in the code you posted where the fun declaration takes 3 arguments and the function declaration does pattern matching on it's input
fun x1 ... xn -> e
is an abbreviation for
function x1 -> ... -> function xn -> e

Resources