Should I mark all method parameters as final and specify type - flutter

Effective dart specifies that top-level variables should be final when applicable:
https://dart-lang.github.io/linter/lints/prefer_final_fields.html
However, I could not find any information about method parameters.
Flutter repo's code functions are mostly ones with parameters not marked final, that includes all the overridden build methods I've seen.
Which of the following is better in terms of performance and app weight:
#override build(context)
#override build(BuildContext context)
#override build(final BuildContext context)
Perhaps overridden functions should be defined the same way as the super function? Is there any difference between overridden functions like build above which can infer the type, and other named/unnamed functions (other than not setting the type makes the variable dynamic), which Flutter repo also writes this way:
static double _flingDistancePenetration(double t) { // t is not final, although treated as immutable
return (1.2 * t * t * t) - (3.27 * t * t) + (_initialVelocityPenetration * t);
}
I've seen this question about Java: Why would one mark local variables and method parameters as "final" in Java?, and, while I agree with the top answer, I'm completely in the dark about why does Flutter repo not do that.

Regarding parameter types: yes, always include them. Otherwise your parameter is likely to be dynamic1, which incurs runtime overhead and no type safety. You also want your API to clearly specify what argument types it expects.
Regarding final: That is an opinion-based question, and my opinion is that while I agree with the prefer_final_fields lint, I disagree with the prefer_final_locals lint. I think that adding final for local variables (including function/method parameters) is pointless.
Contrary to what the top-voted answer to the related Java question says, any half-decent compiler should be able to easily determine whether a local variable is reassigned. If there's any optimization opportunity there, the compiler should be able to do it for you.
In languages such as Dart where implementation usually is inline with the interface (as opposed to languages such as C or C++, which have separate header files to declare interfaces), adding final to parameters is visual noise. It provides no useful information to callers.
You shouldn't unilaterally mark all function/method parameters as final anyway. Sometimes reassigning parameters is appropriate. For example, if your function needs to perform some sort of normalization on its arguments:
void foo(File file) {
file = file.absolute;
...
}
in such a case, using a final File file would mean you'd need a separate local variable for the normalized version, and now the code would be error-prone since it could accidentally use the original variable.
final for a field is an important part of an API. It tells callers that the field will not be reassigned; the object referred to by the field will always be the same object. final for local variables and for function/method parameters affects only the person implementing the function. If the implementor doesn't want to reassign a variable, they can choose to simply not reassign it.
Some people will claim that having final local variables helps code readability since they know that the variable will not be reassigned. However, I instead think that final can be misleading since it says only that a variable cannot be reassigned, not that it won't be mutated, and knowing the latter is much more important.
1 For overridden methods, parameter types are constrained by the corresponding parameter types declared by the base class. Therefore omitting a parameter type in an overridden method will use the parameter type from the base class.

Answer to the author of the question.
You should not mark all method parameters as final
You should specify the type
Examples:
foo(Baz baz)
void main(List<String> args)
An exception to these rules.
You can omit the type indication if the type is dynamic
You can don't specify type if the type can be inferred automatically by the compiler, in the case of using an function-expression.
foo(Baz baz, bar)
list.sort((x, y) => x.compareTo(y))
Some useful information:
From Dart specification:
Dart Programming Language Specification
5th edition draft
Version 2.2
A final variable is a variable whose binding is fixed upon initialization; a final variable v will always refer to the same object after v has been initialized. A variable is final iff its declaration includes the modifier final or the modifier const. A mutable variable is a variable which is not final.
Variable immutability does not make an object immutable in Dart.
This is a very common misconception when variable immutability is confused with object immutability.
P.S.
A common misconception is that Dart users get the impression that function parameters in Dart are passed by reference.
This is not true.
Parameters are passed by value (not by reference).
But due to the fact that (as indicated in the specification) any variable already contains a reference (refers) to the object (but not the object itself), in fact, this reference is passed, by value (as normal value).
That is, a value is passed, but the value itself is of the Referernce type, which is indicated in the language specification.
From Dart specification:
a final variable v will always refer to the same object
That is, the variable stores the reference, but not the value itself.
It is this reference that is passed by value, because there is no reason to pass this reference by reference.

Related

Flutter: Late Initializing a "widget-dot" Class-level Variable in a Stateful Widget -- What's Going on?

Consider the following class level property inside the state class of a stateful widget:
int myInt = widget.int;
Android Studio informs that: "The instance member 'widget' can't be accessed in an initializer."
(I understand what this error means).
So then if we add the late keyword, it appears to be fine:
late int myInt = widget.int;
However... this is surprising to me that I’m allowed to do all that in one line — I thought that late variables had to be not set/set as null:
late int myInt;
... and then assign inside onInit.
Since I didnt declare when to assign it, I dont know when the assignment takes place.
The question is:
Is the one-liner “late int myInt = widget.int;” exactly equivalent to assigning it myself in the initState method?
The late keyword in Dart has 2 distinct usages, melt into a single keyword.
The first usage, e.g. late int i:
This usage is well-known: delay assigning a value until later. This is most commonly used to make a field non-nullable, even though you might not have the value right away. I'm sure you are familiar with this usage.
The second usage, e.g. late int i = 0:
This is to delay the value calculation until the field is being accessed. This is useful when the value is expensive to calculate, so you might want to delay its calculation until it's needed for the first time. It's stated on the official documentation:
When you do this, the initializer becomes lazy. Instead of running it
as soon as the instance is constructed, it is deferred and run lazily
the first time the field is accessed. In other words, it works exactly
like an initializer on a top-level variable or static field. This can
be handy when the initialization expression is costly and may not be
needed.
So basically, depends on whether you assign a value right away (on the same line), Dart will decide which of the 2 usages you are using. If you write late int i it will be the first usage, if you write late int i = 0 or late int i = calculateValue() it will be the second usage: delay the calculation until when the field i is accessed for the first time. It's like lateinit in Kotlin or lazy in Swift.
Now back to your case. By assigning a value on the same line as the late keyword, you are using the second usage, basically "lazy init" until the field is accessed for the first time. By the time it's accessed, this class would've been instantiated, so (by that time) you are allowed to use the this keyword.
In the first case Android studio throws that error because int myInt requires a value the moment you are declaring it.
In that particular moment, in the Statefull widget state, the widget object is not accessible.
In the second case:
late int myInt = widget.int;
That is a valid one line declaration and assignment of the variable, but the effect is a bit different from the onInit alternative.
The late keyword works in a lazy way.
Instead of running as soon as the instance is built, it run the first time the field is used. In that moment the widget object will be accessible.
Take a look at the answer to this question, it can be helpful: here
Assigning the value inside the onInit guarantees that the value is actually assigned only once when the widget is initialized.
widget.xxx corresponds to the value of xxx of the instance of a widget, ie the widget once it exists.
So when you use widget.xxx in initialisation of the widget, the var xxx does not exists.
That's why the dart compiler tell you The instance member 'widget' can't be accessed in an initializer .
By adding the keyword late in front of the declaration, you tell the compiler that this variable will be defined later.
But be careful, it will then really have to be defined later (in initState for example) and in any case before any use.
This error comes from the fact that dart is now a null safety aware language.
That is to say a language that strives to ensure that no variabales can have a null value. This is for reasons of code quality and greater code security.

Why can't non-nullable fields be initialized in a constructor body in Dart?

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.

Why do some Matlab class methods require "apparently" unnecessary output argument

After evolving my project code for months, I've finally hit a need to define a new class. Having to romp through my previous class definitions as a refresher of the conventions, I noticed that all constructors and property setters all have an output argument, even though nothing is assigned to it, e.g.:
function o = myConstructor( arg1, arg2, ... )
function o = set.SomeProperty( o, arg1 )
I've been looking through the documentation for upward of an hour without finding the explanation for this. It doesn't look like it depends on whether a function is defined in the class definition file or in its own separate m-file.
Can anyone please explain?
The best place to start is the documentation "Comparison of Handle and Value Classes". From the very top:
A value class constructor returns an object that is associated with the variable to which it is assigned. If you reassign this variable, MATLAB® creates an independent copy of the original object. If you pass this variable to a function to modify it, the function must return the modified object as an output argument.
A handle class constructor returns a handle object that is a reference to the object created. You can assign the handle object to multiple variables or pass it to functions without causing MATLAB to make a copy of the original object. A function that modifies a handle object passed as an input argument does not need to return the object.
In other words, value classes need to return a modified object (which is a new object distinct from the original), while handle classes don't. The constructor of either class will always have to return an object, since it is actually constructing it.
Some good additional reading is "Which Kind of Class to Use", which links to a couple helpful examples of each type of class object. Looking at the DocPolynom value class example, you can see that property set methods have to return the modified object, while the dlnode handle class example only requires an output for its constructor. Note that you could still return an object from a handle class method (if desired), but it's not required.

For an object in scala to be immutable what is required?

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.

With Scala closures, when do captured variables start to live on the JVM heap?

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.