[erlang-questions] Erlang newbie - quick critique?
Richard A. O'Keefe
Thu Sep 7 07:40:18 CEST 2006
This is what I've drawn up on paper -
my_join([H|T] Delimiter) ->
myjoin(T, Delimiter, [H])).
You have a missing comma, but it's clear that you know about commas
There's another slip: you are calling myjoin/3, but it's
actually called my_join/3.
Let's think about this.
What should it mean to join no strings?
It could be an error, but why not return the empty string?
join(Strings, " ").
join(, _) -> "";
join([H|T], Delimiter) ->
H ++ join_loop(T, Delimiter).
join_loop(, _) -> "";
join_loop([H|T], Delimiter) ->
Delimiter ++ H ++ join_loop(T, Delimiter).
my_join([H|T], Delimiter, Acc) ->
myjoin(T, Delimiter, lists:append([Acc, Delimiter, H]) ).
my_join(, Delimiter, Acc) ->
In Prolog, each clause of a predicate is terminated by a full stop.
In Erlang, the clauses of a function are separated by semicolons;
only the last clause has a full stop.
Apart from using lists:append([X,Y,Z]) when you could just do X++Y++Z,
which isn't actually _wrong_, just awkward, there's only one serious
problem with the way you are approaching this.
You are writing this as a tail recursive loop, passing an accumulator.
In general, that's an EXCELLENT thing to do.
Unfortunately, list concatenation is not a constant time operation.
The cost of A++B is O(length(A)), and your Acc keeps on getting bigger
and bigger. Not only that, you keep on making a new Acc and throwing
the old one entirely away, so you are creating a lot of garbage.
In this particular case a body recursion is the right thing to do;
join_loop/2 never makes a list cell that won't be part of the final
result, and the total cost is linear in the size of the input.
Well, it's proportional to
sum(length(X) | X <- List) +
length(List) * length(Delimiter).
Put it this way, it is linear in the size of the output.
What I'm concerned about is the [H] and the lists:append call with the
arguments being inserted into two square brackets to make a new list.
Would that work? It's a Python thing, or do I need to use a function
to make it a list?
Square brackets are how you make a list.
More information about the erlang-questions