What? Why? Are you going to endlessly post indecipherable and
incomprehensible snippets and rants on functional programming like those Haskell
types? (Just joking guys – honest.) Well at least I can’t bang on about Monads
as F# does not have them (‘cos the close equivalent are called “Computation
Expressions”)
Continuing on my “meta” travels I started to look at what
was available to the .NET developer in the general field of “numerics”. Linear
Algebra, Regression, Optimization, Time Series Analysis and beyond – hopefully with
a liberal license. There are a lot out there but an interesting subset were
clearly developed in F# - time to clone the odd GitHub repository (and also see
what Nuget could provide as packages) and see if I could make sense of anything.
You might be interested by Microsoft Research’s “Tabular” http://research.microsoft.com/en-us/projects/tabular/
Or Deedle from BlueMountain Capital http://blogs.msdn.com/b/fsharpteam/archive/2013/11/13/announcing-deedle-data-frame-and-time-series-package-for-exploratory-data-programming-with-f-and-c.aspx
Or indeed
Math.NET http://numerics.mathdotnet.com/
Meta Numerics http://metanumerics.codeplex.com/
Of course R.NET http://nugetmusthaves.com/Package/R.NET.Community
to “wrap” the R statistical package https://www.r-project.org/
And lots more…
Please don’t get the impression these are all F# projects
but it does look like F# has a distinct appeal to the people that build them
and those that use them.
You may already have F# as an optional programming language
available within your copy of Visual Studio but VS2015 installed the option “on
the fly” for me after I cloned “Tabular” from GitHub. After that I did a quick
search on my C: drive for fsi.exe (the F# interactive console), located it
among the Microsoft SDKs and then created a desktop shortcut. Once double
clicked, this allowed me to try out some of the tutorial stuff on the web –
just to get familiar with the basics of the language. Yes, in that respect at
least it does feel a bit like Python – but with the comfortable option to
compile code and include it in a C# app. Did I say comfortable? F# is
distinctive – say that for it.
At first glance the variable assignment statements above
look like those of many other languages – the double semi-colons by the way are
a feature of the interactive interpreter as they indicate that a statement is
complete – which is a marker for some of what is to come.
First off, variables are not variables but immutable values
and are thus referred to as values. Well except when they are not (because
sometimes you might need to switch to an imperative style or do stuff like
populate and save data records) and that is when you use the mutable keyword:
> Let mutable x = 8;;
With a special mutable assignment operator:
> X <- 23;;
> x;;
Val it : int = 10 \\the
fsi output
But I am wandering from the point – stick with values are immutable.
Functions are simply defined:
> let addfunction x y = x + y;;
Which defines a function that takes two integers and returns
their integer sum. Did I mention that F# is (very) strongly typed? Probably
not. I did not define any types in the code statements above but F# inferred a
type – that defaults to integer. I could have written
> let addfunction (x : float) (y : float) = x + y;;
But what I could not have done (unlike most languages) is
write
> let addfunction (x : float) ( y : int) = x + y;;
error the type ‘int’ does not match the
type ‘float’
F# does not support implicit casts even safe ones like int
to int64.
> let addfunction (x : float) ( y : int) = x + (float y);;
// works though, with the explicit
cast.
Here is a longer function – our old friend Fibonacci – and no
I have not yet figured out how to memoize it:
let rec fib = function
| 0 -> 0
| 1 -> 1
| n -> fib (n – 1) + fib (n – 2)
| 0 -> 0
| 1 -> 1
| n -> fib (n – 1) + fib (n – 2)
The “rec” keyword indicates the function is recursive
(despite that being obvious) and you can clearly see something similar to a
switch statement and “arrow notation” indicating the values to be returned.
Going back to a
simpler form – say:
let addString x y = (x + y).ToString();;
the ToString() bit looks .NET normal shall we call it but if
you type it into fsi.exe you get the following response:
val addString : x:int -> y:int -> string
and this needs exploring. The implication is that the second
parameter is passed to a function that returns a string and the first integer
parameter is passed to a function that returns an integer. This would (broadly)
be correct as F# functions only take a single argument and only return a single
type. So how is that? F# automatically curries functions. See https://en.wikipedia.org/wiki/Currying
for a quick dip into currying if you have not played with the technique. Then pause
and thing about how that might impact upon a language where functions are not
just first class citizens but rather the whole point.
To quote the Wikipedia article “F# is a strongly typed, multi-paradigm programming language that
encompasses functional, imperative, and object-oriented programming techniques.”
Which maybe understates things a bit as there does not seem much at the cutting
edge of language development left out – and all encapsulated within a
functional programming paradigm.
For the moment I will be content when I have taken on board
enough of the language syntax to be able to follow the relevant math library
code but I will be coming back to try and write something non trivial in F#.
The syntax is superficially daunting but starts to make sense as the underlying
functionality becomes a little clearer. F# feels like it could give you (like Oddball's Sherman) a very
nice “edge” (in some of life's more complex coding challenges).
Addendum:
If you are a user of Visual Studio it is easier to run Fsi.exe withing that environment by pressing <ctrl><alt><f> with an F# project open.. The text is clearer as well.
F# is more that somewhat absorbing - although it does suffer from the "this is the only way" crowd banging on a bit. I can see my next side project might be C# for the UI and F# for all the functionality which would be a neat solution solving some of the issues raised by Python - and hey guess what? F# borrowed the concept of "significant white-space" from that very source (plus a few other bits I think).
If you are a user of Visual Studio it is easier to run Fsi.exe withing that environment by pressing <ctrl><alt><f> with an F# project open.. The text is clearer as well.
F# is more that somewhat absorbing - although it does suffer from the "this is the only way" crowd banging on a bit. I can see my next side project might be C# for the UI and F# for all the functionality which would be a neat solution solving some of the issues raised by Python - and hey guess what? F# borrowed the concept of "significant white-space" from that very source (plus a few other bits I think).