
On Thu, Oct 01, 2015 at 03:57:18PM -0500, Ron Adam wrote:
On 10/01/2015 02:59 AM, Nick Coghlan wrote:
As a result, one interesting way of looking at this problem is to ask: what if we *only* offered the conditional operations, *without* offering a binary null-coalescing operator?
How languages treat None, null, and nil, are very fundamental aspects of how they work. For example I noticed that if we add an None specific 'or' operator, we may want a None specific 'and' operator too.
Why would we do that? What would it do and which other languages have it?
And in order to use those in conditional statements, it makes sense to have None specific 'if' and 'while'.
Which other languages have these?
So it may be a slippery slope. (Or they may be good to have. I'm very undecided still.)
Most slippery-slope arguments aren't actually that slippery. Sure, we could invent a new short-cut for "if spam is None" statement, but it doesn't buy us much benefit, so why would we bother? if spam.eggs[cheese] is None: ... ifn spam.eggs[cheese]: ... You save a few characters typing, big deal. But with an expression, you can save complexity, by avoiding temporary variables: # before expensive = spam.eggs[cheese] # don't calculate this twice value = expensive.attribute if expensive is not None else None # after value = spam.eggs[cheese]?.attribute [...]
Another possibility is to have a *special magic callable* that when called skips the argument evaluation and returns None.
NoneCall(these, args, are, never, evaluated)
That cannot work with standard Python semantics. In Python, the function doesn't evaluate the arguments, they are evaluated before the function even gets called. For this to work, the parser would have to recognise this NoneCall function *at compile time*, so it can decide whether or not to evaluate the arguments. That is, in general, an impossible task: func = random.choice([NoneCall, lambda *args: None]) func(a+1, b*2, c**3) # to evaluate or not to evaluate? Python has only one thing even remotely like this, the special handling of "super" inside functions, and that's a special case which I think Guido has ruled won't be repeated. But even there, it isn't a change in what gets evaluated when.
Then a special method on objects, obj __cond__call__() can return a NoneCall to skip the arguments on the right side of ?(, or return another callable to use them.
No, it can't work anything like that. It can't be a regular method call, because the arguments are already evaluated before the method call is made. It has to be a change in what code gets compiled. -- Steve