It is such an expressive and clear language to write code in. That is until you start needing to use imperative .NET types :)
I tried porting a small demo program, a few hundred lines, directly from C# to F#. It required only 1/20th of the type annotations. I've written web APIs in F# and many took about half the lines of code.
I particularly like the ease in which I can define local functions to reduce redundancy. In, say, C#, there's so much overhead involved that it's just not worth it.
Going back to F# I've written years ago hasn't been hard either. Since the code is so compact, it's not difficult to figure things out.
F# should be MS's flagship. While F# isn't perfect (could use more inference, traits or typeclasses, and macros), in terms of tooling, ecosystem, language features it come out near the top.
Does F# run on .NET Core yet? Last I checked .NET Core and ASP.NET Core didn't support F#, which is a really big demerit for new projects considering this is the platform Microsoft is pushing for future server side applications (as they should be).
You can check https://github.com/enricosada/fsharp-dotnet-cli-samples/wiki... .
Remember to use last know good version of .NET CLI (see https://github.com/enricosada/fsharp-dotnet-cli-samples/wiki... ), until latest version is fixed
I generally think functional programming is a smart idea, but knock it off with the short, generic function names. We're not writing Fortran on an 80-char terminal any more. Name shit what it is, it's going to auto-complete anyway after you type 3-4 characters, so you might as well give it a name that you won't have to puzzle about later.
var newCustomers = getNewCustomers()
foreach(var newCustomer in newCustomers) {
newCustomer.this .that etc.
}
Depending on the length of the surrounding function, you're better off using "xs" and "x". Or "cs" and "c". I think people trick themselves into thinking that long names somehow provide more context. At a high level, this is correct: modules, exported functions, etc. But for programming "in the small" it's just needless noise.It's not just the hassle of typing long names out; a good editor can help there. It's the visual overhead of having so many extra pixels lit as you read things.
Short functions are good for local functions:
var sb = new StringBuilder()
sb.AppendLine bla
...
sb.AppendLine foo // And another 5 places in the following 10 lines of code.
It's nicer to instead have:
let al = sb.AppendLine
al bla
...This is especially true then the local code pattern is 2, 3, or more lines or when it contains branches.
Both have merits though.
Your brain is excellent at turning words, even long ones, into instantly recognizable shapes. That's why transposing lteters as I'm doign in this sentnce doesn't harm readability very much.
Good, easily-maintained code is not poetry, and it's not math. It's Hemingway: short, terse sentences that say only what they need to say and nothing more. They are self-contained and self-evident.
On a semi-related note, there's a study showing that non-programmers have a much easier time reading code with more white space. To adapt your example above:
var newCustomers = getNewCustomers()
foreach(var newCustomer in newCustomers)
{
newCustomer.this .that etc.
}
It's much easier for your brain to pull out different symbols when there's more white space.fit the length of the functions. Long names might be indicative of some deeper problem with coding style.
function a(b) ... requires reading the whole function definition to understand what it does.
function createNewUser(userInfo) ... tells you exactly what it is and what it does. Especially if you're dealing with pure functions, it makes reading and understanding a code base much faster (and decreases the need for documentation).
I'm a C# developer with almost a decade of experience, and am pretty enamored with F# as well, but like almost everyone else, am stuck using it solely in my own personal time.
However, I'm not certain how much benefit most teams would gain from using F#, after seeing the average (poor) level to which most developers are able to leverage the C# type system to improve the design of their software. Too many developers are forever stuck in a purely imperative paradigm, only knowing how to type one line of code after another, relying exclusively in enums for "extensibility," etc. It seems a bit hopeful to convince the community at large to switch to a language with an improved type system in hope that it will be used to create better software.
But I think somewhere I read that the number of bugs goes up once a function stops fitting on one screen. Or maybe that was Arthur Whitney - J and K seem to do that nicely, and even his C style does so.
Edit: Of course all those other benefits of F# are huge, indeed. But don't underestimate the advantages and pure joy that excellent "programming in the small" provides.
As far as teams being stuck, you're basically saying that mediocre programmers can't handle good things. That's fine, but then the problem is hiring mediocre programmers. I suppose for a lot of basic CRUD/LOB or "enterprisey" stuff, it's important you can take essentially a typist and have them add business rules (like in Wisconsin, if the user is over 50, remove a certain discount). I don't find this type of programming to be particularly interesting though, so who cares what they use?
Is there really much of that stuff going on? I would have thought they would provide some kind of rules engine to the business rather than hard coding masses of it.
Consuming F# code from C# works pretty well for the most part, although F# specific types are cumbersome to use (records, discriminated unions, computational expressions aka monads). This just means that if you want an F# DLL to be usable from C#, you need to think a little bit about the exposed API (perhaps by adding a C# specific wrapper).
Having said that, IMO the interop between the two is better than the interop between JVM languages like java, scala & clojure (Kotlin is probably different).
The F# compiler used to emit "tail." prefixes in every case that was eligible. But not only does the CLR have lots of restrictions, it was slower to request tailcalls.
Maybe that changed in the last version or two.
Edit: OK I found the email where I had asked fsbugs why tailcalls were no longer generated. But that was in 2009 so I'm more out of date than I remember.
In the release notes[1] for the May 2009 release, there's this section:
Optimizations for Tailcalls
On some implementations of the CLI, normal calls can be more efficient than tailcalls. An optimization is now applied to determine if a function is “closed” in the sense that it never takes any tailcalls outside a finite non-recursive callgraph. If so, the use of tailcalls is suppressed.
1: http://blogs.msdn.com/dsyme/archive/2009/05/20/detailed-rele...
That said, it doesn't attempt to read your mind, so the intellisense only kicks in when the type you're interacting with is unambiguous. So, for example, you'll need to explicitly state a function parameter's type before intellisense will help you figure out what methods you can call on it.
You can also do a pure WebAPI module in F#.
It sounds like he's calling the F# functions directly.
http://www.felienne.com/wp-content/themes/zerif-lite/js/smoo...
Also, it's hard to describe exactly what the problem is, but scrolling up and down definitely feels weird and frustrating. For example, a light push that normally goes down a few lines of text on any other page seems to go down a full page. It also seems "stickier", like any scrolling takes a split second to "kick in". As a more contrived example, if I hold two fingers down on the trackpad and scroll up and down in place, any other page will scroll up and down following my fingers, but this page seems to jump around in an inconsistent way.
Something on the page is trying to intercept scroll events and do something smart, but at least on a trackpad on Mac OS in Chrome it makes scrolling feel much worse and less predictable. It looks like Chrome, Firefox, and Safari all behave differently here, with Chrome behaving the worst.
Your users know better than you how fast they intend to scroll. Always.