[Python-Dev] Python Language Reference has no mention of list comÃprehensions

Steven D'Aprano steve at pearwood.info
Thu Dec 3 20:25:14 EST 2015


On Thu, Dec 03, 2015 at 09:25:53AM -0800, Andrew Barnert via Python-Dev wrote:
> > On Dec 3, 2015, at 08:15, MRAB <python at mrabarnett.plus.com> wrote:
> > 
> >>> On 2015-12-03 15:09, Random832 wrote:
> >>> On 2015-12-03, Laura Creighton <lac at openend.se> wrote:
> >>> Who came up with the word 'display' and what does it have going for
> >>> it that I have missed?  Right now I think its chief virtue is that
> >>> it is a meaningless noun.  (But not meaningless enough, as I
> >>> associate displays with output, not construction).

I completely agree with Laura here -- to me "display" means output, not 
construction, no matter what the functional programming community says 
:-) but I suppose the connection is that you can construct a list using
the same syntax used to display that list: [1, 2, 3] say.

I don't think the term "display" will ever feel natural to me, but I 
have got used to it.


Random832 wrote:

> >> In a recent discussion it seemed like people mainly use it
> >> because they don't like using "literal" for things other than
> >> single token constants.  In most other languages' contexts the
> >> equivalent thing would be called a literal.

I'm not sure where you get "most" other languages from. At the very 
least, I'd want to see a language survey. I did a *very* fast one (an 
entire three languages *wink*) and found these results:

The equivalent of a list [1, a, func(), x+y] is called:

"display" (Python)

"literal" (Ruby)

"constructor" (Lua)

http://ruby-doc.org/core-2.1.1/doc/syntax/literals_rdoc.html#label-Arrays
http://www.lua.org/manual/5.1/manual.html

Of the three, I think Lua's terminology is least worst.


MRAB:
> > "Literals" also tend to be constants, or be constructed out of
> > constants.

Andrew: 
> I've seen people saying that before, but I don't know where they get 
> that. It's certainly not the way, say, C++ or JavaScript use the term. 

I wouldn't take either of those two languages as examples of best 
practices in language design :-)

"Literal" in computing has usually meant something like MRAB's sense 
for close on 20 years, at least. This definition is from FOLDOC (Free 
On-Line Dictionary Of Computing), dated 1996-01-23:

literal

   <programming> A constant made available to a process, by
   inclusion in the executable text.  Most modern systems do not
   allow texts to modify themselves during execution, so literals
   are indeed constant; their value is written at compile-time
   and is read-only at run time.

   In contrast, values placed in variables or files and accessed
   by the process via a symbolic name, can be changed during
   execution.  This may be an asset.  For example, messages can
   be given in a choice of languages by placing the translation
   in a file.

   Literals are used when such modification is not desired.  The
   name of the file mentioned above (not its content), or a
   physical constant such as 3.14159, might be coded as a
   literal.  Literals can be accessed quickly, a potential
   advantage of their use.


I think that an important factor is that "literal" is a description of 
something in source code, like "expression" and "declaration". We surely 
don't want a distinction between the *values* x and y below:

x = 3.14159

y = 4.0 - len("a")
y += 0.14159

but we might want to distinguish between the way they are constructed: x 
is constructed from a literal, y is not.


[...]
> > A list comprehension can contain functions, etc.
> 
> A non-comprehension display can include function calls, lambdas, or 
> any other kind of expression, just as easily as a comprehension can. 
> Is [1, x, f(y), lambda z: w+z] a literal? If so, why isn't [i*x for i 
> in y] a literal?

I wouldn't call either a literal.

I often find myself (mis)using the term "literal" to describe 
constructing a list using a display where each item is itself a literal:

x = [1, 2, 3]

(or at least something which *could* have been a literal, if Python's 
parsing rules were just a tiny bit different, like -1 or 2+3j) but I 
accept that's an abuse of the term. But I certainly wouldn't use the 
term to describe a list constructed from non-literal parts:

x = [a, b**2, func() or None]

and absolutely not for a list comprehension.


> The problem is that we need a word that distinguishes the former; 
> trying to press "literal" into service to help the distinction doesn't 
> help.
> 
> At some point, Python distinguished between displays and 
> comprehensions; I'm assuming someone realized there's no principled 
> sense in which a comprehension isn't also a display, and now we're 
> stuck with no word again.

I don't think comprehensions are displays. They certainly look 
different, both in input form and output form:

py> [1, 2, 4, 8, 16]  # Display.
[1, 2, 4, 8, 16]
py> [2**n for n in range(5)]  # Comprehension.
[1, 2, 4, 8, 16]


Lists display using display syntax, not comprehension syntax. Obviously 
the list you get (the value of the object) is the same whichever syntax 
you use, but the syntax is quite different.


[...]
> Ultimately, the best we have is "displays that aren't comprehensions" 
> or "constructions that aren't comprehensions".

I don't think that's right. We can easily distinguish a display from a 
comprehension:

- displays use the comma-separated item syntax [1, 2, 3], the same 
syntax used for output;

- comprehensions use a variation on "set builder" syntax from 
mathematics, using for-loop syntax [expr for x in seq].

I don't see any good reason for maintaining that there's just one 
syntax, "display", which comes in two forms: a comma-separated set of 
values, or a for-loop. The only thing they have in common (syntax-wise) 
is that they both use [ ] as delimiters. They look different, they 
behave differently, and only one matches what the list actually displays 
as. Why use one term for what is clearly two distinct (if related) 
syntaxes?



-- 
Steve


More information about the Python-Dev mailing list