F# (FSharp) Local Constants

F# (FSharp) Local Constants

I just realized that my post last month on the immutability benefit of F# failed to address one of the most basic benefits. In C# and VB.NET, I *believe* it is *impossible* to have “local” constants to non-literal values while in C++ and F# it *is* possible to have these “local” constants.

You *might* be thinking: what about C#/VB.NET const (1) and ReadOnly (2)? Unfortunately, those don’t work in every scenario. The problem with C#/VB.NET const is that it seems to only work with literal values. At the time of this post, the documentation even seemed to say "...the only possible values for constants of reference types are string and null." (1)

If you try compiling this program in C# you will get an error:

    
namespace testApplication
{
   class Program
   {
      static int square(int x) {
         return x * x; 
      }
      static void Main(string[] args)
      {
         const int squareOfThree = square(3);
      }
   }
}
    
    

error CS0133: The expression being assigned to 'squareOfThree' must be constant

Your next thought might be to try and replace the const keyword above with the readonly (2) keyword that I mentioned in the post last month but then you will get yet another error:

The modifier 'readonly' is not valid for this item

In fact, at the time of this post, I don't know of anyway to get around this problem in C#/VB.NET. Unmanaged C++ and F# resolve the problem quite eloquently though. In Unmanaged Visual C++, you just use the const keyword like this and squareOfThree will not be changeable for the rest of its local life:

    
#include "stdafx.h"

int square(int x) {
   return x * x; 
}

int _tmain(int argc, _TCHAR* argv[])
{
   int const squareOfThree = square(3);     
}
    
    

On the other hand, in F# you would simply do something like this
(Notice how the below fully complete program is *much* easier to read then either the C# or Unmanaged C++ versions and has the same or better features):

        
let square x = x * x 
let squareOfThree = square 3
    
    

Then, if you try to do any of the following, you will get errors:

        
let square x = x * x 
(* SquareOfThree immediately becomes a local constant just like it did
   in Unmanaged C++ with the "const" keyword. *) 
let squareOfThree = square 3


(* Now, if you try to change squareOfThree, you will get errors *)
(* Trying to change squareOfThree by redefining it, yields an error *)
let squareOfThree = 8

(* Trying to change squareOfThree using F#'s assignment operator 
   yields yet another error (3) *)
   
squareOfThree <- 8

    
    

c:\users\shawn_000\documents\visual studio 2010\Projects\ConsoleApplication8\ConsoleApplication8\Program.fs(18,1): error FS0027: This value is not mutable
c:\users\shawn_000\documents\visual studio 2010\Projects\ConsoleApplication8\ConsoleApplication8\Program.fs(13,5): error FS0037: Duplicate definition of value 'squareOfThree'

This demonstration of "local" constants shows yet another feature of how the functional F# behaves like the good old imperative C++. While it is really unfair to compare F# and C++, I think it is interesting to note that F# seems to be one of the few languages that can do some of the things that Unmanaged C++ can that VB.NET and C# can't. The default immutability of F# is one example of how F# comes closer to meeting the const-correctness (4) of Unmanaged C++.

Bibliography

1. Microsoft.
const (C# Reference).
MSDN. [Online]
[Cited: FEB 02, 2013.]
http://msdn.microsoft.com/en-us/library/e6w8fe1b(v=vs.100).aspx

2. Microsoft.
readonly (C# Reference).
MSDN. [Online]
[Cited: FEB 02, 2013.]
http://msdn.microsoft.com/en-us/library/acdd6hb7(v=vs.100).aspx

3. Microsoft.
Values (F#).
MSDN. [Online]
[Cited: FEB 02, 2013.]
http://msdn.microsoft.com/en-us/library/dd233185.aspx

4. Various.
Const-Correctness.
Wikipedia. [Online] JAN 15, 2013.
[Cited: FEB 02, 2013.]
http://en.wikipedia.org/wiki/Const-correctness

©2013 - Shawn Eary
This post and all included code is released under the Free Christian Document License (FCDL)