Skip to content

Commit 8e7112a

Browse files
authored
PEP 802: Display Syntax for the Empty Set (#4531)
1 parent be15a36 commit 8e7112a

File tree

2 files changed

+276
-0
lines changed

2 files changed

+276
-0
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,7 @@ peps/pep-0798.rst @JelleZijlstra
677677
peps/pep-0799.rst @pablogsal
678678
peps/pep-0800.rst @JelleZijlstra
679679
peps/pep-0801.rst @warsaw
680+
peps/pep-0802.rst @AA-Turner
680681
# ...
681682
peps/pep-2026.rst @hugovk
682683
# ...

peps/pep-0802.rst

Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
PEP: 802
2+
Title: Display Syntax for the Empty Set
3+
Author: Adam Turner <[email protected]>
4+
Discussions-To: Pending
5+
Status: Draft
6+
Type: Standards Track
7+
Created: 08-Aug-2025
8+
Python-Version: 3.15
9+
10+
11+
Abstract
12+
========
13+
14+
We propose a new notation, ``{/}``, to construct and represent the empty set.
15+
This is modelled after the corresponding mathematical symbol ':math:`\emptyset`'.
16+
17+
This complements the existing notation for empty tuples, lists, and
18+
dictionaries, which use ``()``, ``[]``, and ``{}`` respectively.
19+
20+
21+
Motivation
22+
==========
23+
24+
Sets are currently the only built-in collection type that have a
25+
:ref:`display syntax <python:comprehensions>`,
26+
but no notation to express an empty collection.
27+
The :ref:`Python Language Reference <python:set>` notes this, stating:
28+
29+
An empty set cannot be constructed with ``{}``;
30+
this literal constructs an empty dictionary.
31+
32+
This can be confusing for beginners, especially those coming to the language
33+
from a scientific or mathematical background, where sets may be in more common
34+
use than dictionaries or maps.
35+
36+
A syntax notation for the empty set has the important benefit of not requiring
37+
a name lookup (unlike ``set()``).
38+
``{/}`` will always have a consistent meaning, improving teachability
39+
of core concepts to beginners.
40+
For example, users must be careful not to use ``set`` as a local variable name,
41+
as doing so prevents constructing new sets.
42+
This can be frustrating as beginners may not know how to recover the
43+
:py:class:`set` type if they have overriden the name:
44+
techniques to do so (e.g. ``type({1}-{1})``) are not immediately obvious.
45+
46+
Finally, this may be helpful for users who do not speak English,
47+
as it provides a culture-free notation for a common data structure
48+
that is built into the language.
49+
50+
51+
Rationale
52+
=========
53+
54+
Sets were introduced to Python 2.2 via :pep:`218`, which did not include
55+
set notation, but discussed the idea of ``{-}`` for the empty set:
56+
57+
The PEP originally proposed ``{1,2,3}`` as the set notation and ``{-}`` for
58+
the empty set. Experience with Python 2.3's ``sets.py`` showed that
59+
the notation was not necessary. Also, there was some risk of making
60+
dictionaries less instantly recognizable.
61+
62+
Python 3.0 introduced set literals (:pep:`3100`), but again chose not to
63+
introduce notation for the empty set, which was omitted out of pragmatism
64+
(`python-3000, April 2006`_, `python-3000, May 2006`_).
65+
66+
Since then, the topic has been discussed several times,
67+
with various proposals, including:
68+
69+
#. Changing ``{}`` to mean an empty set and using ``{:}`` for an empty dictionary
70+
(`python-ideas, January 2008`_, `Discourse, March 2023`_)
71+
#. A Unicode character (e.g. ```` or ``ϕ``)
72+
(`python-ideas, April 2021`_)
73+
#. ``<>``
74+
(`python-ideas, November 2010`_, `Discourse, December 2024`_)
75+
#. ``s{}``
76+
(`python-ideas, June 2009`_)
77+
#. ``{*()}``, perhaps optimising to compile this to the ``BUILD_SET`` opcode
78+
(`Discourse, August 2025 (#37)`_)
79+
#. ``{-}``
80+
(`python-ideas, August 2020`_)
81+
#. ``{,}``
82+
(`Discourse, August 2025`_)
83+
#. ``{/}``
84+
(`python-ideas, January 2008`_)
85+
#. ``set()`` (i.e. doing nothing)
86+
87+
The authors propose ``{/}`` as the notation,
88+
being in their opinion the best of these options.
89+
It is simple and concise, with the benefit of resembling the mathematical
90+
notation for the empty set, :math:`\emptyset`.
91+
This makes it an easier mnemonic to explain than several in the language,
92+
such as ``**`` for exponentiation or ``@`` for matrix multiplication.
93+
94+
The ``{/}`` notation was also the most popular in a `recent Discourse poll`_,
95+
selected by 41% of respondents overall and 60% of those voting for a new syntax.
96+
97+
Brief summaries for the other proposals may be found in `Rejected Ideas`_.
98+
99+
100+
Specification
101+
=============
102+
103+
The grammar for set displays will become:
104+
105+
.. productionlist:: python-grammar
106+
set_display: "{" ("/" | flexible_expression_list | comprehension) "}"
107+
108+
``{/}`` will become the default syntax for the empty set.
109+
110+
.. code-block:: python
111+
112+
>>> type({/})
113+
<class 'set'>
114+
>>> {/} == set()
115+
True
116+
117+
The representation and string forms of the empty set will change to ``'{/}'``.
118+
119+
.. code-block:: python
120+
121+
>>> repr({/})
122+
'{/}'
123+
>>> str({/})
124+
'{/}'
125+
126+
There will be no behavioural changes to :py:class:`set` objects.
127+
128+
129+
Backwards Compatibility
130+
=======================
131+
132+
Code that relies on the ``repr()`` or ``str()`` of the empty set
133+
will no longer work, because the representation will change.
134+
135+
There will be no other backwards incompatibile changes,
136+
all current constructors for the empty set will continue to work,
137+
and the behaviour of the :py:class:`set` type will remain unchanged.
138+
139+
140+
Security Implications
141+
=====================
142+
143+
None.
144+
145+
146+
How to Teach This
147+
=================
148+
149+
All users can be taught that ``{/}`` is the new spelling for ``set()``,
150+
and that it is equivalent in all other ways.
151+
To help reinforce this, we will update the documentation to use ``{/}``
152+
instead of ``set()``, including the tutorial, standard libary modules,
153+
and the Python Language Reference.
154+
155+
For new users, sets can be introduced through syntax, noting that the four
156+
built-in collection types with syntax all have empty forms:
157+
``()``, ``[]``, ``{/}``, and ``{}``.
158+
159+
The empty set uses a forwards slash to differentiate it from
160+
an empty dictionary.
161+
It uses this syntax because it looks like the mathematical symbol
162+
for the empty set (':math:`\emptyset`').
163+
This can be used as a helpful mnemonic when teaching beginners,
164+
especially those that have a maths or science background.
165+
166+
167+
Reference Implementation
168+
========================
169+
170+
Forthcoming.
171+
172+
173+
Rejected Ideas
174+
==============
175+
176+
Change ``{}`` to mean an empty set and use ``{:}`` for an empty dictionary
177+
--------------------------------------------------------------------------
178+
179+
This would be an entirely backwards incompatible change,
180+
all current empty :py:class:`dict` objects would become sets.
181+
182+
Use a Unicode character (e.g. ```` or ``ϕ``)
183+
---------------------------------------------
184+
185+
The Unicode character 'U+2205 ∅ EMPTY SET' is not currently a valid identifier.
186+
Introducing a Unicode character as syntax would be hard to use,
187+
as it does not appear on standard keyboards.
188+
189+
Using other characters that look like ∅, such as 'U+03C6 ϕ GREEK SMALL LETTER
190+
PHI' or 'U+00D8 Ø LATIN CAPITAL LETTER O WITH STROKE', would be more confusing
191+
with the same drawbacks of using a Unicode character.
192+
193+
Use the ``<>`` syntax
194+
---------------------
195+
196+
It does not have a resemblance to the syntax for non-empty sets.
197+
This would be harder to explain than this PEP's proposal.
198+
199+
This syntax further has historic use as the inequality operator,
200+
which can still be accessed via ``from __future__ import barry_as_FLUFL``.
201+
Using both the ``barry_as_FLUFL`` future import and ``<>`` for the empty set
202+
would lead to parser ambiguity: what would ``<> <> <>`` mean?
203+
204+
Use the ``s{}`` syntax
205+
----------------------
206+
207+
This syntax may cause confusion with ``s`` as a local variable.
208+
The only current use of prefixes of this kind is for string literals.
209+
This would be harder to explain than this PEP's proposal.
210+
211+
Use the ``{*()}`` syntax
212+
------------------------
213+
214+
This relies on unpacking the empty tuple into a set, creating an empty set.
215+
This has the benefit of support since Python 3.5 (:pep:`448`), but is unwieldy
216+
and complicated to explain; it was not designed for this purpose.
217+
218+
Use the ``{-}`` syntax
219+
----------------------
220+
221+
This syntax was originally proposed in :pep:`218`,
222+
but removed from the PEP before it was accepted.
223+
The authors prefer ``{/}`` due to the resemblance to :math:`\emptyset`.
224+
225+
Use the ``{,}`` syntax
226+
----------------------
227+
228+
This is the authors' next preferred option.
229+
However, if a single comma were to be used to represent an empty collection,
230+
it may be confusing why this could not be used for empty tuples or lists.
231+
In time, there might be proposals to add support for ``[,]`` and ``(,)``.
232+
This conflicts with the general principle that
233+
'*there should be one-- and preferably only one --obvious way to do it*'.
234+
Having a visibly different form, in ``{/}``, helps to reinforce the idea
235+
that the syntax for the empty set is a special case, rather than a general rule
236+
for all empty collections.
237+
238+
239+
Open Issues
240+
===========
241+
242+
None.
243+
244+
245+
Acknowledgements
246+
================
247+
248+
* Chris Angelico, Dominykas Grigonis, Ben Hsing, James Webber,
249+
and other contributors to recent Discourse topics.
250+
* Hugo van Kemenade, for helpful feedback on a draft of the PEP.
251+
252+
253+
Footnotes
254+
=========
255+
256+
.. _Discourse, August 2025 (#37): https://discuss.python.org/t/101197/37
257+
.. _Discourse, August 2025: https://discuss.python.org/t/101197
258+
.. _Discourse, December 2024: https://discuss.python.org/t/73235
259+
.. _Discourse, March 2023: https://discuss.python.org/t/25213
260+
.. _explicitly deferred: https://mail.python.org/pipermail/python-3000/2006-May/001599.html
261+
.. _python-3000, April 2006: https://mail.python.org/pipermail/python-3000/2006-April/001286.html
262+
.. _python-3000, May 2006: https://mail.python.org/pipermail/python-3000/2006-May/001666.html
263+
.. _python-ideas, April 2021: https://mail.python.org/archives/list/[email protected]/message/X4TX2HDNKDJ7PVZL3DVI5QD2MIMRHKO4/
264+
.. _python-ideas, August 2020: https://mail.python.org/archives/list/[email protected]/message/QOBONXUPUMC3ULCGJU6FVHOCIZQDT45W/
265+
.. _python-ideas, January 2008: https://mail.python.org/archives/list/[email protected]/thread/IBMTTESRSF5755LNMVTUMHHABKOBSPUZ/#IBMTTESRSF5755LNMVTUMHHABKOBSPUZ
266+
.. _python-ideas, June 2009: https://mail.python.org/archives/list/[email protected]/thread/AMWKPS54ZK6X2FI7NICDM6DG7LERIJFV/#AMWKPS54ZK6X2FI7NICDM6DG7LERIJFV
267+
.. _python-ideas, November 2010: https://mail.python.org/archives/list/[email protected]/thread/N7CHDYXW2FYHDJ5BTP7CCC5HLAIINOVH/#N7CHDYXW2FYHDJ5BTP7CCC5HLAIINOVH
268+
.. _recent Discourse poll: https://discuss.python.org/t/101197/15
269+
270+
271+
Copyright
272+
=========
273+
274+
This document is placed in the public domain or under the
275+
CC0-1.0-Universal license, whichever is more permissive.

0 commit comments

Comments
 (0)