Is `String` a primitive type ? if so , why I can u...
# getting-started
x
Is
String
a primitive type ? if so , why I can use
lateinit
on it but not on
Int
? the doc(https://kotlinlang.org/docs/properties.html#late-initialized-properties-and-variables) says
The type of the property or variable must be non-null, and it must not be a primitive type.
I got a error like this
j
String
is not a primitive type, so everything checks out here
x
it's amazing that String is not a primitive but Int is
j
Why so?
x
In ts , string and number and boolean are primitive type and object are not , actually, I never think why is that .
j
I don't think there is a concept of primitive type in TS
x
could you please tell me how to tell a type is primitive or not ? for me , I think if you can declare some without new , then it is primitive, say
var name = "something"
, so name is a
String
and it is primitive, and
var someone = new Person()
then someone is not a primitive.
m
It’s a common confusion, “primitive” here doesn’t mean “built-in” types as apparently you’d expect. In JVM languages, primitive types, also called value types, pretty much means “stack-allocated”.
j
for me , I think if you can declare some without new , then it is primitive
No, that just means that the language supports literals for that type
🚫 1
m
primitive types are byte, short, int, long, char, float, double, and boolean
everything else is a reference type
k
By the way, on Kotlin you don't use the
new
keyword
k
Kotlin documentation is confusing as to whether or not Kotlin has primitives types at all.
k
Certainly Kotlin/JVM has. But Kotlin as a language in its own right?
m
yeah, Kotlin is a bit blurry on that; in short: Kotlin’s
Byte
,
Short
,
Int
,
Long
,
Char
,
Float
,
Double
, and
Boolean
types are represented as JVM primitives if they’re non-nullable, or as boxed (reference) types if they’re nullable.
yeah, I apologize; I’m way too biased towards Kotlin/JVM
j
Kotlin documentation is confusing as to whether or not Kotlin has primitives types at all.
I agree it's a bit strange that you can get compile errors mentioning them, but there is no clear definition of primitive types in the docs. On the one hand, it is kind of an implementation detail on the JVM, but on the other hand it's quite important that the users are aware of them if they can face limitations on some language features like
lateinit
k
I think the Kotlin documentation sometimes just assumes familiarity with the JVM making it somewhat confusing sometimes.
2
k
It's also confusing that you can declare
const
values for the "primitive" types (whatever they are) and also for
String
. But not for any other type, such as classes. Even though String is a class.
m
Yeah — again it’s a JVM implementation detail driving a language feature
(Strings literals are interned by the compiler)
k
It's only for String literals as well, correct?
👍 1
k
Although,
const
values are not necessarily linked to primitives in some languages, I think there's even some work to introduce constant compile-time evaluation to Kotlin, which in the future should allow you to use other types as
const
values
1
m
const
in Kotlin means “value determined at compile time”
j
@Klitos Kyriacou that specific problem about const will probably be solved separately. It's not about primitive types per se, but also expressions that can be computed at compile time, or functions that can be called at compile time. There is an issue in Youtrack for this
👍 2
x
I think it is pretty like JS, I mean you can do it like this
const five = 5;  five.toString()
in js, so I never dive into that before.😅 I have a long way to learn kotlin.
m
JS’s
const
is more akin to Kotlin’s
val
, that is, a non-reassignable variable definition
that said, JS const values can be mutated:
Copy code
const arr = [1, 2];
arr.push(3);
arr[1] = 'x';
console.log(arr);
> [ 1, 'x', 3' ]
(same is true for Kotlin’s
val
)
k
That's know as internal mutability
m
but not for
const
— since only values that are fully computed at compile time can be const
x
wow, totally new concept to me. I used to think
val
is equal to
const
, so the variable
arr
above is not
const
, right ? cause you may push something into it later. so it can't be computed at compile time.
j
used to think
val
is equal to
const
@xun su as Marcus just said, Kotlin's
val
indeed corresponds to JS's `const`: they define variables that cannot be reassigned. But Kotlin's
val
is not the same as Kotlin's
const
, because Kotlin's
const
requires a value that can be computed at compile time
💯 1
k
And both JS const and Kotlin val are not immutable, they are read-only
1
m
even “read-only” is misleading; they’re just not reassignable
k
True, but I think the documentation often refers to it as read-only, especially when talking about collections.
I think this highlights that if you're learning Kotlin without having worked with the JVM previously, some things are very easy to misunderstand.
k
When referring to collections? I think that'd be a wrong statement, as already mentioned you can actually declare a
MutableList
with
val
and still remove and add elements to it, how is that considered read-only?
k
I'm not arguing that, or arguing at all. I'm just saying I used it interchangeably.
m
that’s why I mentioned this is somewhat misleading;
val
only means you can’t assign a different value to that name.
j
you can actually declare a MutableList with val and still remove and add elements to it, how is that considered read-only?
@Kevin Del Castillo nobody said the list was read-only, only the
val
property is read-only. It's a property that can only be accessed, but not changed. So the property will always point to the same mutable list. It doesn't mean the list itself is read-only. That depends on the list.
☝️ 1
k
Yeah, it depends on the type, could be a
MutableStateFlow
,
MutableList
, etc. I think I just misunderstood this:
True, but I think the documentation often refers to it as read-only, especially when talking about collections.
j
even “read-only” is misleading; they’re just not reassignable
I don't really find this confusing, you just need to be clear about what things we are referring to. I believe most of the confusion comes from the fact that some people confuse reference variables with the instances that those variables point to.
1
❤️ 1
k
Now, if you want to get more confused, and hopefully understand more about mutability, immutability, internal mutability, references, etc learn Rust, the learning curve can be a bit steep at the beginning but it truly helps to clarify a lot of these concepts down to a lower level of abstraction
j
True, but I think the documentation often refers to it as read-only, especially when talking about collections
Read-only collections are a different beast, but the terminology is the same because the concept is the same. A handle to something can be read-only, but that doesn't mean the thing it handles cannot be changed. So a
val
property is read-only in the sense that you can only read (access) its value, but not set its value (you cannot assign another value to it). Some implementations of
val
properties may return arbitrary values, like
val x: Int get() = Random.nextInt()
. This property is read-only, you cannot set its value, but each access will give a different value, so it's not constant, nor immutable (this term is not really applicable to a property, but rather to a value) In the same vein, a variable of type
List
is read-only in the sense that it is a handle that only provides read operations from the list instance it is pointing to. Using such a variable, you can get elements from the list, read the size of the list etc., but not add or remove elements from that list. However, this doesn't prevent (in itself) other pieces of code from adding/removing elements from the list if they use a variable of type
MutableList
to access that same list instance, so long as the instance itself really is a mutable list.
💯 3
☝️ 1
x
Could someone explain a little to a newbie that what is immutable and what is readonly. For me , I think 5 stored in computer as
101
, if you declare a variable with 5 , it is immutable. but if you declare a varible with a list, actually you can add a node or remove a node, but you don't wanna do this , so you use a mutable interface to tag it is readonly so if you add or delete node, your IDE will give you a error.
j
@xun su I just did before you sent the message 🙂 please let me know if it's unclear
x
excellent! but I wanna run the code , it gives me some error I don't understand
j
Ah, this is because the getter syntax I used can only be used for properties, but here you're trying to use it for a local variable (a variable declared inside a function, here
main
). You could try it by declaring
x
outside the
main
function:
Copy code
import kotlin.random.Random

val x: Int get() = Random.nextInt()

fun main() {
	println(x)
    println(x)
    println(x)
}
See it in the playground here: https://pl.kotl.in/oj6JEmo9o
x
after read your message above twice , you mean immutable is some variable that each time you access it it give you the same result ? so a list with immutable interface is not really a immutable thing, other piece of code may change the list.
j
Actually I believe the "immutable" term is a bit confusing if we're talking about a variable or property. IMO a property is either mutable or read-only depending on whether you can assign a new value to it. Immutability IMO makes more sense when we talk about values/objects. A value is immutable if it cannot be changed. So I would say a value is immutable if it is a primitive type or if it is an object that has only read-only properties, all of which pointing to immutable objects themselves or having immutable primitive values.
1