I would like to propose a new syntax to simplify e...
# language-evolution
m
I would like to propose a new syntax to simplify expressions involving nullable types and avoid awkward nested
?.let { }
expressions, in case it has not been discussed before. Whenever, inside of an expression, a
?
(question mark) is appended to the name of a variable (mutable
var
or non mutable
val
) of nullable type, the whole expression containing it would evaluate to
null
if that variable is
null
, otherwise the variable is cast to the respective non-nullable type.
Copy code
fun f(a: A): B = TODO()
fun g(a: A?): B? = f(a?)
Copy code
fun h(a: Int?, b: Int): Int? = (a? + b)*2
fun i(a: Int?, b: Int?, c: Int?): Int? = (a? + b?)*c?
I don't know how to call this feature. Maybe "short-circuiting null operator"? As suggested by @uli, this feature is symmetric to the
?.
operator, and would work on all arguments of a function like
?.
does on the
this
argument. Would this syntax cause conflict with other language features? Would you consider its implementations?
u
There is a good hint in the name you choose. Discussing this name brings us immediately to the question do we want to shirt circuit. I.e. not evaluate parameters 2 if parameters 1 is already null? Seems a little unexpected?
👍 1
With only one single ?-expression on the receiver there was no short circuiting
👍 1
So i am totally in favor of the idea. But i see some important design questions
👍 1
i
In Arrow continuations there is `nullable`https://github.com/arrow-kt/arrow/blob/85862e5629f19c1858891904044a864308d81ebe/ar[…]re-data/src/test/kotlin/arrow/core/computations/NullableTest.kt But this would be great to have something in that direction at language level.
👍 2
m
@uli, thanks making those observations. I should check the case of other method invocations, but, as far as assignment is involved, safe-calls (
?.
) do perform short-circuiting. The documentation says:
Copy code
// If either `person` or `person.department` is null, the function is not called:
person?.department?.head = managersPool.getManager()
But you are right: these issues should be discussed and defined properly.
@Imran/Malic Yes, Arrow
nullable
was mentioned in the original thread by @kioba. Thanks for mentioning it here too.
i
Oh I am sorry for repeating that part 🙏🏽 @melatonina. I haven’t checked the previous conversation
👌 1
m
A variant of this proposal would be liming the scope of the short-circuit only to the function call where the
variable?
expression appears. So:
(f(a?) + 2) * g("hello")
would only short-circuit
(f(a?) + 2)
and probably cause a compile-time error. While:
(f(a?) + 2)? * g("string")
would short-circuit the whole expression. This would be an option. I'm not sure which one I'd like more.
u
The interesting case is:
f(effect1()?, effect2()?)
because effect1 and effect2 are independent
And in person?.department?.head there is no short circuit. That's why you need two question marks. person?.department.head would fall because ? does not short circuit
m
@uli I see what you mean, now: what I meant is that the right hand of the assignment is not evaluated.
u
@melatonina you are right. In the case of optional left hand side expressions ? does short circuit. thanks for pointing that out. i was not immediately aware.