That would be a joy to read but a pain to write with most keyboards.
ASCII art like {/}
or (/)
would be friendly to both read and write.
That would be a joy to read but a pain to write with most keyboards.
ASCII art like {/}
or (/)
would be friendly to both read and write.
Would have to measure to figure out whether itâs actually worth the effort, but this is at least theoretically possible. The optimizer has all the information it needs to do this. That would NOT be possible with set()
due to the potential for shadowing.
(Imo it would be pretty reasonable for python to elevate part/all of the buitins to a special status that are assumed to not be shadowed to allow such optimizations - but thatâs a different FR)
That would be a breaking change and an unpopular one. You can and should be able to use those names in your own code. I donât know when I would do it with set
, but I have at times done something like this:
_print = print
def print(*a, **kw):
if "file" not in kw: kw["file"] = sys.stderr
_print(*a, **kw)
This wouldnât be possible if I couldnât shadow print (and is one of the reasons it became a plain function rather than a language keyword). Like I said, Iâve never personally done this with set()
[1], but the option is there and it would be a pain to revoke it.
that I can recall, anyhow âŠď¸
Yeah, print
should probably not be part of this elevated set - but I still think others, like set
could be (imo, the fact that you donât recall ever wanting to overwrite it is evidence for this). I would probably start conservative and only do this set
and dict
if there is no write access to them in the current file or something like that.
A lot of existing code would break though, including some in CPython:
Why should some be special and others not? What would be the boundary? It would be highly confusing - a small collection of names that canât be overridden, but are otherwise normal names? And what if you do something like globals()["set"] = ...
or exec("set()", {"set": some_function})
- would that be disallowed?
I donât think itâs a good path to go down.
The special treatment did happen to True
and False
with Python 3. The change didnât break a lot of code though since there arenât many if any other way in English to interpret True
and False
as anything else so people donât tend to reassign them. set
however has quite a few meanings other than a mathematical set so the impact of a keywordization would be much larger.
Ah, thatâs slightly different. They became keywords - in effect, a new kind of boolean literal. Theyâre not regular names any more. Doing that would have even stronger backward compatibility issues, although it would at least avoid the confusion of âname, but not shadowableâ.
With the description I used and you quoted, neither of these would break.
You mean this? Itâs a bit magical:
Which of these counts as âwrite accessâ?
globals()["set"] = ...
setattr(sys.modules[__name__], set.__name__, ...)
sneaky_module.update_my_globals("set", ...)
Etcetera. If youâre going to call it an optimization, these will break it (and bear in mind that injection into another module is a common way of implementing tests, so these arenât as contrived as they look). OTOH, if you want to make it a part of syntax, itâs going to need to be clearly defined.
Making set
into a keyword would definitely be less magical. But unlike True
and False
, thereâs far more breakage and far less benefit.
Ah, I now see what you mean by âif there is no write access to them in the current fileâ. Thatâs going to be hard to determine if the write access is done indirectly as @Rosuav pointed out.
None of those (IMO obviously). But I donât think there is much value in continuing this discussion here - maybe I will write out a proper proposal at some point.
From all ideas so far I like {/}
most.
Visual reference is pleasing.
+1 on {/}
since itâs probably as close to the official unicode representation of the empty set (U+2205
, â
) as we can get.
I think it also fits in nicely with the existing non-empty set literals:
empty = {/}
one = {"a"}
two = {"a", "b"}
+1 on {/}
I also like the {/}
proposal.
Perhaps to allow optional disambiguation {:}
could then be additionally recognised as an empty dict? Naturally the current {}
must be retained too to avoid breaking a billion lines of code.
Adding just an alias is pretty weak argument but regardless I think thatâs an entirely seperate topic that deserves its own thread if a set literal ever gets added.
Youâre probably right. Rather than it just being an alias, I thought that maybe {}
could be gradually deprecated in favour of {:}
over a long period, but thatâd probably see pushback.
And yeah, it should be considered a separate issue. I think {/}
is clear enough on its own (even a beginner would realise itâs not dict syntax) that confusion is fairly unlikely.
{/}
is a bug today because s = {1/2}
is valid. In general, s = {expression}
is valid.