On Tue, Aug 27, 2019 at 10:07:41AM -0700, Andrew Barnert wrote: > > How is that different from passing a string argument to a function or > > class constructor that can parse that token however it wants? > > > > x'...' > > > > x('...') > > > > Unless there is some significant difference between the two, what does > > this proposal give us? >
> Before I get into this, let me ask you a question. What does the j > suffix give us? I'm going to answer that question, but before I answer it, I'm going to object that this analogy is a poor one. This proposal is *in no way* a proposal for a new compile-time literal. If it were, it might be interesting: I would be very interested to hear more about literals for a Decimal type, say, or regular expressions. But this proposal doesn't offer that. This proposal is for mere syntactic sugar allowing us to drop the parentheses from a tiny subset of function calls, those which take a single string argument. And even then, only when the argument is a string literal: czt'abc' # Okay. s = 'abc' czt's' # Oops, wrong, doesn't work. But, to answer your question, what does the j suffix give us? Damn little. Unless there is a large community of Scipy and Numpy users who need complex literals, I suspect that complex literals are one of the least used features in Python. I do a lot of maths in Python, and aside from experimentation in the interactive interpreter, I think I can safely say that I have used complex literals exactly zero times in code. > You can write complex numbers without it just fine: [...] Indeed. And if we didn't already have complex literals, would we accept a proposal to add them now? I doubt it. But if you think we would, how about a proposal to add quaternions? q = 3 + 4i + 2j - 7k > But would anyone ever write that when they can write it like this: > > 1 + 2j Given that complex literals are already a thing, of course you are correct that if I ever needed a complex literal, I would use the literal syntax. But that's the point: it is *literal syntax* handled by the compiler at compile time, not syntactic sugar for a runtime function call that has to inefficiency parse a string. Because it is built-in to the language, we don't have to do this: def c(astring): assert isinstance(astring, str) # Parse the string at runtime real, imag = ... return complex(real, imag) z = c"1.23 + 4.56j" (I'm aware that the complex constructor actually does parse strings already, so in *this specific* example we don't have to write our own parser. But that doesn't apply in the general case.) That is nothing like complex literals: py> from dis import dis py> dis(compile('1+2j', '', 'eval')) 1 0 LOAD_CONST 2 ((1+2j)) 3 RETURN_VALUE # Hypothetical byte-code generated from custom string prefix py> dis(compile("c'1+2j'", '', 'eval')) 1 0 LOAD_NAME 0 (c) 3 LOAD_CONST 0 ('1+2j') 6 CALL_FUNCTION 1 (1 positional, 0 keyword pair) 9 RETURN_VALUE Note that in the first case, we generate a complex literal at compile time; in the second case, we generate a *string* literal at compile time, which must be parsed at runtime. This is not a rhetorical question: if we didn't have complex literals, why would you write your complex number as a string, deferring parsing it until runtime, when you could parse it in your head at edit-time and call the constructor directly? z = complex(1.23, 4.56) # Assuming there was no literal syntax. > I don’t think so. What does the j suffix give us? The two extra > keystrokes are trivial. The visual noise of the parens is a bigger > deal. I don't think it is. I think the big deals in this proposal are: - you have something that looks like a kind of string czt'...' but is really a function call that might return absolutely anything at all; - you have a redundant special case for calling functions that take a single argument, but only if that argument is a string literal; - you encourage people to write cryptic single-character functions, like v(), x(), instead of meaningful expressions like Version() and re.compile(); - you encourage people to defer parsing that could be efficiently done in your head at edit time into slow and likely inefficient string parsing done at runtime; - the OP still hasn't responded to my question about the ambiguity of the proposal (is czt'...' a one three-letter prefix, or three one-letter prefixes?) all of which *hugely* outweighs the gain of being able to avoid a pair of parentheses. [...] > And the exact same thing is true in 3D or CUDA code that uses a lot of > float32 values. [...] I actually have to go through a string for > implementation reasons (because otherwise Python would force me to go > through a float64 and distort the values) Indeed, but this proposal doesn't help you here. You still have to write strings. What you want is a float32 literal, let's say 1.23f but what you have to write is a function call with a string argument f('1.23'). All this proposal buys you is to drop the parentheses f'1.23'. Its still a function call, except it looks like a string. While I'm sympathetic, and I'd like to see a Decimal literal, I doubt that there's enough use-cases outside of specialists like yourself for 16- or 32-bit floats to justify making them built-ins with literal syntax. Python is not Julia :-) But if you could get the numpy people to write a PEP... *wink* -- Steven _______________________________________________ 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/JQDIIASPERXREVCXJBFB5V45FJ4INGPP/ Code of Conduct: http://python.org/psf/codeofconduct/