This message was deleted.
# language-proposals
s
This message was deleted.
d
This places the question mark on the property, not on the expression.
Question marks are always trailing tokens, using them in a leading position would be confusing.
The confusion is not worth it, this change does not have much value at all because, as you demonstrate,
a ?.let { }
works the same
j
"works the same" is a poor argument against something because you can literally say that about every form of desugaring until you're staring at a page of x86 assembly
d
That's a bit extreme, but point taken
Interested to hear about other places where you could add ? though
j
i would add it to
return
Copy code
return? returnsNullable()
someSideEffect()
return? anotherNullableReturn()
otherSideEffect()
return whatever
👍 1
i hate reading
returnsNullable()?.let { return it }
4
d
And other keywords like
throw
?
Maybe
=?
would be a bit better
I would like to be able to overload how
?
works on non-nullable values. For example in a project where I make heavy use of inline classes because the code would otherwise run extremely slowly.
Anyways getting off topic
It could be implemented in a way where there is a special value that isn't necessarily
null
. In other words, there would be heavy restrictions. As for your question, because it places
?
in a more trailing position, and it's more consistent with
return?
that Jake proposed.
?=
could be applied like: myVar?=nullableValue Which is confusing because it looks like ? is applied on the property more than with =? I would say.
j
How do you reconcile that argument with
myVar?.foo()
?
d
In
myVar?.foo()
the subject of the question mark is
myVar
. Not the . following it.
The condition is dependent upon
myVar
j
Got it. Makes sense.
d
I want to sleep, good talks, good night 😄
j
i mean, it's not really implicit since you denote it with
?
, right? also it's for the Result type and error propagation which is slightly different
d
The result type is an excellent example of when you may want to define behaviour of ? On non nullable type
Something like
operator fun Result<*>.isSpecialNullValue(): Boolean
Back to sleep (I cant sleep)
j
I've never used it with an Option that I can remember. I didn't know it applied to them. What I'm asking for is actually the opposite though. So maybe it's
return!
d
result??
I'm not too familiar with Rust
j
Don't learn it. It'll show you all the things about Kotlin that are annoying
😂 3
d
I think I know quite well given kotlin has been my go to language for everything for 2+ years
Upvote my keep proposal <shameless plug>
j
return someValueThatCouldBeNull ?: skip
and
x = someValueThatCouldBeNull ?: skip
, perhaps? Where
skip
is like
break
and
continue
and
return
in that it interrupts execution and skips to the end of the statement?
j
i don't like that the behavior is moved really far away from the
return
keyword. It would make reading
Copy code
return reallyReallyReallyReallyReallyReallyReallyReallyReallyLongLine() ?: skip
println("Hi!")
hard to understand when scanning vertically
j
I had the same thought - with returns I'd be less worried because it's fairly clear that if the function keeps going that the return could be skipped, but with assignments pushing that information to the back of the line seems problematic
In any case, it doesn't quite do what it needs to for readability.
j
It’s good that it’s ugly to deal with nulls! We could all do with fewer nulls in our lives . . .
j
Instead we can allocate wasteful boxes on the heap and chase pointers for useless abstractions of optionality?
l
As I am thinking about Jake's example with returns, then with the current possibilities it maybe could be done like this as well:
Copy code
return sequence {
    yield(returnsNullable())
    someSideEffect()
    yield(anotherNullableReturn())
    otherSideEffect()
}.filterNotNull().firstOrNull() ?: whatever
This is a very raw sketch, so maybe it could be wrapped into something more simpler and meaningful 🙂
Or another possibility could be to force the side-effect functions to always return null. Then it could be all chained by the Elvis operator:
Copy code
fun nullResult(action: () -> Any) = null.apply { action() }

fun returnsNullable() = null
fun anotherNullableReturn() = null
fun someSideEffect() = 1
fun otherSideEffect() = 1

fun main(): Any {
	val whatever = 1
    return returnsNullable() ?:
        nullResult { someSideEffect() } ?: 
        anotherNullableReturn() ?:
        nullResult { otherSideEffect() } ?:
        whatever
}
d
That's utterly unreadable.
l
Alright, I agree 😁 , another option would be wrapping the side-effect function and successive function call into a lambda, which could look like:
Copy code
return returnsNullable() ?: run { 
            someSideEffect() 
            anotherNullableReturn()
        } ?: run { 
            otherSideEffect() 
            whatever
    	}
But I cannot think of any better version at the moment 😁
d
I use this for conditional return value ?: { return error } or value ?.let{ return it }