A dialyzer question on improper list detection of list appends

Jesper Louis Andersen jesper.louis.andersen@REDACTED
Thu Aug 19 21:24:12 CEST 2010


I have some code which goes like this (in gproc):

qlc_next(_, '$end_of_table') -> [];
qlc_next(Scope, K) ->
    case ets:lookup(?TAB, K) of
        [{{Key,_}, Pid, V}] ->
            [{Key,Pid,V} | fun() -> qlc_next(Scope, next(Scope, K)) end];
        [] ->
            qlc_next(Scope, next(Scope, K))
    end.

The dialyzer does not like it, it reports:

gproc.erl:1149: Cons will produce an improper list since its 2nd
argument is fun(() -> maybe_improper_list({_,_,_},fun(() ->
maybe_improper_list(any(),fun(() -> any()) | [])) | []))

This is entirely true and the warning is in addition good. Improper
lists is somewhat of a mistake :) Since this is a problem in general
with QLCs, and qlc_next/1 I wondered how it was fixed for, say, ETS
tables in Erlang. In lib/stdlib/src/ets.erl we find:

qlc_next(_Tab, '$end_of_table') ->
    [];
qlc_next(Tab, Key) ->
    ets:lookup(Tab, Key) ++ fun() -> qlc_next(Tab, ets:next(Tab, Key)) end.

Hmm, clever! So I change the code from gproc to:

@@ -1157,7 +1146,7 @@ qlc_next(_, '$end_of_table') -> [];
 qlc_next(Scope, K) ->
     case ets:lookup(?TAB, K) of
         [{{Key,_}, Pid, V}] ->
-            [{Key,Pid,V} | fun() -> qlc_next(Scope, next(Scope, K)) end];
+            [{Key,Pid,V}] ++ fun() -> qlc_next(Scope, next(Scope, K)) end;
         [] ->
             qlc_next(Scope, next(Scope, K))
     end.
@@ -1166,7 +1155,7 @@ qlc_prev(_, '$end_of_table') -> [];
 qlc_prev(Scope, K) ->
     case ets:lookup(?TAB, K) of
         [{{Key,_},Pid,V}] ->
-            [{Key,Pid,V} | fun() -> qlc_prev(Scope, prev(Scope, K)) end];
+            [{Key,Pid,V}] ++ fun() -> qlc_prev(Scope, prev(Scope, K)) end;
         [] ->
             qlc_prev(Scope, prev(Scope, K))
     end.

and magically, the Dialyzer warning disappears. Now the million dollar
question is: Why? Both are equivalent improper lists, right? Maybe
Kostis or someone else with dialyzer-fu can shed some light on this?

-- 
J.


More information about the erlang-questions mailing list