On Fri, 18 Mar 2022 at 00:31, David Mertz, Ph.D. <david.mertz@gmail.com> wrote:
I just do this myself in my text editor (vim):
But this is just cosmetic because I like to look at it this way. The actual file on disk contains `set()`, `<=`, `in`, `not in` and wouldn't be a problem for anyone without the same fonts installed, or require anyone to know odd key combos.
This is potentially confusing if you ever shadow the name 'set' (since the word doesn't appear in the visual form, but does appear in the source), but otherwise, it's a good solution. Here's a crazy thought: What if we start by standardizing on {*()} as an idiom, teach the optimizer to skip the tuple altogether, and then encourage editors to (a) show it as an empty set glyph, and (b) provide a convenient way to enter it? On disk, it would still be a syntactic form that's compatible all the way back to Python 3.5 (I had to check actually - the additional unpacking generalizations have been around longer than I thought), but in the display, it would look quite elegant. Then, if it catches on, support for the actual ∅ symbol (btw, "⦰" is actually "reversed empty set", but they're in the same category so same diff) could be added as an alias for {*()}, at which point editors could have an option to represent it either way. For the record, here's the timings for the different forms: rosuav@sikorsky:~$ python3 -m timeit -s 'from opcode import opmap as o; f1 = lambda: set(); f2 = lambda: {*()}; f3 = type(f2)(f2.__code__.replace(co_code=bytes([o["BUILD_SET"], 0, o["RETURN_VALUE"], 0])), f2.__globals__)' 'f1()' 5000000 loops, best of 5: 78.6 nsec per loop rosuav@sikorsky:~$ python3 -m timeit -s 'from opcode import opmap as o; f1 = lambda: set(); f2 = lambda: {*()}; f3 = type(f2)(f2.__code__.replace(co_code=bytes([o["BUILD_SET"], 0, o["RETURN_VALUE"], 0])), f2.__globals__)' 'f2()' 5000000 loops, best of 5: 98.9 nsec per loop rosuav@sikorsky:~$ python3 -m timeit -s 'from opcode import opmap as o; f1 = lambda: set(); f2 = lambda: {*()}; f3 = type(f2)(f2.__code__.replace(co_code=bytes([o["BUILD_SET"], 0, o["RETURN_VALUE"], 0])), f2.__globals__)' 'f3()' 5000000 loops, best of 5: 62.8 nsec per loop Sorry for the messy setup but I wanted something that would work on multiple Python versions, so hardcoding a bytes literal wouldn't work. I tried it on Python 3.8, 3.9, 3.10, and 3.11, and in each case, the relative speeds (f2 slowest, f3 fastest) were maintained. ChrisA