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/

Reply via email to