[erlang-questions] Erlang newbie - quick critique?

Richard A. O'Keefe ok@REDACTED
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])).
	
Why "my_"?
You have a missing comma, but it's clear that you know about commas
in general.
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(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) ->
	     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 mailing list