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 -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/JQDIIASPERXREVCXJBFB5V45FJ4INGPP/
Code of Conduct: http://python.org/psf/codeofconduct/