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

Nick Coghlan ncoghlan at gmail.com
Fri Dec 4 03:38:03 EST 2015


On 4 December 2015 at 12:48, Andrew Barnert via Python-Dev
<python-dev at python.org> wrote:
> On Dec 3, 2015, at 17:25, Steven D'Aprano <steve at pearwood.info> wrote:
>> On Thu, Dec 03, 2015 at 09:25:53AM -0800, Andrew Barnert via Python-Dev wrote:
>>> 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'm one of the folks that use it that way, but I learned that
terminology *from* the Python language reference.

>> I wouldn't take either of those two languages as examples of best
>> practices in language design :-)
>
> No, but they seem to be the languages (along with C and Java) that people usually appeal to.
>
> You also found "literal" used the same way as JavaScript in Ruby, one of three languages in your quick survey. It's also used similarly in ML and Haskell. In Lisp, it has a completely different meaning (a quoted list).
>
> But as I said before, we can't use the word "literal" to contrast with comprehensions, because a large segment of the Python community (including you) would find that use of the word confusing and/or annoying because you intuitively think of the C/FORTRAN/etc. definition rather than the C++/Ruby/JS/Haskell definition. It doesn't matter whether that's a peculiar quirk of the Python community or not, whether there's a good reason for it or not, etc.; all that matters is that it's true.

Even though it's true, I'm not sure it's sufficient to rule out a
switch to "there are two kinds of literal" as the preferred
terminology.

The recent case that comes to mind is the new format string literals -
those can include arbitrary subexpressions, like container displays
and comprehensions, but the conclusion from the PEP 498 discussion was
that it makes the most sense to still consider them a kind of string
literal.

There's also a relatively straightforward way of defining the key
semantic different between a literal and a normal constructor call:
with a literal, there's no way to override the type of the resulting
object, while a constructor call can be monkeypatched like any other
callable.

The distinction that arises for containers is then the one that Chris
Angelico pointed out: a container literal may have constant content,
*or* it may have dynamic content. If we switched from calling things
"displays" to calling them "dynamic literals", I'd be surprised if too
many folks that were able to figure out what "display" meant struggled
to make the transition.

Summarising that idea:

* literals: any of the dedicated expressions that produce an instance
of a builtin type
* constant literal: literals that produce a constant object that can
be cached in the bytecode
* dynamic literal: literals containing dynamic subexpressions that
can't be pre-calculated
* display: legacy term for a dynamic literal (originally inherited from ABC)
* comprehension: a dynamic literal that creates a new container from
an existing iterable
* lexical literal: constant literals and dynamic string literals [1]

The ast.literal_eval() docs would need a slight adjustment to refer to
"literals (excluding container comprehensions and generator
expressions)", rather than the current "literals and container
displays".

Regards,
Nick.

[1] https://docs.python.org/dev/reference/lexical_analysis.html#literals

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-Dev mailing list