
Why Use F#? - adgasf
https://fsharpforfunandprofit.com/why-use-fsharp/
======
Barrin92
In my opinion it's honestly the best statically typed general purpose
programming language.

f# and also Ocaml strike for me the right balance between practicality and
correctness (strict by default, no insistence on purity), but still immutable,
good concurrency story, functional first with the ability to write imperative
code easily, great type inference etc..

Given that so many mainstream languages are piece by piece moving into the
same direction and adopting the ML family approaches I have no idea why not
more people are moving directly to F# or Ocaml.

~~~
delhanty
I'm looking at Ocaml again because of the existence (and quality) of the
Bucklescript backend for Javscript.

That makes Ocaml sound pretty attractive on the portability front.

A question for anybody here regarding portability: Is it viable to maintain a
portable core using a subset of Ocaml (something like Standard ML maybe - no
objects) and compile that in F# using Ocaml portability mode?

For context, I've read this question on SO from 2010 [0] but I'm looking for
some more 2018 perspectives from HN people.

[0] [https://stackoverflow.com/questions/4239121/code-
compatibili...](https://stackoverflow.com/questions/4239121/code-
compatibility-between-ocaml-and-f)

~~~
yawaramin
That answer hasn't changed, in fact as of today OCaml and F# have diverged
more than they had back then.

BuckleScript and ReasonML are solid for the frontend, though. I would
recommend them without hesitation. For the backend, F# could be nice but as I
mentioned, you would share almost nothing between them. If you're looking for
a universal (i.e. same language on BE/FE) stack there are many options today,
but a classic one is [https://ocsigen.org/eliom/](https://ocsigen.org/eliom/)

~~~
kbd
> but a classic one is
> [https://ocsigen.org/eliom/](https://ocsigen.org/eliom/)

I didn't know there were any other attempts at a "universal" platform since
Meteor. Thanks for sharing! Please let me know if there are others that you
think are worth learning.

~~~
yawaramin
Sure :-) Another one I admire is [http://opalang.org/](http://opalang.org/) .
It too is based on OCaml, funnily enough. The last commit is from last year,
though, so this is not a project on the rise.

Here's one for Scala (and Scala.js): [https://udash.io/](https://udash.io/) .
It has a lot of cool concepts, like out-of-the-box push notification support
with WebSockets. And I am more familiar with Scala than anything else so it is
attractive. The only thing that gives me pause is that I've used Scala.js in
the past, and its compile times are not something I want to deal with again
after using faster transpilers like BuckleScript.

Finally, the one I'm keeping my eye on is
[https://dockyard.com/blog/2018/12/12/phoenix-liveview-
intera...](https://dockyard.com/blog/2018/12/12/phoenix-liveview-interactive-
real-time-apps-no-need-to-write-javascript) . The idea here is to serve static
HTML with a minimal bit of JavaScript needed to maintain a live connection to
the server, over a WebSocket, and drive dynamism that way. Think React+Redux,
but driven from the server side. The client can be mostly a dumb client again.
This one has a promising future, with lots of optimizations and benefits
falling out of using the Erlang runtime properly.

------
lihaoyi
Having used and enjoyed F#, I ended up programming in Scala which is almost
the same language, despite the huge superficial differences:

\- Indentation delimited blocks vs curlies

\- CLR vs JVM

\- Whitespace vs Parenthesis for function calls

\- Currying by default vs currying optional

Despite all this, when you actually start coding, it's remarkably the same:

\- Immutability by default, transformations rather than mutation

\- Less classes with embedded implementation logic, more "dumb" records with
external functions

\- Structural pattern matching

\- Tagged unions

\- Type inference

\- Convenient definition of record/struct-like data types with free copy-
constructor

\- Operator overloading

\- Easy FFI to external libraries in a different paradigm

\- Easy "dropping down" to mutable, imperative code (e.g. for performance, or
interop)

\- Both have lots of syntactic and semantic warts and corner cases, though few
enough you can live with them

\- Garbage collected, multithreaded, JITed runtime

\- Both compile to Javascript

While every single feature looks totally different on the surface, starting
with a totally different syntax, the two languages are more the same than
different. If you look at the tutorials linked from that page, all of them can
be translated almost line-for-line from F# to Scala (and vice versa: take any
random Scala tutorial, and you can trivially translate it line-for-line into
F#)

Scala brings with it a bigger ecosystem, both in Scala and from the JVM, and
better tooling support in general (Both Scala-specific, as well as general JVM
tooling which all works with Scala: profilers, debuggers, package managers,
...), and slightly more seamless platform interop (Scala <-> JVM is less
jarring than F# <-> C#), which is why I ended up sticking around.

~~~
soulnothing
I can echo this. I'm working in F# in my day to day. While I like the
language. I find the tooling IDE and other essentials are missing. I spent
several weeks fighting swagger generation client and server tools. Something
that just worked on the jvm.

I bounce between Scala and Kotlin. But as a Linux dev I find the JVM far more
forgiving.

~~~
bonesss
Re F# tooling and IDEs: sadly the churn around the transition to .Net Core has
really hurt F#s tools. Things that were stable and working since inception,
and enabled highly productive workflows, have been trampled by missing
features and shifting boundaries on the new platform.

That said: it seems it's finally coming around, as .Net Core matures and gets
more mature secondary tooling, a lot of the little blocking issues can finally
be addressed.

------
AdeptusAquinas
Because if you are a top-notch C# dev, F# is just like you normally code but
with less brackets and null reference exceptions.

Also, you haven't experienced implicit typing until you have used F#'s
ridiculously powerful approach to it (relative to C# anyway).

~~~
bunderbunder
I'd argue that that's painting with too broad a brush. C# has picked up a lot
of features to support functional programming, and has made great strides in
reducing boilerplate and clutter, but there are still all sorts of things that
F# has and C# either lacks, or requires a lot more verbosity to accomplish the
same thing.

Pattern matching, for starters. It's not just chained if-statements on
steroids; F#'s decision to make partial matching emit a compiler error is a
real sea change in terms of the level of compiler support you get in guarding
against unintended consequences in an evolving codebase.

Type providers. They let you interact with external data sources with about
the level of ceremony you get in a dynamic language, but are still statically
typed. The SQL type provider is particularly impressive. Not only does it
generate your DTOs for you without ceremony, even when you `SELECT *`, even
when the schema changes, but, if you make a mistake in an inline SQL query,
you'll get red squigglies under exactly the spot in the string where the error
is, just like if it had been a syntax error in the F# or C# code.

Computation expressions. F#'s equivalent of Haskell's do notation. C#
accomplishes similar levels of purpose-specific expressivity in some specific
areas - LINQ, async/await, etc - by adding syntactic sugar to the compiler,
which means only the C# compiler team gets to do it. Computation expressions
let you roll your own.

Currying and partial application. You can achieve the same result in C# with
higher order programming, but it gets messy quickly. Also, there's an argument
to be made that, similar to how objects are heavyweight closures, dependency
injection is heavyweight currying.

~~~
mattferderer
Do you have thoughts on C# 8's increased pattern matching features?

~~~
bunderbunder
I haven't actually used C#, or any .NET language, since before 7 came out.
Based on what I've seen as a sideline observer, though, it looks to me like
C#'s pattern matching and destructuring are just syntacitc sugar, and
therefore still significantly weaker than what F# has. I don't think you can
get to the level of type safety that F#'s pattern matching provides without
F#-style algebraic data types.

The reason is that a set of algebraic types in F# is effectively bundle of
types that are collectively sealed. In C#, you can really only seal the
terminal classes in a cluster of types, which means that anyone else can come
along and add a new class to the type at a later date, after the initial
module is compiled, possibly even at run time. That undercuts your ability to
ensure that a branching statement is airtight.

I believe C# also still lacks active patterns, which are a pretty killer
feature if you're looking to do data-oriented programming.

~~~
victorNicollet
C# now has active patterns (which feel like the `is` pattern matching) in the
ability to declare a variable as you pass it as an out parameter to an
extension function, e.g.

    
    
        if (num.IsNotPrime(out var a, out var b))
            WriteLine($"{num} = {a} × {b}");

------
knocte
I love F# and there's only one thing lacking in its ecosystem: not many
opensource projects written in it. And I don't mean libraries, tools &
frameworks, there are tons of those; I mean a real app.

But I hope I can break the trend myself:
[http://github.com/knocte/gwallet](http://github.com/knocte/gwallet) . If you
want to learn F# by contributing to a real opensource project, you have a
chance now.

~~~
AdeptusAquinas
I built a 2D platformer in it:
[https://github.com/ChrisPritchard/MiniKnight](https://github.com/ChrisPritchard/MiniKnight)

Also uses MonoGame, and its all running on dotnet core. Reasonably sizable,
though still more of an exercise than production quality.

~~~
knocte
Nice! I wonder if you could remove the dependency on System.Drawing by using
SkiaSharp?

~~~
AdeptusAquinas
I probably don't need to use bitmaps as maps at all, really; Text files would
work just as well. But using System.Drawing cross platform in .net core was an
education in itself, so I think worth it :)

------
kyleperik
Can someone please explain to me how you can use F# without each aspect of the
development process being a Microsoft technology?

Not to be rude, I just honestly want to know. There is quite a bit of hype
around C#, F#. But every time there is a comparison to other languages it
seems to skip over the fact that you much have a windows computer running
Visual Studio which is a big disadvantage to some people. Quite honestly, they
are great languages. I just don't want to buy in completely to Microsoft

~~~
nikofeyn
is it microsoft or windows you are against? basically all of the f# toolchain
is open source, and it runs perfectly fine on all three major os platforms
using either .net framework (windows), .net core (cross-platform), or mono
(cross-platform). most people either develop f# in visual studio or using
visual studio code. same goes with c#.

.net core, which is intended to be fully cross-platform is the future of .net.

~~~
kyleperik
I understand there exists .net core and mono. I'll give them mono. My problem
is I haven't seen a single example of a practical application written in .net
core or a company that uses it, everything is .net framework. There just
aren't many available alternatives to the frameworks and packages that are
those who use .net framework take for granted. I hear what they're saying
about it's the future, but I have yet to see the fruit of it.

To me .net core seems more like just a buzz word to prove that they like open
source and anyone can use their software. But there isn't any way to monitize
it so there isn't any reason for them to focus on it.

~~~
atombender
The last time I brought this up on HN, I received a comment [1] from one of
the people who work on F# at Microsoft:

    
    
      F# is fundamentally a .NET language ... It's impossible to divorce 
      the two, even if the target runtime environment is not necessary a
      .NET runtime. Those other environments inherent language design
      decisions made with .NET as a target runtime. The .NET runtime
      with .NET Core is indeed minimal, is natively supported just about
      everywhere, and was built with cross-platform in mind. F# is a
      part of this, for better or worse.
    

I like F# a lot, and to me it comes across as something of a cleaner, more
modern OCaml. I have zero interest in .NET and its toolchain, and I don't want
the baggage of its runtime or VM.

[1]
[https://news.ycombinator.com/item?id=17936732](https://news.ycombinator.com/item?id=17936732)

~~~
kazinator
It strikes me as nonsense. Let's take the paragraph and replace "F#" with "C",
".NET" with "PDP-11", and "Core" with "V6 Unix".

Come on, surely you can make a non-.NET dialect of F#. Sure, not every .NET F#
program will be portable to it. There must be some considerable abstraction in
F# that isn't tied to .NET.

~~~
piaste
[https://fable.io/repl/](https://fable.io/repl/)

This is a F# -> Javascript compiler and environment, itself running in your
browser (in Javascript, obviously).

[https://github.com/kjnilsson/fez](https://github.com/kjnilsson/fez)

This is a project running F# on BEAM (Erlang).

So yes, of course you _can_ write a compiler from F# to whatever platform you
choose. It's just a really major effort, in no small part because F# is a way,
_way_ higher-level language than C (you'll remember 'worse is better' \- a big
deal with C is that it's easy to write a compiler for).

~~~
kazinator
> _a big deal with C is that it 's easy to write a compiler for_

We are still feverishly at it in 2018 and there is no end in sight.

> _It 's just a really major effort_

That is neither here nor there.

------
s369610
Didn't see a mention of the fact it can compile to and interop with JS via
Fable [https://fable.io/](https://fable.io/) which is pretty handy

------
projectramo
Okay, I have heard many good things about F# so I’ll give the (probably) kind
people who work there two tips on how to get more people interested.

1\. Release an easy to use web framework that deploys easily. (Rails clone)

2\. Release an IDE which can graph from the command line (R studio or Spyder
clone)

If you already have these (say a subset of .Net or visual studio / vscode)
then the tutorials are misleading because they don’t seem the same.

~~~
kirse
Best web frameworks:

[https://github.com/giraffe-fsharp/Giraffe](https://github.com/giraffe-
fsharp/Giraffe) <\- thin layer on top of ASP.NET Core

[https://safe-stack.github.io/docs/intro/](https://safe-
stack.github.io/docs/intro/) <\- slightly more opinionated but also .NET Core
based.

I tend to mix F# and C#, Giraffe is great for sticking a slim web API or
interface in front of .NET Core applications that use a combination of F# and
C#.

~~~
sparkie
Another suggestion would be websharper.

I'm not a web developer, but I have found it extremely simple to write some
basic web apps using this.

------
DanielBMarkham
Big F# fan here.

After going through a dozen languages, and listening in/reading scads of
debates on languages, I think the author here misses the point.

Don't get me wrong: the points he makes are valid, and they make for a great
language. Where I think the problem is when discussing languages is that
_languages are an ecosystem_. They're groups of people, tools, message boards,
IDEs, meetups, and so forth.

F# is great on the things he mentions, but the real strength is the way F# can
take a bunch of dotnet guys and slowly move them towards pure functional
programming without there having to be a huge learning curve. Like C#? Like
your objects and classes? Fine. Do that. Like you FooBar .NET libary? We've
got that too.

From your favorite IDE to the places you hang out, it's all the same. Just now
with functional programming.

F#, in my mind, is first and foremost a _training language_ , and I don't mean
that in a bad way. It exists in an ecosystem where it naturally helps a bunch
of devs learn new stuff. (As opposed to most languages that do some core
things, then keep adding crap on top year-after-year)

Which brings me to my only criticism of the language: we're growing a
community of wannabe Haskell/Erlang guys who are frustrated doing hook-the-
wire-up C# in their day jobs. That can lead to language elitism and
frustration on everybody's part. I'm not sure how to solve that. It's probably
a good thing to have devs interested in upping their game. I think that if you
want to move on to a more pristine language, you probably should do that.
Understanding F# as an intermediate/training language for those interested in
programming in general is a good way to keep needed context. If you expect it
to be something that it's not, it's going to lead to frustration.

~~~
sparkie
Maybe Microsoft don't put the effort into the F# ecosystem because it's like
the gateway drug to other platforms, which aren't Microsoft. I ended up moving
to Haskell after learning F#. I've since moved back to using F# as my primary
language, as I'm a recovered type addict, but it does sometimes feel
restrictive in its capabilities.

~~~
DanielBMarkham
My mission is to help devs, so F# is the best spot for me right now. Having
said that, I'm quite interested in the theory, so I'll probably be playing
around with Category Theory and Haskell over the next few years.

My biggest technical frustration with F# is just what you pointed out: they
started down the OCAML route, then pulled back immediately after somebody
figured out it would lead devs away from MS. Now all I hear about is how F#
will integrate better into existing MS stuff and complaints about how the C#
guys are copying F# stuff (and badly). None of that I'm interested in. None of
that helps devs.

And I believe your and my observation are related: the more MS tries to keep
F# in the fold, the more tension it's going to build between devs who want to
branch out and those who don't.

~~~
akra
The way to combat that IMO is to continue to innovate the language improving
both the language and the context it runs in (tooling, ecosystem, etc) making
it easier to use, more robust, minimize the costs/benefits of changing, etc.
Having a great working functional language with access to a large ecosystem
and decent tooling makes adoption easier and less risky. There's more to a
language choice than features; it has to work for the dev's, the organization
and it has to scale to the "good but not passionate" developer.

------
buybackoff
I used to love F# before .NET Core, but then it was broken for two years for
any sane design time experience on Core. I even wrote some rant about it with
specific concerns I had ([http://hotforknowledge.com/2016/10/19/4-functional-
for-thoug...](http://hotforknowledge.com/2016/10/19/4-functional-for-thought-
imperative-for-hacking/)).

Two years later.. and very recently the .NET Core story started to work well,
tooling improved to quite workable state, and in combination with C# it's very
strong mix of practicality/performance + complex flexible abstractions and
correctness.

Over that time F# has added quite a lot of low-level performance features (on
par with C# - Span/Memory<T>, ref structs, struct tuples/unions, voidPtr, etc)
and they _just work_. Build time is probably the main concern now, I have to
disable building F# projects when they are in a solution but not touched
because even on i7-8700/16GB it's very noticeable.

Two weeks ago I needed text parser and picked familiar FParsec. It's one of
the fastest one in .NET (including C# ones) and is a mix of C# for low-level
stuff and F# for powerful abstractions. I refactored it quite substantially
and tooling was finally nice. But my attempts to micro-optimize it yielded
only in substantially reduced GC due to the support of value structs and
Span<T>, throughput was already quite optimal from .NET perspective (only
c.<5% gain probably due to GC), so if used with care F# could be as fast as C#
(which BTW is native-like fast when also used with care).

I believe such mix is the winning combination: C# is best for low-level high
performance stuff, F# is best for complex things such as recursive data
structures, analytics and so one.

My big concern is that F# community is great but often F#-only focused, e.g.
reinventing existing C# libraries just because it's not F#. This isolationism
from .NET as a uniform platform led for example to things such as F#'s `async`
is better than Task Parallel Library (C#'s async/await machinery) in
theory/design, but TPL is so much superior is usability, performance and deep
platform integration but F# cannot use it directly. Without native TPL
`task{}` F# is not a fully-featured .NET Core citizen but a niche language for
specific tasks where it shines, e.g. to write a AST parser for a new query
language. Sad that MSFT invests so little in F#, but the language is
definitely is alive, is improving and is worth using.

~~~
verinus
As I understand it, F#'s async funktionality was there first, and C# TPL was
modeled after it, but I might be mistaken...

Anyhow I am with you that this is one of the problems I have with F#. Interop
from F# to C# is generally pretty bad.

~~~
buybackoff
Yes, F# was the first with async. Interop with C# is native, all code is
compiled to IL and JIT-ed together. Problem with TPL is that it is supported
by Roslyn at the language level. The C# compiler rewrites async/await into
very efficient state machine. F# cannot natively integrate into that state
machine and a long async call chain is always broken on C#/F# boundary, while
in C# async-only code could be compiled in a big state machine and with
ValueTask (and even better IValueTaskSource that is used in Streams and
Sockets in dotnet core 2.1+) a long running while(true) {await... } loop could
be allications-free. Add to this upcoming in C# 8 AsyncStreams and importance
of this increases. F# allocates a lot on every boundary and basically cannot
be a part of a high preformance async data processing pipeline where GC
latency pauses are important. Throughput is also lower. There is a way to hook
into the state machine manually, but it's still less efficient, cumbersome and
unmaintainable. Been there - done that.

~~~
verinus
Ofc everythink is IL but working with Options in C# is not fun at all... same
with F# async and C#...not belding well into each other- some things I meant
when saying that interop is not good imho.

I am with you in thinking, that there should be only one mechanism and that
C#s async is superior...

------
seanmcdirmid
Someone who worked on F# once told me that one reason F#'s uptake was limited
was because C# was so good at stealing its best features.

~~~
btschaegg
> …because C# was so good at stealing its best features.

Let's agree on "replicating some of its great features". If you look at what
C# makes of them, more often than not, it's a hack. Maybe one that's better
than what C# had beforehand, but a hack nonetheless.

Example:

`async` in F# is not only amazing because of async IO, but its integration is
really elegant, too: `async` is basically just a computation expression (if
you used haskell: read "do notation"). C# OTOH built in a whole new class of
functions that's hardcoded into the language (the same techniques also
differentiate C#'s iterator blocks vs. F#'s `seq`).

Another example:

F# has pattern matching, which is tremendously useful because it is exhaustive
(there are squigglies if you forget a case). C# 8 introduces switch
expressions that aren't, but will throw an exception at runtime instead (i.e.:
the detection code is there anyway[1], it's just used the wrong way).

[1]: AFAIK, the autogenerated `default:` IL code is omitted if the compiler
can prove that it will never be called. Someone mentions that in the latest
"What's new in C#8" videos.

~~~
kod
Isn't async in f# considerably less efficient than in c#?

~~~
dgudkov
They have different design goals. Async in F# works better for F#
applications. Tomas Petricek wrote a couple good articles [1][2] comparing
both approaches to async computations.

[1] [http://tomasp.net/blog/csharp-fsharp-async-
intro.aspx/](http://tomasp.net/blog/csharp-fsharp-async-intro.aspx/)

[2] [http://tomasp.net/blog/csharp-async-
gotchas.aspx/](http://tomasp.net/blog/csharp-async-gotchas.aspx/)

------
jchendy
> // no curly braces, semicolons or parentheses

Is this a good thing? It feels like saying "It's English without the periods
or line breaks or capital letters."

~~~
BeetleB
It is because those things are simply not _needed_ to parse or understand the
code.

Everyone indents anyway. So why need braces?

Most people write one statement per line. Who needs semicolons. I've often
called it the most useless character in programming language history. Whenever
I switch from a language that doesn't use them to one that needs them, it's a
horrible transition. I have to mentally remember to add this character at the
end of most lines.

Parentheses for function calls - in some contexts they are helpful. In most,
though, they are not needed. Wherever they are needed, you will have them in
F#. For people who went from Python 2 to Python 3, you'll know the pain of
suddenly needing parentheses for print statements, and for most of those
people, you will not see any benefit to adding those parentheses. Extend that
to other functions.

~~~
maxxxxx
"Everyone indents anyway. So why need braces?"

I don't indent. I let the editor do it based on braces.

~~~
BeetleB
Fair enough. I save on keystrokes by not inserting braces. I do have to
manually indent once in a while, but the editor will usually figure out what I
mean.

As an example, in a for loop in Python, I need to press a single key for
indenting[1]. In a language like C, it would be 4 keystrokes - 2 for each
brace. Come to think of it, this is true for if conditions, functions, etc.
Pretty much all places you'd need braces in C. I'm having trouble figuring out
where in regular programming in Python a braces would mean less work for the
programmer.

Indenting is simply less work than inserting braces.

[1]Strictly speaking, for dedenting when I'm done with the for loop.

~~~
maxxxxx
All you are saying is personal taste and familiarity. Nothing wrong with that
but I could argue every one of your points exactly the other way and would be
as right as you are.

In the end you get used to almost everything.

------
smt88
I've read on HN that F# doesn't get nearly as much attention and support from
Microsoft as C# does, to the point where people expressed concern that F#
might be put into maintenance mode.

Does anyone reading this feel that way, or was it just FUD?

~~~
lenkite
F# support always lags behind by a couple of years. Only very recently (as of
last week) you could release F# UWP apps.
[https://github.com/dotnet/corert/issues/6055](https://github.com/dotnet/corert/issues/6055)

~~~
pjmlp
Which still isn't production ready it seems.

"One thing I noticed is that the compiler only crashes when building x86. It
compiles fine for x64."

"Are we stuck on "Allowed but not officially supported" for now or are there
any plans towards "Officially supported" ?"

------
ssijak
How does F# compare to Haskell? I wan`t to put one staticaly typed functional
language under my belt and I do like what I read about F# but I do not like
it`s windows/microsoft ecosystem. I`ll probably go with Haskell.

~~~
sparkie
F# is not strictly tied to Windows, it also works fine on Android, iOS &
Linux, and is completely open source. It was open source well before the rest
of the .NET ecosystem. Community contributions are larger than Microsoft's
own. Haskell has very limited mobile support.

In terms of language. F# is easier to learn and more practical to use for
everyday programming. Haskell is more of an academic language, and takes a
high level of expertise to utilize for real world development.

Haskell is a purely functional language which makes great effort to eliminate
side-effects altogether. F# on the other hand, is merely functional-first, but
allows side effects by explicitly marking things as mutable, or by utilizing
existing .NET libraries which have side-effects.

------
dzonga
Been learning F# the last two months. Wanted to learn Ocaml first. But F# is
the sweet spot, beautiful functional syntax . Can leverage the now open .Net
Ecosystem + pretty fast for doing financial stuff that I wanna do.

------
Nelkins
My startup, [https://masse.app](https://masse.app) has it's entire backend
running on F# + .NET Core + AWS (Lambda and Fargate). Works great!

------
Solar19
I've wanted to learn F#. I'm particularly curious about parsing and text
processing, and wonder whether the pattern matching feature would work well
for that.

It would be great to see an HTML minifier in F#. I've thought about building
one as a way of learning the language. An F# based static site generator,
similar to Jekyll or Hugo, would also be neat.

Compilation of F# is a confusing story to me. If it's still compiling to an
IR, and getting JITted at runtime, that seems kind of inefficient in a world
where Go exists. There's the CoreRT project, I think, that allows for
precompiled .NET applications, but I'm not sure how F# fits in. I also read
that all Windows Store/UWP applications are precompiled on Microsoft's cloud.
I'm curious about compile-time flags and optimizations for F#, but they're
rarely mentioned.

~~~
AdeptusAquinas
For text processing in F# there is a library called FParsec, which is really
powerful: [http://www.quanttec.com/fparsec/](http://www.quanttec.com/fparsec/)

Regarding JIT and Go, I've built identical programs in both and while Go is
faster, its not by as much as you would think (in my example, 60ms vs 40ms).
Go is much more verbose to write, but its output exe is all by itself without
the hundreds of dlls .NET likes to lug around.

F# works with CoreRT just fine, with some small caveats (its sprintf/printfn
functions don't work I think). I've modded one of my games to use it:
[https://github.com/ChrisPritchard/Tetris](https://github.com/ChrisPritchard/Tetris)

------
insulanian
My favourite F# features:

\- Single-case discriminated unions. I feel so unprotected when working in C#
due to IDs usually being primitive types. You're never sure if you'll
accidentally flip two `int` parameters in a method call.

\- Automatic currying and partial application in combination with piping `|>`.
Enables so intuitive and elegant code flow.

Performance characteristics are decent as well[1].

[1] [https://benchmarksgame-
team.pages.debian.net/benchmarksgame/...](https://benchmarksgame-
team.pages.debian.net/benchmarksgame/faster/fsharp.html)

------
galkk
I love F#, but it seems like the language is either abandoned or on life
support by Microsoft - compare the feature development speed of C# and
Typescript against F# and you'll see that.

~~~
bonesss
C# is still rushing to get features that F# has had for years, with no hope on
some major fronts. If F# were innovating that much it would indicate that F#
was sorely lacking at launch, but it wasn't.

F# is based on a much more mature langauge, with mature concepts for handling
the secondary and tertiary effects of those features currently coming into C#
and Typescript. By adopting that mature language, F# started out "right" and
hasn't needed much to fix it.

And in terms of work: checkout the templates for F#, the libs for F#, and the
thoudands of examples on MSDN in F#... But more specifically, check the amount
of low-level improvements, refinements, and user-friendly sugar the team has
landed in years of late. There's constant improvement, but of a less
"revolutionary" nature as the base design was so mature.

People confuse new shiny toys in IDEs with fundamental support. That's not
necesarily the important thing... The convergance of functional languages and
cloud native development is, in many cases, the important thing to MS, and is
another area where F#s tooling/ecosystem is years ahead of the C# equivalents.

------
keithnz
I played around a lot with F#, and I really like it, but I got to this
question of why use F#, and it is actually really hard to come up with a good
answer to it, mainly because C# is really good and the real question in .NET
is why use F# over C#. If you program with the same mindset of F# in C# then
the differences are not super quantifiable.

In general terms F# as a language is nicer than C#, but my real question is it
good enough that you'd want to covert to it if you are mainly a group of C#
programmers, and I reached the conclusion that it's probablly not simply
becaus C#, in general, is not really that horrible to start with and a lot
more people do things in C# and everything in the .NET world is looked at
through the lens of C#. I asked a similar question on the F# communities
slack, and beyond a few language features ( that are nice! comprehensions and
discriminated unions, and more concise syntax with implicit typing ) it's
really hard to find a reason. Part of the problem is there is very little in
terms of libraries that are unique for F# that massively jump start you in any
particular direction. What's more, quite a lot of F# code that fits in with
frameworks that were built in C# often just look like C# written in F#. F#
code written with F# oriented libraries are really nice and super concise, but
it's a bit of a lonely world.

~~~
knocte
> If you program with the same mindset of F# in C# then the differences are
> not super quantifiable.

I think they are. F# defaults to immutable stuff. Everytime you write anything
in C# and forget the word "readonly", you're opening the door for a race
condition. Also F# is much more succinct, things that take dozens of lines in
C# are just one line in F#, take a look at this quick guide I wrote:
[https://github.com/knocte/csharp2fsharp](https://github.com/knocte/csharp2fsharp)

~~~
keithnz
While those are nice things, they don't really bite me in the C# world.
There's a lot of fuss about it in the F# world, but it really isn't that big
of a problem in my experience. I do like the robustness of it, but in
practical terms... it's only a minor point in F#s favor

~~~
knocte
I guess you say this because you don't really do multi-threading that much or
haven't had the urge about parallelising your work yet ;)

~~~
sk5t
C# with the good old .NET BCL has excellent support for multithreading, even
if some language features could make it even better, there's no need for
smugness.

~~~
knocte
I didn't say that C# doesn't have support for multithreading, I said that
C#+multithreading is more prone to race-conditions than F#+multithreading.

~~~
sparkie
I wish MS had continued support for their "Axum" project, or at least open-
sourced it so that it could be continued outside of MS.

It was essentially a C# subset with "static" removed and replaced with
"isolated", with some other new stuff added. Code was separated into domains
and actors, which could be safely used without the concerns on race
conditions. Essentially erlang-like programming on .NET

~~~
knocte
Interesting.

------
dkrikun
Seems like a decent alternative to C# on dotnet. Its a pity it feels second-
class.

------
Koshkin
The curly brackets is not “coding noise.”

~~~
verinus
I think otherwise. Curly braces and semicolons do not serve a purpose.

My only beef with F# is multi line expessions...indentation is sometimes
weird.

~~~
kkarakk
curly braces enable code readability, you know where to start reading and you
know where to stop reading. the situation is the same with the semicolon.

programming languages are written to be read by humans and humans do better
with start and stop points. if i've ever blearily looked at code at 3 in the
morning,i basically run on autopilot relying on the braces and the semicolons
to guide my eyes

~~~
sparkie
If you use VS or Monodevelop, there's are options you can enable which show
indentation margins, which is even better than braces. Seems like a non-issue.

~~~
Koshkin
Basically, you are discussing an attempt to move away from the purely textual,
linear representation of program code (at least, in the way the programmer
sees it). Yes, sophisticated tooling becomes very important then. But it is
not always available.

~~~
sparkie
I wouldn't say it's really sophisticated tooling. Many basic editors support
visual whitespace in one form or another. Some insert a semi-opaque character
in place of tabs/spaces, and others show rulers.

F# is whitespace sensitive, so you need to stick to correct tab sizes anyway,
and it becomes quite readable.

For types, you can also add `class`, `interface`, `struct` at the start and
`end` on the correct indentation after its definition to show a clear
boundary.

    
    
        type X() = class
    
            member this.X =
                ...
    
        end

------
ainar-g
They show the “type-safe printf” example there, but they don't seem to explain
anywhere, if I can write my own type-safe variadic function or not. Is printf
a built-in that is built with magic not allowed for mere mortals or do they
just not dive into the topic because it's complex? Can any F# affectionados
elaborate?

Also, they only talk about units of measurement in the context of floats. Can
I not have integers or rationals with units?

------
pjmlp
Lack of support in all targets that require .NET Native, no love from the
teams that do .NET graphical tooling, a couple of high figures on the
community that love to bash C# and VB.NET and the company that makes it
possible that F# exists to start with, is what puts me off to invest more time
into F#.

It is one of the best ML derived languages, but as it is, I rather wait for C#
and VB.NET to keep getting features from F#.

~~~
gaterelic
> a couple of high figures on the community that love to bash C# and VB.NET
> and the company that makes it possible that F# exists to start with

I stopped learning F# myself for this reason in particular. I really enjoy the
language but I just cannot stomach the F# community. The .NET community is
small enough as it is, and F# is a fraction of a percent of that, but they are
extremely vocal others and bully others for what seems like no other purpose
than to gain personal popularity and sell books. If this community went away I
think the language would do much better, or maybe there would be room for
another functional language on .NET that could start fresh without a history
of pain. The entire situation is simply sad.

------
staticassertion
If I want to learn F# is there a good IRC/slack channel I can get on? I'd like
recommendations for libraries. I have a project I could throw at it for fun/
learning.

P.S.

Can someone explain this?

    
    
        // complex types in a few 
        type Employee = 
          | Worker of Person
          | Manager of Employee list

~~~
platz

        abstract class Employee {}
        class Worker : Employee { 
          public Worker(Person o) {...}
        }
        class Manager : Employee { 
          public Manager(Employee[] o) {...}
        }

~~~
sparkie

        abstract sealed class Employee {
    
            enum TAG { Worker, Manager }
            
            readonly TAG tag;
    
            Employee(TAG t) {
                tag = t;
            }
    
            public class Worker : Employee {
                public Worker(Person p) : base(TAG.Worker) { ... }
            }
    
            public class Manager : Employee {
                public Manager(Employee[] o) : base(TAG.Manager) { ... }
            }
        }
    

This is a bit closer to how it is really implemented. The constructors are
internal to the outer type because it is sealed, making it a closed type.
Interestingly C# rejects abstract & sealed on the same type, although this is
accepted on the CLR.

Discriminated unions are sometimes called tagged unions because of the way
they're implemented. It's typically more efficient to check the tag on the
object than it is to test its type. The tag is used when pattern matching over
the object.

~~~
platz
Ok, the idea was to communicate to someone who has never seen an ADT before
what kind of thing it is, rather than a full decompilation of how it's really
implemented, but thanks for that too.

------
month13
Wow, and I was just looking at mixing this in with a API C# dotnet core app I
was playing with.

Wish it was easier to mix the two, it's pretty nice being able directly
interface through dotnet, be even better if I could have fs and cs files next
to each other.

~~~
sparkie
One thing about F# is that the ordering of compilation units is essential. You
need to list your files in the order they are to be compiled because you
cannot have circular dependencies between the units. This leads to making
better decisions about code most of the time.

It is still possible to have circular dependencies. Either by including the
mutually related types in the same code file separated by the "and" keyword,
or by using signature files to define the type signatures ahead of their
implementation (which work similar to header/implementation files in C, C++
etc).

------
hexo
and yet they impose nonsensical CamelCase on us where unsuitable as always,
for example - this.IsEven... i'd say IsEven is a type, buuuuuuuuuuuuuuuuut,
how can I know here in F#?

~~~
oblio
That's PascalCase :)

------
verinus
imho one of the best sites for learning a programming language if you already
know how to program.

My biggest problem with F# is the bad tooling. For professional coding you
need tools like static analysis, refactoring and so on.

with those you can use the knowledge of other to improve your code.

R# did a lot for C# in that regard.

------
rusabd
Does anyone know specific teams in Microsoft which are mostly F#? I might
start to target them :)

------
Paraesthetic
I like f# because most of the notes in the scale are black keys, so don't have
to move my hands very much to play the whole scale... Of course I know what
you're talking about.

------
Jenz
I'm impressed :o

------
gambiting
"F# is not cluttered up with coding “noise” such as curly brackets, semicolons
and so on.

You almost never have to specify the type of an object, thanks to a powerful
type inference system."

As a C++ programmer, both of those sentences make me shudder. Lack of
specified types reduces readability by an order of magnitude, at least for me
personally, and especially with complex projects I end up spending a lot of
time trying to guess "what is the compiler going to assume this object
is"(looking at you, "auto" nonsense in C++)

~~~
jcelerier
I have seen a lot of people say something like you did, and after one month
working in a mostly-always-auto project they can't ever go back to writing
types that your compiler knows perfectly well. 99% percent of the time it is
the interface that matters, and for the 1% remaining, sure, write your type.

~~~
stinos
This, I think. Whenever I see heavy anti-auto statements I can't help but
wonder whether the author actually ever used auto (or var, or dynamically
typed languages) for a while and not just read about it and thought 'wow this
is radically different from what I do so it must be bad' (note: been there,
done that). I mean sure everybody can have their opinion, but if you have
millions using languages without bothering about types and you have the C++
gurus telling you to almost always auto then surely some bells should start
ringing that maybe, just maybe, its not _that_ bad.

~~~
gambiting
So personally I have tried it with the projects we work on(large, heavily
templated C++ projects) and issues I have is that using auto confuses the hell
out of VisualAssist and Intellisense(80% of the time they just can't guess
what the type actually is so I get no autocomplete on any methods, which slows
me down hugely) but the worst part is that the debugger doesn't know either -
so any time I get a crash with auto I need to spend additional few minutes to
find the actual type(and the right template!) and cast it manually in the
watch window, because the debugger either straight up doesn't know, or is
inferring the type incorrectly(which is actually worse than not knowing).
That's in VS2015 with both MSVC and Clang.

It's great on smaller projects and I have used it for few tools that I wrote -
but the larger projects, no thanks. In general our code standard only allows
auto if the type is defined immediately before it(so if you create a vector
and then want a for loop immediately below it, then it's fine to use auto for
the loop, otherwise no).

~~~
stinos
Thanks for sharing, didn't know this was still as bad as you describe. Despite
having a considerable amount of template code as well we don't have problems
to the degree you mention - especially not in the debugger (but only when
compiled in debug without optimizations, not in release, but that's sort of
expected). We do use VS2017 though, and basically ditched VAssistX after
moving to it because the built-in intellisesne was good enough. It's not like
literally _everything_ works, but it's usable enough.

Apart from that I also have an impression, not measurable, that since a couple
of years using auto we somehow got used to it and don't have to rely on
intellisense etc. Sounds like a contradiction, and might not have anything to
do with auto but just C++ in general or even just the team becoming better,
but it's like the code is more generic and cares less about exact types but
still has less bugs because it's easier to reason about.

