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