[erlang-questions] behavior of lists:append/1

Raimo Niskanen raimo+erlang-questions@REDACTED
Mon Sep 23 10:08:56 CEST 2019


On Thu, Sep 19, 2019 at 06:54:29AM +0900, zxq9 wrote:
> On 2019/09/18 21:00, Raimo Niskanen wrote:
> > On Tue, Sep 17, 2019 at 11:25:11PM +0900, zxq9 wrote:
> >> On 2019/09/17 22:13, Raimo Niskanen wrote:
> >>> On Mon, Sep 16, 2019 at 10:53:57PM +0900, zxq9 wrote:
> >>> No.
> >>>
> >>> lists:append/2 can be used and *is* used by existing code to construct
> >>> improper lists.  It would break backwards compatibility.
> > 
> > ...to construct improper lists even as in appending a tail element (that is
> > need not be a list) to a list...
> 
> At least here we can put down a line and say "that's a violation of the 
> typespec", because it is:
> http://erlang.org/doc/man/lists.html#append-2

You are right.

I dug up this discussion:
    http://erlang.org/pipermail/erlang-questions/2013-March/073022.html

And from that I draw these conclusions:
* The type specs and documentation describe the intention of the API
* If the arguments follow the type spec, so will the return value
* If not, it will not, but there is no guarantee for e.g an exception
* Code may be more lenient that its type spec

So, if you use lists:append/1,2 to construct an improper list you will get
a Dialyzer warning, even though the code works.

We will not change the implementation of lists:append/1,2 for effeciency
and legacy reasons.  If anything should change it should be the type spec
and documentation, but I see no good reason why.  Now you get a warning
from Dialyzer for "bad style" according to some definition of it, which
many think is a good thing.

Dialyzer only makes guarantees about code that follows the type specs.
Code that does not follow the type specs might work anyway.

I suspect this whole thread originates in a misunderstanding about what
type specs specify and not...

> 
> So if we want to continue to use append/2 to *create* improper lists 
> (which I've never once encountered anywhere in the last decade, but 
> maybe you've got some examples of super wizard code where this is 
> necessary?) then the typespec should be changed, otherwise I think it 
> isn't unreasonable to do at +O(1) cost at runtime what Dialyzer would 
> do, or just leave things as they are and actively discourage deliberate 
> construction of improper lists via append/2.
> 
> I'm not particularly opposed to changing the typespec to say "List2 can 
> be whatever because who cares whether lists are lists or not? Let's 
> ditch type sanity because a handful of people feel like it! WOOO!" but I 
> *do* believe it is inconsistent to the extreme to say "Well, we're going 
> to have Dialyzer (and all users who read the documentation... har har 
> har! Joke's on them!) believe that both arguments must be lists!" and 
> then in unofficial -- but heavily referenced -- discussion have an OTP 
> developer say "well, append/2 is used by some people to deliberately 
> construct improper lists, so let's just ignore the discussion entirely 
> even though there is actually a way to efficiently check this at runtime".
> 
> -Craig

-- 

/ Raimo Niskanen, Erlang/OTP, Ericsson AB



More information about the erlang-questions mailing list