PEP 802 – Display Syntax for the Empty Set
- Author:
- Adam Turner <python at quite.org.uk>
- Discussions-To:
- Pending
- Status:
- Draft
- Type:
- Standards Track
- Created:
- 08-Aug-2025
- Python-Version:
- 3.15
Abstract
We propose a new notation, {/}
, to construct and represent the empty set.
This is modelled after the corresponding mathematical symbol ‘∅’.
This complements the existing notation for empty tuples, lists, and
dictionaries, which use ()
, []
, and {}
respectively.
Motivation
Sets are currently the only built-in collection type that have a display syntax, but no notation to express an empty collection. The Python Language Reference notes this, stating:
An empty set cannot be constructed with{}
; this literal constructs an empty dictionary.
This can be confusing for beginners, especially those coming to the language from a scientific or mathematical background, where sets may be in more common use than dictionaries or maps.
A syntax notation for the empty set has the important benefit of not requiring
a name lookup (unlike set()
).
{/}
will always have a consistent meaning, improving teachability
of core concepts to beginners.
For example, users must be careful not to use set as a local variable name,
as doing so prevents constructing new sets.
This can be frustrating as beginners may not know how to recover the
set
type if they have overriden the name:
techniques to do so (e.g. type({1}-{1})
) are not immediately obvious.
Finally, this may be helpful for users who do not speak English, as it provides a culture-free notation for a common data structure that is built into Python.
Rationale
Sets were introduced to Python 2.2 via PEP 218, which did not include
set notation, but discussed the idea of {-}
for the empty set:
The PEP originally proposed{1,2,3}
as the set notation and{-}
for the empty set. Experience with Python 2.3’ssets.py
showed that the notation was not necessary. Also, there was some risk of making dictionaries less instantly recognizable.
Python 3.0 introduced set literals (PEP 3100), but again chose not to introduce notation for the empty set, which was omitted out of pragmatism ([5], [6]).
Since then, the topic has been discussed several times, with various proposals, including:
- Changing
{}
to mean an empty set and using{:}
for an empty dictionary ([9], [4]) - A Unicode character (e.g.
∅
orϕ
) ([7]) <>
([11], [3])s{}
([10]){*()}
, perhaps optimising to compile this to theBUILD_SET
opcode ([2]){-}
([8]){,}
([1]){/}
([9])set()
(i.e. doing nothing)
The authors propose {/}
as the notation,
being in their opinion the best of these options.
It is simple and concise, with the benefit of resembling the mathematical
notation for the empty set, ∅.
This makes it an easier mnemonic to explain than several in the language,
such as **
for exponentiation or @
for matrix multiplication.
Brief summaries for the other proposals may be found in Rejected Ideas.
Specification
The grammar for set displays will become:
set_display ::= "{" ("/" | flexible_expression_list | comprehension) "}"
{/}
will become the default syntax for the empty set.
>>> type({/})
<class 'set'>
>>> {/} == set()
True
The representation and string forms of the empty set will change to '{/}'
.
>>> repr({/})
'{/}'
>>> str({/})
'{/}'
There will be no behavioural changes to set
objects.
Backwards Compatibility
Code that relies on the repr()
or str()
of the empty set
will no longer work, because the representation will change.
There will be no other backwards incompatibile changes,
all current constructors for the empty set will continue to work,
and the behaviour of the set
type will remain unchanged.
Security Implications
None.
How to Teach This
Experienced users can be taught that {/}
is the new spelling for set()
,
and that it is equivalent in all other ways.
For new users, sets can be introduced through syntax, noting that the four
built-in collection types with syntax all have empty forms:
()
, []
, {/}
, and {}
.
The empty set uses a forwards slash to differentiate it from
an empty dictionary.
It uses this syntax because it looks like the mathematical symbol
for the empty set (’∅’).
It is also similar to the syntax for other sets,
which use a comma to separate elements, e.g. {2, 3, 5}
.
These facts can be used as a helpful mnemonic.
Reference Implementation
Forthcoming.
Rejected Ideas
Change {}
to mean an empty set and use {:}
for an empty dictionary
This would be an entirely backwards incompatible change,
all current dict
objects would become sets.
Use a Unicode character (e.g. ∅
or ϕ
)
The Unicode character ‘U+2205 ∅ EMPTY SET’ is not currently a valid identifier. Introducing a Unicode character as syntax would be hard to use, as it does not appear on standard keyboards.
Using other characters that look like ∅, such as ‘U+03C6 ϕ GREEK SMALL LETTER PHI’ or ‘U+00D8 Ø LATIN CAPITAL LETTER O WITH STROKE’, would be more confusing with the same drawbacks of using a Unicode character.
Use the <>
syntax
This syntax has historic use as the inequality operator. It does not have a resemblance to the syntax for non-empty sets. This would be harder to explain than this PEP’s proposal.
Use the s{}
syntax
This syntax may cause confusion with s
as a local variable.
The only current use of prefixes of this kind is for string literals.
This would be harder to explain than this PEP’s proposal.
Use the {*()}
syntax
This relies on unpacking the empty tuple into a set, creating an empty set. This has the benefit of support since Python 3.5 (PEP 448), but is unwieldy and complicated to explain; it was not designed for this purpose.
Use the {-}
syntax
This syntax was originally proposed in PEP 218,
but removed from the PEP before it was accepted.
The authors prefer {/}
due to the resemblance to ∅.
Use the {,}
syntax
This is the authors’ next preferred option.
However, if a single comma were to be used to represent an empty collection,
it may be confusing why this could not be used for empty tuples or lists.
In time, there might be proposals to add support for [,]
and (,)
.
This conflicts with the general principle that
‘there should be one– and preferably only one –obvious way to do it’.
Having a visibly different form, in {/}
, helps to reinforce the idea
that the syntax for the empty set is a special case, rather than a general rule
for all empty collections.
Open Issues
None.
Footnotes
Copyright
This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive.
Source: https://github.com/python/peps/blob/main/peps/pep-0802.rst
Last modified: 2025-08-08 04:47:40 GMT