I think state is a valuable metaphor for us since our brains are structured and conditioned to deal with changing state. Single assignment or variableless programming forces us to discard too many effective thinking strategies to be an attractive choice.Kent goes on to show his readers a set of patterns that can be used to manage and communicate state in a safe and effective manner. I agree that state is a valuable metaphor in programming but what is a programmer to do if they also see value in single assignment or "stateless" programming? I think F# offers the most compelling answer to this question and I'll explain why.
You declare a value in F# with the
let
keyword:> let x = 1;;We can later retrieve the value, 1, using our identifier, x:
val x : int
> x;;Suppose, however, that we wanted to change the value assigned to
val it : int = 1
x
. We would use the assignment operator like so:> x <- 2;;As you can see, identifiers are immutable by default in F#. Once declared, they cannot be changed. This behavior extends to more complex value types. Consider this example:
x <- 2;;
^^^^^^^
stdin(13,1): error FS0027: This value is not mutable.
> open System.Drawing;;Even though the X property of System.Drawing.Point is settable, F# treats our Point as if it is immutable. We can see how the default behavior of F# compels the programmer to limit his use of state; that's just the way that it should be. By contrast, it takes a lot of forethought to limit state in an imperative language.
> let p1 = new Point(0,0);;
val p1 : Point
> p1.X <- 1;;
p1.X <- 1;;
^^^
stdin(24,1): error FS0191: A value must be local and mutable in order to mutate
the contents of a value type, e.g. 'let mutable x = ...'.
You can opt-in to the use of state by using the
mutable
keyword:> let mutable p2 = new Point(0,0);;When you declare an identifier as mutable, you get a variable just like you may be used to in C# or Visual Basic. You can even change the reference entirely:
val mutable p2 : Point
> p2.X;;
val it : int = 0
> p2.X <- 1;;
val it : unit = ()
> p2.X;;
val it : int = 1
> p2 <- new Point(1,1);;To conclude this post, I hope to have shown some very basic examples of how F# forces you to think about where you are using state and why. This is a very good thing and in my next post, we will explore the use of state in functions and types.
val it : unit = ()
> p2;;
val it : Point = {X=1,Y=1} {IsEmpty = false;
X = 1;
Y = 1;}
No comments:
Post a Comment