George
06/13/2022, 5:50 PMNathan Bedell
06/23/2022, 3:02 PMMikhail
06/28/2022, 9:35 PM// in kotlin you can
suspend fun hi() {
suspend fun thing() {
}
thing()
}
// you can
suspend fun hi() {
val thing: suspend () -> Unit = {
}
thing()
}
// you can
fun hi() {
val thing = fun() {
}
thing()
}
// but you CAN'T
suspend fun hi() {
val thing = suspend fun() {
}
thing()
}
any specific reason?Ayfri
07/07/2022, 10:00 PMYoussef Shoaib [MOD]
07/13/2022, 10:33 PM@OverloadResolutionByLambdaReturnType
not cover the case where one of the return types is a subtype of the other? For instance, this surprisingly fails (playground):
@OptIn(kotlin.experimental.ExperimentalTypeInference::class)
@OverloadResolutionByLambdaReturnType
inline fun printIf(condition: Boolean, message: () -> Any?) {
if(condition) println(message())
}
inline fun printIf(condition: Boolean, message: () -> Int) {
if(condition) println(message())
}
fun main() {
printIf(true) { 42 }
printIf(false) { "hello world" } // Type mismatch: inferred type is String but Int was expected
}
This can obv be used to avoid boxing primitives like Int when unneeded. I know the cost of boxing is marginal, but in a tight loop it can be detrimental.Brendan Campbell-hartzell
07/14/2022, 5:56 PMMikhail
07/15/2022, 1:24 PMKlitos Kyriacou
07/22/2022, 2:44 PMwhen (Pair(bool1, bool2) {
Pair(false, false) -> {...}
Pair(false, true) -> {...}
Pair(true, false) -> {...}
Pair(true, true) -> {...}
}
Is it just because it's too difficult for the compiler to figure out that it is in fact exhaustive?Klitos Kyriacou
07/25/2022, 8:11 AMthen
is an infix function but thenBy
isn't?hfhbd
09/07/2022, 7:43 AMval parser = ArgParser("ejwrapper")
val jobID by parser.option(ArgType.String)
parser.parse(args) // No changes to jobID after parsing
if (jobID != null) {
val status = getJobStatus(jobID) // smart cast is not possible because jobID has a open or custom getter
Current workaround is !!
, another variable or let
Olli Helenius
09/30/2022, 8:57 AMSam Stone
11/04/2022, 2:54 AMcontract
about the preconditions. There could even be an error message associated with each precondition.
@Precondition(
target=a,
condition=Preconditions.nonNegative(),
message="a cannot be negative!"
)
@Precondition(
target=a, condition=Preconditions.lessThan(b),
message="a must be less than b!"
)
fun foo(a: Int, b: Int)
Could also apply to variables:
@Invariant(condition=Preconditions.nonNegative())
@Invariant(condition=Preconditions.inRange(1..5)
var x: Int
Could possibly do @Invariant(conditions=[...])
David Bieregger
11/07/2022, 12:31 PMcontext(Logging, Application)
fun hello() {
<http://logger.info|logger.info>("Hello " + applicationName)
}
Prefered over this:
fun (Logging, Application).hello() {
<http://logger.info|logger.info>("Hello " + applicationName)
}
In my opinion the second one is more readable and makes intuitively more sense when you know how to do one context receiver just put braces around. I'm sure that considerations have been made here, but I can't imagine one real advatage of the first code example over the second oneJulia Samól
11/09/2022, 6:06 PM@Throws
• not to overlook functions annotated with @Throws
and handle them properly?Sam Stone
11/25/2022, 4:48 AMval Any.field
get() = when (this) { //these classes don't inherit a common ancestor that has the getField() method, so we need to parse them out into distinct classes
is Class1 -> field
is Class2 -> field
is Class3 -> field
...
else -> null? throw error?
}
A useful feature that would help this case is if I could specify that a function can only be called on certain types, similar to where
, so that the compiler knows that it is at least one of those classes, and can find the corresponding function or field. At the very least, it would write this out for me.Rohan Maity
11/27/2022, 5:06 PM// Initially I have an interface Expr (just like in Java) and have two classes (Constant
// and BinaryPlus) implement that interface
interface Exp {
fun eval(): Double
}
class Constant(val value:Double): Exp {
override fun eval(): Double = value
}
class BinaryPlus(val lhs: Exp, val rhs: Exp): Exp {
override fun eval(): Double {
return lhs.eval() + rhs.eval()
}
}
/**
* Here, I added the stringify() method (which is a tool or operation) to the interface Expr,
* without touching the interface and classes which are implementing it.
*/
fun Exp.stringify() : String {
return when(this) {
is Constant -> value.toString()
is BinaryPlus -> "${lhs.stringify()} + ${rhs.stringify()}"
else -> ""
}
}
// Here is how, I can use it
fun main() {
println(BinaryPlus(Constant(4.0), Constant(9.0)).stringify())
}
/**
* Now in object oriented languages, adding types is easier
* and functional languages adding tools(or operations) is easier
* but since kotlin can act as functional and object oriented and with my above given example.
* I think extension function solves the expression problem for kotlin.
*/
Ruckus
12/08/2022, 3:39 PMKroppeb
12/09/2022, 4:53 PMKroppeb
12/09/2022, 4:54 PMcontext(InternalAddOp<T>, InternalAddOp<R>)
prohibited, cause in theory they could have a subtype relation between them, or is that an error?Kevin Del Castillo
12/09/2022, 7:23 PMKotlin has several unsound exceptions, in part due to its goal to interoperate with Java. As you can see in this Kotlin example, generic types can trigger cases where null values can flow into a list declared as holding non-null elements.I understand why Java libraries can sometimes be troublesome (
T!
), but I'm a bit confused about the generic types example they're giving, this is the offending code:
private fun <E> List<E>.addAnything(element: E) {
if (this is MutableList<E>) { this.add(element) }
}
fun main() {
// A list of non-null Ints.
var myList : List<Int> = arrayListOf(1, 2, 42)
// Add a null.
myList.addAnything(null)
// Add a non-number.
myList.addAnything("This is not even a number")
// Print resulting list, not matching `List<Int>`.
print(myList);
}
Which prints:
[1, 2, 42, null, This is not even a number]
Why is this happening? My first guess is that the if
in addAnything
is true because of type-erasure, is this correct?PHondogo
12/18/2022, 7:07 PMvngantk
12/23/2022, 10:11 PMKlitos Kyriacou
01/04/2023, 3:42 PMwhen (expr) { ... }
blocks are just the four specific operators is
, !is
, in
and !in
? It seems quite arbitrary to limit the allowed operators instead of saying you can have any binary operator with just its right-hand side (for example, when (temperature) { < 5.5 -> ... }
Nathan Bedell
01/27/2023, 11:15 PMDron Bhattacharya
02/16/2023, 10:11 AMmbonnin
02/21/2023, 2:54 PMMap
-like type I guess and property accesses would be cast to the build-time type (and assert if wrong). Does that make any sense?Michael de Kaste
03/01/2023, 2:16 PMfilterKeysIsInstance
and filterValueIsInstance
on a Map? Would like to track its progress if its there.Luke
03/01/2023, 9:31 PMval String.isValidUrl: Boolean get() = TODO()
fun areValidCredentials(email: String, password: String): Boolean = TODO()
Then, could the compiler generate:
val String.isNotValidUrl: Boolean inline get() = !isValidUrl
fun areNotValidCredentials(email: String, password: String): Boolean = !areValidCredentials(email, password)
The name could be changed via annotation, or by default the compiler wouldn't do anything but adding an annotation with an optional name could generate the negations..?
I feel it would make code more readable than having the !
before or .not()
after. The standard library already has some negated function such as List.isNotEmpty, so I feel Kotlin could improve by generalizing this trend.Sam Stone
03/06/2023, 12:09 AMandroid.text.TextWatcher
. I am not interested in beforeTextChanged()
and onTextChanged()
, only afterTextChanged()
. Should the compiler assume (or can I inform it) that I will implement it like this?
object : TextWatcher {
override fun beforeTextChanged(...) {}
override fun onTextChanged(...) {}
override fun afterTextChanged(...) {
...
}
}
Dirk Hoffmann
03/13/2023, 4:13 PMcontext(someInstance, someInterface)
I just realized, that if you want to use context receiver declaration on override fun xyz(...)
on interface
methods, then you have to have the context declaration on BOTH, the interface fun definition AND the implementing class fun (correct??).
That is ok by itself ... but the compile time error message for this is 2-pages long and really really cryptic with no hint what might be the problem whatsoever ... don't know if this is the correct channel, but I would love to see a bit more "readable and usefull" compiler error for that case.Dirk Hoffmann
03/13/2023, 4:13 PMcontext(someInstance, someInterface)
I just realized, that if you want to use context receiver declaration on override fun xyz(...)
on interface
methods, then you have to have the context declaration on BOTH, the interface fun definition AND the implementing class fun (correct??).
That is ok by itself ... but the compile time error message for this is 2-pages long and really really cryptic with no hint what might be the problem whatsoever ... don't know if this is the correct channel, but I would love to see a bit more "readable and usefull" compiler error for that case.elizarov
03/14/2023, 12:21 PMDirk Hoffmann
03/17/2023, 10:21 PM