Is the answer to this :
Instantiation of the object uses 'val' instead of 'var'.
Each member variable of the object being created is also 'val' instead of 'var'. This is to prevent users updating an object value after its set.
An object is immutable if there is no way for the user of that object to mutate it. This means that it must have no public methods that reassign any of its member variables or mutate any objects referred to by those variables. If all the object's members are vals this ensures the former (i.e. they can't be reassigned), but not the latter (i.e. if the objects referred to by those variables are themselves mutable, they can still be mutated by calling mutating methods on them even if they're referred to only by vals).
Also note that even if the members are declared as vars, the object can still be immutable if none of the object's methods actually reassign the variables (or call mutating methods on them) - assuming of course, they're private.
So having only val members is neither necessary nor sufficient for an object being immutable. Whether the object is referred to by a val or a var (or both) makes no difference in that matter.
#sepp2k nicely and correctly explains the criteria for an object being technically immutable. One subtle point missing from his answer is that not all member variables correspond to externally visible state. A member may also be e.g. a cached internal value to store some local, hard to compute data which is not directly visible from outside (thus qualified as private[this] in Scala). An object can have such a var member e.g. to store a computed hash value. It can even be accessible via a public getter - as long as the behaviour of the accessor is purely functional, i.e. it always produces the same value for each invocation on the same object (except that it returns faster when reusing the internally cached value).
The Scala compiler is aware of this distinction so it can help one to implement an immutable class correctly, even when using mutable state internally. This is important when generic type variance comes into play. Namely, the compiler allows a generic type parameter to be covariant even if the class contains reassignable fields of this type - as long as these fields are private[this], ensuring that one cannot have a reference to a containing object that has a statically weaker type than the type the object was defined with (which would be a precondition for variance to cause type errors).
This is explained in more detail, with a code example, in section 19.7 of Programming in Scala.
Related
Often times I have an instance field that needs to be initialized in a constructor. For example, it might be needed to be calculated based on other instance fields, hence I can't initialize it inline (where declared) or with a constructor initializer list.
But it either has to be nullable, or declared late, if I need to initialize it in constructor. The rationale behind late keyword is that programmer states "I'll initialize this before using, trust me", when it can not be determined by the compiler that initialization will take place before first usage. BUT: this "programmer guarantee" seems A) terrible and B) unnecessary in case of constructors, because it can be determined by compiler whether the field was initialized in a constructor (and constructor itself is obviously guaranteed to execute before any other instance methods).
Obvious downside to using late fields in such scenarios is that nothing enforces them compile-time to be actually initialized during construction (or anywhere, for that matter). Plus, every time the late field is read, a runtime check is inserted to make sure it has been assigned a value - I don't need that when I initialize in constructors.
Therefore, it seems that, technically it should be possible to have non-nullable non-late fields that are initialized within a constructor body (and if they are not - compiler can throw an error).
So what is the rationale of requiring constructor-initialized fields to be either nullable, or declared as late? Is there a technical reason why this limitation is imposed, or is it just a design oversight by the Dart team?
Dart executes constructor bodies inside-out, from base class to derived class. This allows virtual dispatch to occur in the constructor body. The fact that virtual dispatch can occur in the constructor body means that the compiler cannot statically determine what code will be executed by the constructor body, and therefore it cannot deduce what the constructor body might ultimately initialize.
That the constructor body can execute arbitrary code (including callbacks) that might initialize members or that might depend on initialized members makes it even more complicated.
Furthermore, allowing members to be not initialized when the constructor body runs would be error-prone and a source for confusion. For example, with:
class SomeClass {
int member;
SomeClass() {
updateMember(0);
}
void updateMember(int value) {
print(value); // Oops.
member = value;
}
}
With Dart's current design, all instance methods (and their overrides) can be guaranteed that members are initialized when the method is called. If members were allowed to be uninitialized when the constructor body is executed, that would not longer be true, and all instance methods then would need to consider if they might be invoked from the constructor (or from a base class constructor), possibly indirectly from other method calls, and whether accessed members might not be initialized yet.
(I'll grant that that previous point isn't terribly strong since it currently can still happen that a member is initialized to an object that the constructor body must mutate, but typically instance methods receiving an empty List, Map, etc. is less of a problem than receiving uninitialized members. The above situation also could happen with late members, but that's the baggage that comes with choosing to use late.)
Null-safety disallows the possibility of accessing uninitialized non-late variables, but your proposal would make that possible.
Also, because there is a distinction between initializing members via an initializer list and via a constructor body, people are encouraged to use initializer lists when possible.
The point that you are ignoring here is that when you want to pass a variable to a constructor you will definitely initialize it, otherwise you wouldn't be able to use that widget because you have to pass the variables needed to its constructor. so this late or nullable keywords can be used for the values that you are trying to pass to a widget and not in the widget itself that you are passing them to, but before it.
I am having trouble understanding my professor's lecture notes because my brain seem to treat objects, attributes, variables and class instance as interchangeable. I really appreciate any help in distinguishing these 4 terms. Thank you!
this would be helpful for u Visit https://www.quora.com/What-is-the-difference-between-instance-variable-and-class-variable
Class variables are declared with keyword static and Instance variables are declared without static keyword.
Class variables are common to all instances of a class. These variables are shared between the objects of a class. Instance variables are not shared between the objects of a class. Each instance will have their own copy of instance variables.
As class variables are common to all objects of a class, changes made to these variables through one object will reflect in another. As each object will have its own copy of instance variables, changes made to these variables through one object will not reflect in another object.
Class variables can be accessed using either class name or object reference. Instance variables can be accessed only through object reference.
https://qph.fs.quoracdn.net/main-qimg-c4b92e80a8500c11fe705c1bafc3ed26
You don't mention the programming language at question.
Usually a class is a model or template that declares
how a certain category of objects look like.
You give a class a name and you mention if it inherits
members from another class or not.
You define also the class members.
These can be variables that hold data (object state)
and methods (class defined functions) that define
the object behaviour.
When you instantiate a class using the declared model
, you get an object, that is a concrete class instance.
This is a concrete entity, think of it as a new variable in memory,
whose data type is the class (instead of for example
integer or string data types), whose value is its state
in a defined moment in time (the state being the
combination of all of its data member variables values
at that moment). This object has to have an identity,
because it exists in memory and it is a different entity
from the other objects you can instantiate from this or
any other class. The data member variables hold specific
values for each instance. These are not shared between
instances.
Now the member methods can be shared between instances
because they have no state, so they are equal for every object.
They are called with some arguments
and they do some action that changes the object state, or
is at least tightly related with the concrete object.
But they are common to every object. The methods usually
know what concrete object they act upon by means of a special
name like 'this' or 'self', that references to 'itself'.
Objects are usually assigned to variables upon creation,
storing a reference to its identity that allows the
remaining code to manipulate them.
You use these variables to refer to the concrete object
outside the code of the classes, and use 'this' or 'self'
to refer to it from inside the classes.
Frequently you access object members qualifying with the
object name. Like in 'player.run()', or 'player.total_score'.
That is if player is a variable to which you assigned a
class Player instance. This can look like player = new Player
or player = Player().
Attributes is just another name given to data members.
Sometimes attributes and also methods can be public or private,
meaning code outside the class can use them, or only
the class code can have access.
Sometimes you see data members or attributes referred as
properties. When you access an attribute, you are accessing
a property. In some languages like Python, property can mean
something a little different but close related anyway...
Now also depending on the language things can be like described
(C++, Java) or you can have everything being treated as objects,
including the class definitions (Python).
You should also search the internet or SO about
inheritance, overriding, class diagrams, and other things class
related.
This is all no more than the ability of defining your own data types
beoynd the language builtin types.
You can think of variables as names for boxes (memory containers in a certain address) holding values. But sometimes you want to manipulate
not the values but the addresses themselves. This time you say you have
references (to addresses). Sometimes variables are just names for those
references. References are also known as pointers. But you could do math with pointers (increment, decrement, add a fixed value to...) that you usually don't do with references.
What is the difference between the const and immutable type qualifiers in D?
Something that is const cannot be mutated via that reference but could be mutated by a mutable reference to the same data. Something that is immutable can't be mutated by any reference to that data. So, if you have
const C c = foo();
then you know that you cannot mutate the object referred to by c through c, but other references to the object referred to by c may exist in your code, and if they're mutable, they could mutate it and therefore change what c sees. But if you have
immutable C c = foo();
then you know that it's not possible for the object referred to by c to change. Once an immutable object has been constructed, it's illegal for it to be mutated, and unless you subvert the type system via casting, it's not even possible to have a mutable reference to an immutable object. And since immutable objects can be put into read-only memory if the compiler chooses to, you could actually get segfaults and the like if you ever tried to cast away immutable and mutate the object. The same goes for const, since a const reference could actually refer to an immutable object. Casting away either const or immutable and then mutating the then mutable object is undefined behavior and should basically never be done.
And since an immutable object can never be mutated even by another reference, reading an immutable object from multiple threads is completely thread-safe. So, immutable objects are implicitly shared across threads, whereas everything else which isn't explicitly marked with shared is considered thread-local. immutable also provides better optimization opportunities to the compiler than const does, because it's guaranteed to never change, whereas a const object can change through another reference to the same data.
For value types, there isn't really much difference between const and immutable (since you can't have mutable references to non-mutable value types), but for reference types, there is a significant difference.
When you declare something as const, you promise that you won't modify it. When something is declared as immutable, you get promised that it won't get modified somewhere else(and ofcourse, you can't modify it either)
They are different in that immutable data, could actually placed in read-only sections of memory, and hence, any attempts to modify the data it will fail.
Something declared const (and not immutable) on the other hand exists in the r/w section and the value can still be changed via a different non-const reference to it.
So, "const-ness" can be bypassed in such a case, while immutability cannot.
(Reference)
A variable declared of type const can accept a mutable value or immutable value. This definition is relevant for referenced types like arrays and objects or pointers. It would typically be used for function arguments. So in D const is a kind of wildcard attribute for mutable and immutable values.
It doesn't have much sense for values that are copied with an assignment like a char, int or float.
The concept of const and immutable is very different from the one found in C and C++. I was very confused by this.
Related question:
Scala closures compared to Java innerclasses -> final VS var
I wonder when do Scala makes the variables captured into a closure live on the heap instead of the stack. I'm reading the Scala book of Martin Odersky but for now i didn't find this information. Can someone explain what's behind the hood?
An anonymous function (and actually, any function) in scala is actually an object (an instance of Function*). When it is instantiated, the capture of vals is done by copying the vals into internal fields of the function object. In the function body (that is, in the function object's apply method) the access to the captured vals is done by accessing these fields.
The capture of vars is similar, except that the compiler has to add a level of indirection: the var value is accessed through some hidden mutable holder (simply an object with a mutable field pointing to the current value of the var) and this is this holder that is copied into the function object. When writing into the var (either by local code or by the function object), it is the holder's field which is written. This mechanism ensures that the local code and function's code manipulate the same data, and both see each other's modifications.
So the answer is that a captured vals and a captured var both always live on the heap (whether directly as a field of the function object, or as a field of some wrapper object)
I don't know the insides of the compiler, but here is how it can be done. For each local variable, the compiler maintains a flag initialized to false. Whenever the variable is used, the compiler checks whether it is being used inside a class or closure that doesn't contain the variable's declaration; if so the flag is set to true. At the end of the variable's scope, if the flag is still false, the variable can live on the stack. Otherwise it must live on the heap.
I'm very confused by Scala's HashSet and Set types as they both seem to do the same thing.
What is the difference between them?
Is it the same in Java?
In my reference it says that HashSet is an "explicit set class" (as compared to Set). What does that mean?
Scala's mutable and immutable HashSet implementations are concrete classes which you can instantiate. For example, if you explicitly ask for a new scala.collection.immutable.HashSet, you will always get a set which is implemented by a hash trie. There are other set implementations, such as ListSet, which uses a list.
Set is a trait which all the set implementations extend (whereas in Java, Set is an interface).
Set is also a companion object* with an apply** method. When you call Set(...), you're calling this factory method and getting a return value which is some kind of Set. It might be a HashSet, but could be some other implementation. According to 2, the default implementation for an immutable set has special representation for empty set and sets size up to 4. Immutable sets size 5 and above and mutable sets all use hashSet.
*In Scala, instead of having static class methods, you can create a singleton object with the same name as your class or trait. This is called a companion object, and methods you define on it can be called as ObjectName.method(), similar to how you'd call a static method in Java.
**Set(x) is syntactic sugar for Set.apply(x).