[Python-3000] Set literal

J. Cliff Dyer jcd at sdf.lonestar.org
Fri Jan 25 21:31:03 CET 2008

I'm a -0.9 on this one. I really like that Python is powerful, but also
a great pedagogical language.

I don't like that whereas before you could teach someone {} creates a
dict, but now you have to say {} creates a dict, if there are colons
inside, or it's empty, but otherwise creates a frozenset. I also don't
like that it will be easy (especially coming from Certain Other
Languages) to make the following error:

my_dict = {
'a', 'b',
'c', 'd',
'e', 'f'

Moreover, I don't like that once you've done that, you'll be able to do

if 'c' in my_dict:

and have it evaluate as true even though you aren't dealing with a dict.
Those are ugly gotchas for something so basic to the language. Newcomers
will run into it a lot.

As a half-baked alternative thought, what about using {{ 'a', 'b', 'c'
}} for the syntax. It's visually clearer, and still syntactically
unambiguous, because a dict can't have another dict as a key, and a
(frozen)set can't have a dict inside it. Thinking about possible
issues--what if you come across a construct with three opening braces at
the start? ({{{)

* It can't be a dict within a dict within a dict, because a dict is not
hashable, so can't be a key.
* It can't be a dict within a frozenset, because a dict is not hashable.
* It can (and must) be a frozenset within a dict, because a frozenset is
hashable, and hence a valid dict key.

Four braces? ({{{{)
* I think this has to be a frozen set within a frozen set.

* The outer one is a dict if an odd number of braces, everything else is
a frozen set.

Obviously, the more complex cases get less visually clear, but (1) they
are not common cases, and (2) they are still unambigous, and will often
be made clearer by (a) the placement of closing brackets, and (b) decent
syntax highlighting.

Any major holes in this idea?


Nick Coghlan wrote:
> Mark Summerfield wrote:
>> On 2008-01-25, Guido van Rossum wrote:
>>> For the record, I'm thinking Raymond has won this argument fair and
>>> square, and I'm withdrawing my opposition.
>>> I hope it isn't too confusing that {1: 1} creates a *mutable* dict
>>> while {1} creates an *immutable* frozenset. I still find this slightly
>>> inelegant. But the practicality of being able to treat set literals as
>>> compile-time constants wins me over.
>> So this will produce:
>>     frozenset()	# empty frozen set
>>     {1}	    	# 1 item frozen set
>>     {1, 2}  	# 2 item frozen set
>>     {}	    	# empty dict
>>     {1:1}   	# 1 item dict
>>     {1:1, 2:2}	# 2 item dict
> More completely:
>       ()           # empty tuple
>       (1,)         # 1 item tuple
>       (1, 2)       # 2 item tuple
>       []           # empty list
>       [1]          # 1 item list
>       [1, 2]       # 2 item list
>       {}           # empty dict
>       {1:1}        # 1 item dict
>       {1:1, 2:2}	  # 2 item dict
>       frozenset()  # empty frozen set
>       {1}          # 1 item frozen set
>       {1, 2}       # 2 item frozen set
>       set()        # empty mutable set
>       set({1})     # 1 item mutable set
>       set({1, 2})  # 2 item mutable set
> So with Raymond's proposal we will have syntax for two immutable 
> literals (tuples, frozensets) and two mutable container displays (lists, 
> dicts).
> Yes, there will be a few anomalies to learn in this list:
>    - 1-tuples require a trailing comma
>    - {} is a dict rather than a frozen set
>    - frozen sets are immutable while dicts are mutable
> Do these anomalies make this area of the language syntax harder to 
> learn? Almost certainly - the 1-tuple anomaly has been tripping people 
> up for years. Despite any reservation, are there valid reasons for 
> having these anomalies in Py3k? As far as I am concerned, yes there 
> are*, and I believe that is Guido's view as well.
> Cheers,
> Nick.
> *Taking them from the top:
> - 1-tuples require a trailing comma to differentiate them from the use 
> of parentheses for mere expression grouping. Expression grouping is kind 
> of important, and this anomaly in the syntax is a small price to pay for 
> making that work intuitively.
> - {} is used extensively in existing code (both operational code and 
> code in documentation and other examples). Py3k may lower the bar for 
> 'acceptable breakage' in the realm of backwards compatibility, but it 
> doesn't get rid of it altogether - and changing the meaning of {} fails 
> to clear even that lowered hurdle. Also, as Marcin pointed out, an empty 
> frozenset() is pretty useless, while an empty dict() is common.
> - making set literals immutable provides excellent optimisation 
> opportunities, which is important because it is a concern for speed 
> which is likely to lead to the use of a set in the first place. It is 
> also convenient in that set() is a lot easier to type than frozenset(), 
> so going from an immutable literal to a mutable container is easier than 
> going the other way would have been.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.python.org/pipermail/python-3000/attachments/20080125/af956f86/attachment-0001.htm 

More information about the Python-3000 mailing list