With the "strong interest" features and type providers, is there any reason left to use F#?
Also, I don't see why array slicing would require CLR support. That would be a welcome addition.
With the "strong interest" features and type providers, is there any reason left to use F#?
Also, I don't see why array slicing would require CLR support. That would be a welcome addition.
But more fundamentally, adding features like these to C# is awesome, but there's no way to remove now-obsolete patterns without breaking legacy code, so it's still possible to shoot yourself in the foot in many ways that you can't in F#.
Some other authors have also addressed this question recently: [1], [2].
[1] http://fsharpforfunandprofit.com/posts/is-your-language-unre... [2] http://blog.ploeh.dk/2015/04/15/c-will-eventually-get-all-f-...
I picked up F# in about 3 months by reading a few books, then refactoring a C# library into F# (this taught me a lot of the interop quirks), and then doing a full project in as much of the F# idiomatic way as possible.
As far as jobs, I don't know anyone who uses the .NET stack that considers themselves strictly an "X" programmer. I've never used VB on a project, but I'd be pretty confident I could consult on a large VB project based on how much C# I've written. Mixed projects are really the best of both worlds anyway, learning F# will improve your C# simply because it teaches you new ways of reasoning about your domain.
If C# 7 ends up implementing Tuples, pattern matching, ADTs, etc... those are all bread-and-butter of F#, might as well learn how to use them ahead of time.
I already improved my C# by reading about F#, there is nothing magical about deconstructible tuples, pattern matching and ADTs that needs too much time to learn. It's the rest of the "succinct" ML syntax that puts me off. That and lack of ReSharper.
When i want move to RoR, they provide asp mvc 3 include EF migration.
When i want move to js, they provide async keyword.
Now when i want move to f#, they provide it all in c# language
Also C#'s statement-oriented nature just makes things ugly. Stuff like:
Bar x;
if (...) {
var a = frob();
x = Foo + a
} else {
x = Baz
}
That's much nicer as a sub-block expression. It also allows you to scope things better. F# allows you to shadow variables, which comes in handy a: to avoid using an "old" variable, b: with nested lambdas.F#'s Active Patterns are pretty damn nifty. F#'s also has deeper support for immutability. Even simple stuff like optional parameters C# gets wrong.
Overall, it's like using vim. There's some big things (like macros) that really help, but a ton of small things really do add up. I find it enjoyable to write in F#, I can be concise and write what I'm thinking. In C# I've got all this extra boilerplate that doesn't benefit me.
There's no doubt that C# can try to close the gap and certainly provide huge improvements from where they are today. But their overall approach seems to get the biggest "bang for buck" while confusing as few of their users as possible. And elegance/consistency be damned[1]. It's not a bad choice for certain projects (I dunno, maybe writing an ERP where you're adding all sorts of boring rules and need to be able to throw interns and get a known-quantity of quality) but it's hardly terrific if you've got control over your developers.
1: Look at C#'s duck typing, or type inference, or lambda expression support - they were forced in for the LINQ use case and nothing more.
I am not following what is bad about the example. Could you reproduce that same code in F# or whatever you're saying is better. It might help explain what you're getting at.
let x =
if ... then
let a = frob()
Foo + a
else Baz
`x` is never in an invalid/uninitialized state, and it's immediately clear exactly what code contributes toward computing its value.Somewhat related, you can also define nested functions in F#, which is very convenient and tidy. No need for a pile of one-off private helpers at the same syntactic level as your public APIs - just tuck them inside the members which need them.
var x = ...
? Foo + frob()
: Baz;
Or to be truer to the original (using my lib): var x = ...
? map(frob(), a => Foo + a)
: Baz;
But the idioms of the language mean that in the real world you see the ugly version with the associated risks of uninitialised variables. I applaud the C# team for the direction they're taking. I suspect C# will end up closer to Scala than it will to F#, which isn't a bad niche for it to be.