On Fri, 21 Jan 2022 at 12:15, Chris Angelico <ros...@gmail.com> wrote: > > On Fri, 21 Jan 2022 at 22:52, Oscar Benjamin <oscar.j.benja...@gmail.com> > wrote: > > > > I really don't understand (having read everything above) why anyone prefers > > {1,2,3}.frozen() over f{1,2,3}. Yes, some people coming from some other > > languages might get confused (e.g. in Mathematica this is function call > > syntax) but that's true of anything: you have to learn Python syntax to use > > Python. The fact that {1,2,3} is a set and f{1,2,3} is a frozenset is not > > difficult to explain or to understand, especially in a language that > > already uses single letter prefixes for other things. > > > > The .frozen() method is a strangely indirect way to achieve a minor > > optimisation. Outside of attempting to achieve that optimisation it's > > basically useless because any time you would have written obj.frozen() you > > could have simply written frozenset(obj) so it does nothing to improve code > > that uses frozensets. > > > > If set.frozen() is optimized, then str.upper() can be optimized the > same way, which means there's a lot of places where constant folding > can be used. We commonly write code like "7*24*60*60" to mean the > number of seconds in a week, confident that it'll be exactly as fast > as writing "604800", and there's no particular reason that method > calls can't get the same optimization, other than that it hasn't been > done yet. > > While dedicated syntax might be as good, it also wouldn't help with > string methods (or int methods - I don't see it a lot currently, but > maybe (1234).to_bytes() could become more popular), and it would also > be completely backward incompatible - you can't feature-test for > syntax without a lot of hassle with imports and alternates. In > contrast, code that wants to use set.frozen() can at least test for > that with a simple try/except in the same module.
The proposal for .frozen() is not about optimising method calls on literals in general: the proposal is to add a method that is basically redundant but purely so that calls to the method can be optimised away. > Not one of the proposed syntaxes has seen any sort of strong support. > This isn't the first time people have proposed a syntactic form for > frozensets, and it never achieves sufficient consensus to move > forward. > > > With f{...} you have a nice syntax that clearly creates a frozenset > > directly and that can be used for repr. This is some actual code that I > > recently wrote using frozensets to represent monomials in a sparse > > representation of a multivariate polynomial: > > "Clearly" is subjective. Any syntax could be used for repr, including > {1,2,3}.frozen(), so f{1,2,3} doesn't have any particular edge there. > Personally, I think that string literals are not the same thing as > tuple/list/dict/set displays, and letter prefixes are not as useful on > the latter. > > > >>> poly = {frozenset([(1,2), (3,4)]): 2, frozenset([(0,1)]): 3} > > >>> poly > > {frozenset({(1, 2), (3, 4)}): 2, frozenset({(0, 1)}): 3} > > > > With the f{...} proposal you have actual syntax for this: > > > > >>> poly = {f{(1,2), (3,4)}: 2, f{(0,1)}): 3} > > >>> poly > > {f{(1, 2), (3, 4)}: 2, f{(0, 1)}): 3} > > > > With .frozen() it's > > > > >>> poly = {{(1,2), (3,4)}.frozen(): 2, f{(0,1)}.frozen()): 3} > > >>> poly > > ??? does the repr change? > > Yes, it most certainly would change the repr. I don't see why that's an issue. I'm not saying it's an issue. That was a genuine question. So I guess you'd expect this: >>> poly = {{(1,2), (3,4)}.frozen(): 2, f{(0,1)}.frozen()): 3} >>> poly {{(1, 2), (3, 4)}.frozen(): 2, f{(0, 1)}.frozen()): 3} This btw is my real point of my post which you seem to have missed (I probably should have kept it more direct): > > That difference in code/repr may or may not seem like an improvement to > > different people but that should be the real point of discussion if talking > > about a frozenset literal. The performance impact of frozenset literals is > > not going to be noticeable in any real application. If we take performance out of the equation would anyone actually propose to add a .frozen() method so that obj.frozen() could be used instead of frozenset(obj)? If so then what is the argument for having a redundant way of doing this? > I don't understand polynomials as frozensets. What's the point of > representing them that way? Particularly if you're converting to and > from dicts all the time, why not represent them as dicts? Or as some > custom mapping type, if you need it to be hashable? Hashability is the point. The polynomial is a dict mapping monomials to coefficients and the monomials are frozensets of factors so that they are hashable with unordered equality. Another option would just be a sorted tuple of tuples and then instead of frozenset(d.items()) you'd have tuple(sorted(d.items())) but that's slower in my timings (for all input sizes). Any custom type with pure Python __eq__/__hash__ methods would slow everything down because apart from a couple of functions like the one I showed all these objects are used for is as dict keys. -- Oscar _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/HJ32BZ75MGWZ2EW6S63P4ZJLQUF4NKSV/ Code of Conduct: http://python.org/psf/codeofconduct/