[erlang-questions] lists:concat with non-string sublists

Kostis Sagonas kostis@REDACTED
Tue May 22 19:55:39 CEST 2012


On 05/22/2012 07:27 PM, James Aimonetti wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> According to the docs[1], lists:concat/1 converts the elements in the
> list to their string representation. The spec for Thing being atom() |
> integer() | float() | string().
>
> However, in the actual implementation in lists.erl, the is_list/1
> guard is used in thing_to_list/1, not a more specific check that the
> list is a string().
>
> So, according to the docs, I would expect:
>
>> lists:concat([[{foo, 123}], [{bar, 234}]]).
>
> to fail. It doesn't, and returns [{foo, 123}, {bar,234}]. Reading the
> implementation of concat/1 its easy to see why this works.
>
> My question is, should the docs be updated to allow Thing to be a list
> of any term so Dialyzer won't issue an error when using sub-lists with
> tuples (in my case, the result of an ets:match/2), or should
> thing_to_list/1 do more inspection of a list element?

You are reading the specs in the wrong way, I am afraid.  Specs are 
contracts: they describe what guarantee the current implementation of a 
function provides to its callers.  The implementation may allow for more 
than that, but the spec is there to tell you that if you break its 
premises (the types in its arguments) you really have no guarantee that 
your code will work without errors the next OTP version.

Typical example of this is something like lists:append/2:

   -spec append(list(), list()) -> list(). % or something more involved

but the implementation may allow for calls of the form:

   Eshell V5.9.2  (abort with ^G)
   1> lists:append([], 3.14).
   3.14

but you probably would not want to change its spec to allow term() for 
its second argument and return, would you?

Kostis



More information about the erlang-questions mailing list