Hello! who can explain what is a main aim of the ‘...
# getting-started
e
Hello! who can explain what is a main aim of the ‘const’ word? i know the mechanism (compile time and no getter method). But i cannot understand when it is useful.
j
The word is used for creating a ... constant. If you want to learn more about the utility of constants, wikipedia has a great article: https://en.wikipedia.org/wiki/Constant_(computer_programming)
💩 1
c
that description seems to match
val
in Kotlin though, while
const
is something different, right?
p
It used at compile time and compiler can optimize code depending on the const value. It can remove "if" branches, for example. For example, to remove logging call completely (i.e. the logging code won't present in the compiled code), you can do something like this:
Copy code
const val DEBUG_LOG_ENABLED = BuildConfig.BUILD_TYPE == "debug"

inline fun debugLog(block: LogWrapper.() -> Unit) {
    if (DEBUG_LOG_ENABLED) LogWrapper.block()
}
If you remove "const" runtime check will be occurred.
v
Will that really work?
const
has to be a compile-time constant. So this shouldn't compile, should it? Unless maybe if
BUILD_TYPE
is a
const
too.
p
Of course BUILD_TYPE is const too
BTW, because of stupid solution of AGP developers, we can't use "DEBUG" property here
Copy code
public final class BuildConfig {
  public static final boolean DEBUG = Boolean.parseBoolean("true");
  public static final String BUILD_TYPE = "debug";
}
e
it’s synthetic a lot what is the real speed up of such manoeuvre?
p
Yes. If you have much debug logs, removing of the logging code in compile time increases performance. The approach removes the logging completely, including messages' stringbuilder
e
j
that description seems to match 
val
 in Kotlin though, while 
const
 is something different, right?
val
is a read-only local variable. Compare that to
const
: https://kotlinlang.org/docs/properties.html#compile-time-constants I would assume a
val
is similar to a Java
final
and a
const
would most closely resemble a
static final
? I don't really know why the poopwas given to the wikipedia article, but I might be missing some context related to the question. Besides the optimisations already known to OP
const
has great semantic utility. At least, that is my view of it.
e
static final ~ companion object { val ... }
fyi
j
Yes, I know. But Java doesn't have constants.
So semantically, what is achieved in Java with
static final
would probably better be replaced by
const
in a kotlin program.
e
Exactly! And this is why I am interesting in kotlin devs motivation to invent it
j
Ah, I see. My guess would be that it is related to a main difference of Kotlin vs Java: that not everything has to be a class. Consider this:
Copy code
class A {
    companion object {
        val MY_CONSTANT = 123
    }
}
compared to this:
Copy code
const val MY_CONSTANT = 123
v
You can also do
Copy code
val MY_CONSTANT = 123
The question is whether you want to have
MY_CONSTANT
in the
A
namespace or not
But it is still not a compile time constant that the compiler can inline
const
is like a
static final
in Java for which you use upper-case letters, as you should usually just use that for real constants and not for any
static final
.
p
BTW, you can't use non-const for annotations. OK:
Copy code
const val QUERY = "SELECT id FROM table"

@Dao
interface ADao {
    @Query(QUERY)
    fun query(): Int
}
Won't compile:
Copy code
val QUERY = "SELECT id FROM table"

@Dao
interface ADao {
    @Query(QUERY)
    fun query(): Int
}
e
ok! is there any sense to write so:
companion object { const val ABC = "abc" }
disclaimer: it’s not my code 😉
v
Sure, why not? It is still a compile-time constant that you can use where you can use compile time constants with the compile-time optimizations in place and it is namespaced to the class of which this is a companion object
If you add
private
, then I'd say it is non-sense clutter and a top-level
private const val
would achieve the same
e
Java does have constants, `final int`/`final String` fields with compile-time constant non-null values will be marked in the resulting .class file and inlined at use sites
however Java doesn't have the ability to mark a final field as non-inlined (for future API compatibility reasons, for example) while giving it a compile-time constant non-null value... without hacks like what AGP does (
Boolean.parseValue("false")
)
Kotlin clearly distinguishes the cases with
const val
vs
val
e
thx for all the answers!