Is int type in Dart a value type or reference type? - flutter

The int type in Dart has default value of null. null is an object of type Null class. (as per Dart documentation). Also, in Dart, int derives from class Object.
Hence,
int i = 10;
print(i.runtimeType is Object); // returns true
This makes me believe that int is not a value type like in other languages (such as C#) but a reference type.
If I am correct, then-
int i = 10;
means i is a reference variable holding the reference to an int object 10.
Is this correct? If not, I would appreciate if a link to the description in the documentation is shared.
Till now, I've been unable to find any proper explanation and hence have come to this conclusion myself.
Thanks.

Yes, Dart's int type is a "reference type".
Dart does not have value types at all, all values are instances of a class, including integers. (At least technically, function values makes their classes very hard to see.)
Integers are immutable and pretends to be canonicalized.
If a and b are int values and a == b, then identical(a, b) is guaranteed to be true, so a and b looks like they are the same object, but it's unspecified whether that's because they really are the same object, or because identical just cheats and does == for integers.
That means that you can largely treat int as a "value type". Whether it is copied on assignment or parameter passing, or you are passing a reference to the same object, is impossible to tell apart. The language ensures that, because it allows the implementations to do whatever is more efficient.
In practice, some integers are unboxed inside functions, some integers are stored as a value in the reference itself, and some are real objects.
(That's also one of the reasons you can't use an Expando with an int).
(In the current Dart language, all types annotations are nullable, meaning that you can assign null to int x;. With the upcoming Null Safety feature, that changes. Types will only be nullable if you write them as such, so int x = 1; would not accept a null value, but int? x; would. And null is an object too, the only instance of the class Null.)

int is a value type in the sense that if you pass int value into a function and change the value of a parameter inside function, it won't affect outer scope.
void add(int inner) {
inner += 1;
}
int outer = 0;
add(outer);
print(outer); // 0, unchanged
But int is still a class even though its name starts from lowercase letter. There was a huge discussion about its naming and lots of people consider it an inconsistency.

Yes int is a class (it even extends num) and therefor has common methods to use on. But one the other side it is different than "normal" classes since you don't have to use a constructor like
int i = int(3);
See int's class documenation https://api.dart.dev/stable/2.8.4/dart-core/int-class.html

Everything in Dart is an object, int, double or num may look like keywords but they are built-in abstract classes. Since they are abstract classes which means they can not be instantiated, they do not start with an uppercase letter.
try this line,
print('2 is instance of "int" class :\t${ 2 is int}');
this will result in true.
And regarding your concern about 'null' :
In Dart, like JavaScript and Python, everything that a variable can hold is an object including null. Every object including null is an instance of some class and all these classes inherit from Object class.
your can refer this link for more info.
Hope this helps.

Related

Dart/Flutter : The meaning of "whether some code is annotated or inferred is orthogonal to whether it is dynamic or some other type"

https://dart.dev/guides/language/effective-dart/design#types
If the code is type annotated, the type was explicitly written in the
code.
If the code is inferred, no type annotation was written, and Dart
successfully figured out the type on its own. Inference can fail, in
which case the guidelines don’t consider that inferred.
If the code is dynamic, then its static type is the special dynamic
type. Code can be explicitly annotated dynamic or it can be inferred.
In other words, whether some code is annotated or inferred is
orthogonal to whether it is dynamic or some other type.
The above explanation is extremely abstract and I'm not sure exactly what this means.
Especially the last sentence, does it mean that "it may be inferred as another type even though it is type-annotated as'dyanmic'"?
But maybe I feel it's not right.
Because I remember being told by the IDE during development that something like "because it's a dynamic type, you can't access that member."
If not, I would like a more specific explanation of what it means after all.
It would be helpful if you could get some clues.
Basically, a variable can be type annotated:
int x = 1;
also, it can be inferred:
var x = 1; // dart knows x is an integer because you assigned 1 to it.
A variable can be dynamic, meaning it's type can change.
That's what the three first sentences mean, the last sentence is saying that a dynamic variable can be either inferred or annotated:
dynamic someFunction() {
return 1;
}
dynamic x = 'aaa'; // annotated
var y = someFunction(); // inferred
So weather a variable is annotated or inferred has nothing to do with weather it is dynamic or not.

what is the difference between either and Option in dartz?

i am trying to understand dartz, but the documentation is not clear enough.
i need to get the difference between either and Option in dartz?
abstract class Option<A> implements TraversableMonadPlusOps<Option, A>
VS
abstract class Either<L, R> implements TraversableMonadOps<Either<L, dynamic>, R>
Well, an Option type normally is a type that holds either a typed value, or nothing.
For example if you want to get the first integer of a list of integers, that might be an Option<int> because it can be an int or nothing in case the list is empty. But it cannot be a string.
An Either type is just what the name says... either one or the other. And it can be two different types altogether. Either<int, string> would have either an int or a string. Never both. Never none. Either one or the other.
For example a functional ParseInt method might return a Either<int, string>, because it will return either a valid int, or an error message.

Is everything an object in Scala?

A literal is an object in Scala, so if you store that into a variable such as val x: Int = 5; would this make this an object as well? Everything seems like to be an object in Scala for some reason.
A literal is an object in Scala,
Well. "Literal" is a property of the source code, mostly. As such, the idea of "being an object" doesn't really apply.
What is correct is that every literal evaluates to an object.
So, the literal 1 in a source file is not really an object. It is just part of the source code. But it evaluates to an object, namely an instance of the class scala.Int that represents the mathematical idea of the integer 1.
so if you store that into a variable such as val x: Int = 5; would this make this an object as well?
What do you mean by "this"?
x is not an object, it is a variable. In Scala, like in almost every other language, variables are not objects themselves, rather they are names for objects. (Technically, a variable references an object.)
Int is not an object, either, it is a type. Types aren't objects. It is possible, however, that a type and a term have the same name, and the reason why that works is precisely because types aren't objects and thus there can never be any confusion about whether you are talking about the type or the term.
Now, 5 in this expression is an object, or more precisely, as we have seen above, it is an integer literal with evaluates to an object.

Scala - How is a variable of type Any stored in memory?

How is it possible to create variable of type Any?
And why does isInstanceOf[Int] print true?
I declared x to be Any, not Int.
How does it work? What is happening behind the scenes?
val x = 4: Any // OK
x.isInstanceOf[Int] // true
x.isInstanceOf[String] // false
[EDIT] Maybe to rephrase my question:
How does val x = 4: Any look like in memory?
And once it is stored in memory as Any type, how can I later say that this particular blob of bytes is Int, but not say String?
Does it come along with some kind of information what was the "original" type? Here for example if I typed 4 AND LATER said this is Any type, would it store this original type of 4 as an Int?
Scala language is defined to support the notion of inheritance polymorphism. In other words, if there is some type T which inherits from type U, then any value of type T can be assigned to a variable of type U:
class T extends U
val x: U = new T // compiles
Same thing with Any and Int: in Scala, Int inherits from Any, therefore it is possible to store an integer in an Any variable:
val x: Any = 4 // essentially the same as your example
Also, all of the runtimes Scala runs on know what type of value is actually stored in a variable, regardless of the static type of this variable. This is important for many features of the language, in particular, virtual method overrides, but it also allows you to do manual checks and downcasts, which is what your code does (the checks). In other words, the isInstanceOf method checks the runtime type of a value stored in a variable, not the static type known at the compile time (which would be quite pointless).

Scala: Why is it necessary to assign values to a var/val during declaration

Unless I've been doing it wrong. It doesn't seem like we can do things like:
var x;
x = 1;
in Scala, but rather you have to declare and assign a value to it. Are there any reasons for why this is the case?
The obvious reason is to help not leave variables uninitialized.
Note that in your declaration without initialization, you will also need to specify the type.
var x: Type;
gives the following error:
only classes can have declared but undefined members (Note that variables need to be initialized to be defined)
Actually only abstract classes can declare members without defining them. You can still get the desired behavior (variables initialized to a default value) as
var x: Type = _
If Type is a reference type, x will be null. This scenario is useful, for example, in case where a factory method completes initialization of an object after object construction.