Small example about immutability:
class Point {
Point(this.x, this.y);
int x,y;
int get sum => x + y;
}
class ImmutablePoint{
final int x,y, sum;
const ImmutablePoint(x,y) :
this.x = x,this.y = y,this.sum = x + y;
}
class SemiImmutablePoint {
int _x, _y; // _ -like private but not access protected by the VM.
SemiImmutablePoint(this._x, this._y);
int get x => _x;
int get y => _y;
}
void main() {
List<int> li = [1,2,3,4,5];
final List<int> immutableLi = const [1,2,3,4,5];
li[1] = 10; //ok
li = [6,7,8]; //ok
immutableLi[1] = 10; //error because const
immutableLi = [6,7,8]; //error because final
var p = new Point(5,10);
p.x = 10; //ok
p.sum = 10; // error can't be directly mutated
var p2 = const ImmutablePoint(5,10); // compile-time constant
p2.x = 10; //error
}
You can use FP with the Dart or even languages without types or immutability like JS. it's just a style, it doesn't require native implementation in the language.
With the languages like Scala FP paradigms are normally implemented with the type system so it's more restrictive and harder to unintentionally breach. But at the same time you require from the lib user specialized knowledge of really complex type system, sometimes category theory - otherwise it's really hard to benefit from knowing that this thing is "monad" or "monoid" or whatever. I can use lists without knowing that those are monads or really useful concept of "future" in Dart. When you implement FP without "type magic" it's often clearer and more accessible to grasp by an average developer. But at the same time having powerful type system can help compiler perform advanced code optimizations and enable better static code analysis.
Category theory for JavaScript programmers - Worth watching.
added: Now collections have UnmodifiableListView UnmodifiableMapBase UnmodifiableMapView