#"Usecase of `!!` in Kotlin"

1 messages · Page 1 of 1 (latest)

lime rapidsBOT
#

@low spruce has a question:

taz_03

@maiden creek is this a good usecase of !!? i haven't wrote enough kt to be sure

#

<@&987246399047479336> please have a look, thanks.

low spruce
lethal anvil
#

its called the double-bang operator

#

it means "assume this is not null, else throw"

#

compared to java, its like Optional#getOrThrow()

low spruce
lethal anvil
#

depends

#

it often smells yeah

#

but not always

low spruce
#

is there anything better i can do in this particular case of this is good?

lethal anvil
#

its language agnostic. thing is: generally, u should prefer having meaningful alternative behavior

#

like, why cant u ensure that the exception has a message?

#

what if it doesnt have any?

#

and if it always has a message, why is it nullable in the first place?

low spruce
lethal anvil
#

is it ur own exception or also a java file?

low spruce
#

its my own yes

lethal anvil
#

i believe u should be able to mark it non nullable in ur exception class then

lime rapidsBOT
#

Changed the category to Kotlin.

#

<@&1008423204219531294> please have a look, thanks.

lethal anvil
#

if u cant, the use of the doublebang is fine

low spruce
#
class InvalidCredentials(message: String) : Exception(message)
#

how do

lethal anvil
#

the need for it often arises with platform-border code like when dealing with java files (Foo?)

low spruce
#

@lethal anvil @maiden creek i change it to this, hope thats better

emailSupportingText.value = it.message ?: ""
lethal anvil
#

it depends on what u want to achieve

#

this is "safer" code. but safe isnt necessarily better

low spruce
maiden creek
#

did you define InvalidCredentials?

low spruce
#

print

low spruce
maiden creek
#

then why does it even support null?

lethal anvil
#

yeah but would u consider it a bug in ur code if u happen to get hands on this exception without it having a message?

#

then u should throw

low spruce
lethal anvil
#

from platform code

maiden creek
#

like i said before, null support exists for java interop. with pure kotlin, you shouldnt need null

lethal anvil
#

its not pure kotlin

maiden creek
#

oh, it extends Exception

#

then yeah, that's fine. not much you can do about it

lethal anvil
#

there might be a way to annotate it non nullable

#

since java-wise nullability is merely an annotation

maiden creek
#

use the double bang if you want an exception to be thrown

#

using a default value is different semantics than failing

lethal anvil
#

so its not part of the pure code contract of the parent method

#

bytecode-wise

#

but im not sure about the syntax without trying out

maiden creek
lethal anvil
#

other than, u know, explicitly overriding and then just super.message

#

and throwing there

maiden creek
#

cant introduce pre-conditions in subtypes

lethal anvil
#

its ur exception though

#

so u define the contract

#

if it doesnt offer constructors with empty messages, it cant have empty messages

maiden creek
#

yeah, but people may interface it using Exception

low spruce
maiden creek
#

so you have to go based on the Exception contract

lethal anvil
#

yes but a non-nullable value is compatible with people who expect that it could be nullable

#

so u dont break contracts

#

adding annotations to subtypes should be possible, dont u think?

#

i havent tried

maiden creek
maiden creek
lethal anvil
#

but it also would shift the double-bang usage only inside the overriden method, so whatever

maiden creek
#

when it comes to defining a subtype of Exception that doesnt expect null messages, that becomes a discussion of LSP, as those interfacing via Exception wont know of those rules

low spruce
low spruce
lethal anvil
#

someone who expects nullable types can work with nonnullable. its compatible

#

cause its a subset

maiden creek
# lethal anvil its a non conflicting rule

if the supertype accept null, but the subtype restricts it, then there's conflict. the supertype doesnt define "non-null". if subclasses throw exceptions on null, thats an LSP violation

#

because people interfacing via Exception dont expect that. the behavior would have to be documented in Exception

#

its similar to List and supporting immutable lists via UnsupportedOperationException

#

List doesnt violate LSP because it documents the behavior. but Exception doesnt document such

low spruce
#

i agree with what zabu said

maiden creek
#

its not the worst of issues, but definitely not something to aim for

#

if an exception is thrown in situations where people expect a value to work, thats not good

maiden creek
lethal anvil
#

i mean, it depends with what options u have available to manipulate message

#

if Exception has a setter that accepts nullable, its an issue

#

if the constructor is the only way, its not

#

ultimately its the responsibility of the subtype author to ensure it stays compatible and valid

#

but we are talking semantics now, i suppose

maiden creek
#

just dont throw an exception, and itll be fine. thats my point. empty message is different from runtime error

#

the idea is, people work with values at a higher level, so they depend on those higher level contracts

#

the subclass can only do so much without impacting that ecosystem

#

you can always violate LSP, its a principle not law

#

but LSP has some good justification behind it

#

if people work with Exception, dont throw em caveats that cause them to dive deeper into the subtyping

#

that defeats the purpose of abstraction

lethal anvil
#

yeah i just dont see it as violation if theres no way to observe it other than via bytecode manipulation or sth. but whatever

maiden creek
#

no post conditions, no pre conditions

lethal anvil
#

its very specific and in general id agree

maiden creek
#

if they threw an error, that would cause failure in a situation thats expected to run

#

which was the double bang thing

lethal anvil
#

if there is no way to get a null value in there, its not a violation if it throws on null

maiden creek
#

elvis operator more fits to the spec of `Exception|

lethal anvil
#

cause its then not observable

low spruce
#

uhh what are we talking about how

#

now

lethal anvil
#

but yeah, its more reasonable to throw on constructor than on the getter

maiden creek
#

and if an annotation processor is present, an error could be raised

#

not a huge deal, kinda rambling now

#

TLDR:
keep LSP in mind when subtyping

#

dont throw an error in this case

low spruce
#

idk what ya'll are talking now but u can close the thread whenever u want my question is solved

lime rapidsBOT
#

Closed the thread.

low spruce
#
val args = it.arguments!!
OtpScreen(navController, args.getString("sessionId")!!, args.getInt("phonePostfix"))
#

it happened again :c

lethal anvil
#

what type is it and it.arguments?

lethal anvil
#

well. its nullable types on purpose it seems

#

so u have to decide what u want to do in case its null

#

if u consider it a bug in ur application if that should happen (i.e. if ur code is correct, it can never happen), then !! is correct

#

otherwise not

low spruce
#

so the flow is good ig

lethal anvil
#

u might want to put these two strings in some constants

#

to eliminate the risk of typos

low spruce
#

yea no im just waiting for the new version to drop it allows me to pass objects so this is all silli