# newbie question: flat_length example

Richard A. O'Keefe <>
Mon Jun 12 03:23:16 CEST 2006

```"Quan Ta" <> wrote:
-module(list2).
-export([flat_length/1]).

%% flat_length(List)
%%  Calculate the length of a list of lists.

Why are you writing a function that is already there
(lists:flatlength/1)?

flat_length([H,T], N) when list(H) ->
----------------------^

The error is almost certainly there; a comma where there
should be a vertical bar.

flat_length(T, flat_length(H, N));

Erlang's lists:flatten/1 is rather odd.
The traditional specification of flatten in Lisp goes something like this:

(define (flatten L)
(if (pair? L)
(append (flatten (car L)) (flatten (cdr L)))
(if (null? L)
'()
(list L))))

from which we conclude that (flatten 27) ==> (27).
The Erlang version,

flatten(List) when list(List) ->
do_flatten(List, []).

do_flatten([H|T], Tail) when list(H) ->
do_flatten(H, do_flatten(T, Tail));
do_flatten([H|T], Tail) ->
[H|do_flatten(T, Tail)];
do_flatten([], Tail) ->
Tail.

makes the top level quite inconsistent with lower levels.  Why?

The definition of lists:flatlength/1 (andwhyisthenameruntogetherlikethat?)
is this:

flatlength(List) ->
flatlength(List, 0).

flatlength([H|T], L) when list(H) ->
flatlength(H, flatlength(T, L));
flatlength([_|T], L) ->
flatlength(T, L + 1);
flatlength([], L) -> L.

This structure is similar (but not identical) to the structure of
flatten/1.  For the sake of efficiency, it shouldn't be.  The first
clause of flatlength/2 should be

flatlength([H|T], L) when list(H) ->
flatlength(T, flatlength(H, L));

```