
Why you should learn F# - aloisdg
https://dusted.codes/why-you-should-learn-fsharp
======
algorithmsRcool
F# is 3 big things to me:

Safer threading with immutability

Safer programming with null-safety

Safer logic with precise domain modeling

The precise domain modeling is the real paradigm shift.

The whole point of static typing is to inform the compiler about your intent
so that it can provide guarantees about correctness. F# makes it easy to
define lots of small types that precisely model state so that you can give
more responsibility to the compiler to verify your program.

I cannot overstate how important this is to maintaining correct software
overtime. If you guard your touches with non F# code, you need far fewer unit
tests and probably even less runtime checks because you already know if the
types are right, so is the logic. And when you need to write unit tests, the
functional style makes your tests very easy to write.

I have personally struggled with domain complexity in C# that i was able to
model precisely in F# and have it work perfectly on the first try.

~~~
contravariant
>I have personally struggled with domain complexity in C# that i was able to
model precisely in F# and have it work perfectly on the first try.

If you're willing to provide a (simplified) example I would be very
interested.

~~~
ambulancechaser
We found it quite nice for properties of objects that appear over time. Think
things like Order that might or might not have delivery details. In C# you are
making classes with nullable delivery timestamps, delivery person, etc. And
one or two properties isn't that bad but it gets a little onerous when you
start to have constraints like "these four properties are either all null or
all populated". In F# it is trivial to set up a new constructor for Delivery
that includes all of these properties. There is no unspoken agreement about
that, you can set it in the model.

~~~
mavelikara
Why do you struggle with this in C#, especially given that you are familiar
with the F# style? I don't know C#, but in Java I'd write this as:

    
    
        public class Order {
          final Optional<DeliveryDetails> delivery;
    
          public Order(Optional<DeliveryDetails> delivery) {
            this.delivery = delivery;
          }
        }
    
        public class DeliveryDetails {
          final long deliveryTimeMs;
          ...
          public DeliveryDetails (long deliveryTimeMs,...) {
            this.deliveryTimeMs = deliveryTimeMs;
            ...
          }
        }
    

My IDE writes most of these lines for me. I believe C# will have similar or
more succinct constrcuts.

~~~
tigershark
The ide maybe will write a small part of it, but you’ll have to keep reading
it forever. And obviously it is modelled wrong because it is possible to have
a Delivered order without delivery details, there is nothing that enforces it.
Compare it with how I would write it in f#:

    
    
        type OrderId = OrderId of string
        type DeliveryTime = DeliveryTime of long
        type DeliveryDetails = { deliveryTime: DeliveryTime...}
        type Order = { id: OrderId ...}
        type DeliveredOrder = { id: OrderId, deliveryDetails: DeliveryDetails...}
    

Probably it is even better to define delivery time using the unit of measures
and specifying it as ms. What is the difference in this way? That an order
cannot ever have DeliveryDetails, while a DeliveredOrder _must_ have
DeliveryDetails. As a bonus you can’t just pass any string as an order id (for
example a description) but you need to pass an actual order id. the same is
true for the deliveryTime with the adddd advantage that you won’t be able to
perform operations on it with a different unit of measure. In java or c# you
would kill yourself if you try to do something similar and moreover you won’t
have all the constraints specified here and the immutability automatically
enforced.

~~~
tpxl
What's the difference between this and having an Order class and a
DeliveredOrder extends Order class in C#?

~~~
hnbroseph
they said "an order cannot ever have DeliveryDetails"

so, if in a nominative subtyping situation like you suggest, a DeliveredOrder
is-a Order, and so we can see that some subset of Orders CAN have
DeliveryDetails. any method receiving an Order could receive a DeliveredOrder.

~~~
contravariant
> any method receiving an Order could receive a DeliveredOrder.

This seems reasonable, if not outright desirable.

~~~
tigershark
No, most of the time is wrong. If you have a DeliveredOrder you want to make
sure that is not delivered again, so the delivery function should accept only
an Order, not a DeliveredOrder. If in some different system you need a domain
object that is both an Order and a DeliveredOrder than in F# you simply use an
union type:

    
    
        type Order = UndeliveredOrder of UndeliveredOrder | DeliveredOrder of DeliveredOrder
    

And in this way you can write a function that accepts both an UndeliveredOrder
and a DeliveredOrder.

------
phillipcarter
Hey folks,

Glad to see Dustin's good post get some visibility here :)

If anyone is interested in learning F#, there are some resources available:

F# docs index (has multiple guides for specific editors and a comprehensive
overview of the language):
[https://docs.microsoft.com/dotnet/fsharp/](https://docs.microsoft.com/dotnet/fsharp/)

F# on JavaScript with Fable: [https://fable.io/docs/](https://fable.io/docs/)

More F# in the browser with WebSharper:
[https://try.websharper.com/](https://try.websharper.com/)

F# on Azure Notebooks (a hosted Jupyter notebook service that's free):
[https://notebooks.azure.com/Microsoft/projects/2018-Intro-
FS...](https://notebooks.azure.com/Microsoft/projects/2018-Intro-
FSharp/html/Introduction%20to%20FSharp.ipynb)

And of course, the now legendary (at least among the F# community), F# for Fun
and Profit:
[https://fsharpforfunandprofit.com/](https://fsharpforfunandprofit.com/)

~~~
AdeptusAquinas
Great thing about this article is that it treats C# with respect, even as it
lambasts it :) Good examples real world situations, no exaggerations. FSharp
For Fun and Profit often uses straw-man implementations of C# to compare
against, which I think does harm to the argument.

------
daxfohl
The only thing I don't like is the DI story presented here and many other F#
guides. Having gone down that rabbit hole and using F# in production for 5
years now, I have gone back to classes and interfaces in almost all cases.

Functions as DI mechanism suffers from a few things. First, it's hard to
search for implementations. They could be defined anywhere. With interfaces,
the implementations are a hot key away. Second, functions only replace single-
function interfaces. Even with a purist view of ISP, there are still plenty of
occasions where a service would expect to call multiple functions on a
contained service. Passing all those in as multiple parameters gets unwieldy
in real world scenarios. Third, F# has no way to inject a dependency into a
whole module, so you have to go function by function. Injection into classes
is much easier to manage this way. Finally since none of the services or
interfaces are named, they don't work with IoC containers.

The good side is that there is nothing in F# preventing you from using classes
and interfaces in your design. Unsurprisingly this is my preferred way to go
about it.

I kinda wish the function based DI wasn't brought up so much and so early.
It's a big mental leap that I think turns off some people coming from other
languages. And for limited benefit. Or negative benefit in plenty of cases.

~~~
jadbox
It sounds like your (more or less) just using classes for just namespacing
functions and allowing bundles of functions to get brought in?

~~~
dvlsg
I've definitely structured f# modules that way. The module exposes one
function that "injects" the dependency into multiple other functions, and then
returns them as a blob.

I'm not sure if that's "the fsharp way" (i suspect it isn't) and maybe I'll
look back on it some day and cringe, but it's working pretty well for some of
my (admittedly small) side projects I'm tinkering with right now.

~~~
daxfohl
Yes, that's what I do too. "Service" modules contain all the functions, with
all dependencies explicitly passed into them, and at the bottom of the module
is an interface with the dependencies assumed injected and a factory function
that takes all the dependencies and returns an object with that interface.

In general I use a suave functional styled api on the top, OO-style SOA in the
middle, and mostly functional style at the bottom layer, something of an FP-
OOP-FP sandwich. I jokingly call it sandwich oriented programming.

------
sevensor
I have a seasonal project that spins up around this time every year. Last
year, I chose F# for a (relatively small) component of the project and I was
not disappointed. I don't have access to the customer's systems, and usually
with Python there's a bit of back and forth where I have to fix bugs that only
customer is able to trigger. My F# program worked flawlessly the first time
and has caused no complaints. I'm excited about writing more F# this year.

------
jweir
A gripe about F# on MacOs - how to install it, count the ways - 6.

[https://fsharp.org/use/mac/](https://fsharp.org/use/mac/)

Don't I need Mono, wait, shouldn't I be using .NET? Oh I will probably install
it one way, only to discover I should have installed it another.

I find the .NET and Mono differences confusing.

So this is a barrier to entry to consider.

That said, this free book is kind of nice introduction:

[https://www.oreilly.com/programming/free/analyzing-
visualizi...](https://www.oreilly.com/programming/free/analyzing-visualizing-
data-f-sharp.csp)

~~~
jjtheblunt
brew install fsharp or similar worked fine for me.

~~~
nobleach
Did you get fsi with that? That was the one thing that made me eventually
install Mono.

------
thedirt0115
I don't know F#, but I do know C#, and it feels like the author is trying to
make C# look more difficult/verbose than it needs to be to make F# look
better. Here is an alternative version of the "Everything is a function"
section's IPasswordPolicy thing:
[https://ideone.com/3Savt9](https://ideone.com/3Savt9) I even went a little
overboard with the function that takes a list of functions and returns a
single composed function -- I could've also written a one-off that uses "&&"
like the F# version: bool isValidCustom(pw) { return f1(pw) && f2(pw) && ...;
} Am I missing something? Why did the author make the C# version so complex??

~~~
algorithmsRcool
Well you're right of course. But my only thought here is that Dustin's code
looks like idiomatic C#, but yours does not.

You can do function composition in C# but I've virtually (heh) never seen it.
Classes and Interfaces are the default abstractions in C# land even if there
are other available.

------
winkelwagen
I've been diving into f# in 2018. I came from c# world, and it really made me
a better developer. Really recommend the language. Think it has a great
balance between functional programming and OO if it is really needed. I really
do think it's easier to write better .net programs with f# then c#. Think this
article point out some great stuff.

That said, it's quite hard to actually get to use it in production at the
places I've worked. My college's are scared of it (that is pretty reasonable,
considering c# is a good stable language and my team is confident that what we
develop will make the customers happy).

One thing that makes me hesitant to really try to get this adopted in my
company is the tooling. My experience hasn't been great. It works, but it has
been pretty unreliable. Some documentation was more focused on the "pre dotnet
core" era of f#. I know i've been spoiled, but stuff like debugging, tooling
and refactor tools can't touch Visual Studio.

There are some decent options, Jetbrains Rider and VS Code are a couple of
them.

Small things, like creating a record type while typing is inconvenient.

type Customer = { Id: int; Name: string; Age : int; }

While typing an instance of the record

let c1 : Customer = {Id = 1;

gives you a bunch of compiler warnings, I know I'm not done, Compiler knows
there are more properties. But without looking at the record type it's hard to
see what order things are.

I'm not sure if this is just OCaml thing, but C kind of languages are better
at predicting what you want to create. It's weird that with the very
predictable Hindley–Milner type system it can't provide the developer with
good information.

I know it's a small thing, but when working with large projects, I don't want
to look everything up, I have the compiler have my back.

I'll really think Microsoft should help the Fsharp Foundation more, seeing
what an amazing language f# is. But it really could use some more love from
MS. Perhaps they should help the community be more confident that they can
solve the business problems they run into. I hope Microsoft would say: "Hey
this is how you create The Boring Line Of Business App, with all the bells and
whistles you normally need". From how to deal with Dependencies in large
projects (No, a couple of (amazing) conference video's of Mark Seemann do not
give me enough confident that after 6 months of development it still is
manageable)

Until the Tooling is done, I just keep enjoying the language and learn how to
become a better developer with it.

~~~
maxxxxx
"That said, it's quite hard to actually get to use it in production at the
places I've worked. My college's are scared of it (that is pretty reasonable,
considering c# is a good stable language and my team is confident that what we
develop will make the customers happy)."

That's my problem too. I would like to give F# a go but at work it seems close
to impossible to implement. Most people don't see the need and if there is a
problem it will be blamed on F#. It's hard to win there if management doesn't
fully support it.

------
mcintyre1994
I've previously used Ocaml at my last job and use Scala at my current one,
it's interesting that F# (just judging from this blog post) looks more similar
to Ocaml than to Scala - like they've more aggressively pulled out syntax and
embraced partial application etc.

I'd always assumed F# was to C# what Scala is to Java - and I think that
probably does represent their design goals, so I wonder what the different
considerations were that led to them being relatively quite far apart.

~~~
pjmlp
F# is the evolution of ML.NET developed at Microsoft Research.

~~~
smcl
Is that right? I know they have a machine learning library called ML.NET ...
but it seems weird to me that they’d recycle the name.

~~~
jweir
ML (Meta Language) vs ML (Machine Learning). It is confusing.

When I hear ML, I think the language (cause I am "old"), but it is usually the
process (Machine Learning) cause that is what is hot.

[https://en.wikipedia.org/wiki/ML_%28programming_language%29](https://en.wikipedia.org/wiki/ML_%28programming_language%29)

~~~
smcl
Right - I'm pretty familiar with Ocaml so the distinction is pretty clear on
my end. I'm just a bit suspicious of this one thing in the comment I replied
to.

------
ken
"No matter if you are already a functional developer from a different
community (Haskell, Clojure, Scala, etc.) or you are a complete newbie to
functional programming (like I was 3 years ago) I think F# can equally impress
you" -> "For this task and for the rest of this blog post I'll be comparing F#
with C# in order to show some of the benefits."

F# is neat, and I see why it's useful if you have a big .NET program already,
but for anyone else I don't see why I'd pick it over a more mature (and less
Microsoft-centric) functional language like OCaml, SML, or Erlang.

Does F# have any unique features that other functional languages lack, or is
.NET integration its killer feature?

~~~
phillipcarter
.NET integration is probably the biggest killer feature, because that unlocks
official support for most important platforms that you'll need to use. Using
AWS or Azure or GCP because your business is moving stuff to a butt provider?
You have access to fully-supported SDKs maintained by teams who do that stuff
for a living. And so on. .NET also has a spectacular standard library, and
with .NET Core, runs _very_ well in any environemnt.

But from a language standpoint, here are three unique features

* Type Providers, which let you generate types based on a data source, and tie compilation to the use of that data being correct

* Active Patterns, which are similar to Haskell's View Patterns, and let you tie some arbitrary functionality that ultimately returns an Option into a pattern for neat pattern matching

* Computation Expressions, which let you express, compose, sequence, etc. monadic and monoidal computations in a convenient syntax that's super easy for newcomers to grok. There is also an RFC and WIP implementation that expands these to support applicative constructs

There's more (Units of Measure, universal quantification via Interfaces, etc.)
but these three tend to be something people like a lot.

~~~
dustinmoris
Thanks, I completely missed to talk about type providers, active patterns and
unit of measure, but then the post was already so long lol. I think I'll add
other good blog posts which cover all these topics to my final notes!

------
PsylentKnight
Regarding F#'s real world usage, today I came across an end-to-end F# stack,
SAFE stack.[0] It looks very intriguing and I would be interested to know if
anyone here has experience with it and has thoughts on it.

[0][https://safe-stack.github.io/docs/intro/](https://safe-
stack.github.io/docs/intro/)

~~~
chusk3
Yep, almost all of my side stuff and an ever-increasing proportion of my work
stuff is in SAFE. It's actually built on Dustin's Giraffe library, which
itself is built on top of Asp.Net Core. Cross platform, great ergonomics due
to Giraffe, and I get to share client side/server side domain models,
validations, etc due to the shared F# heritage.

------
Nelkins
That "famous slide" really rings true for me. F# allowed me to forget (or at
least not worry about) a TON of OO design patterns. Data goes in,
transformation happens, data comes out.

I do like that F# is very practical about OO though.[0] I feel that the
language often strikes a balance of programming paradigms that enables me to
be very productive.

[0] [https://eiriktsarpalis.wordpress.com/2017/03/20/why-oo-
matte...](https://eiriktsarpalis.wordpress.com/2017/03/20/why-oo-matters-
in-f/)

------
moron4hire
I really wish Unity3D would relinquish control of my Visual Studio Solution
files and have a much nicer path to including its libraries as a dependency
manually so I could start using some of the other languages in the CLR
ecosystem.

I've managed to get it to work before by very carefully searching for the DLLs
in the Unity install directory and compiling my own DLLs into a Plugins folder
in my Unity project, but it's very brittle. It's not obvious which set of DLLs
to import (there are lots of different versions of each, for various rhyme
platforms), and I upgrade new Unity versions frequently, so the location is a
moving target. And Heaven help you if you want to depend on something that is
only released as a script bundle in a Unity Package (like every VR SDK out
there right now). And given how Unity's braindead YAML metafile system works,
you're pretty sure to break your component references in your scenes and
prefabs with even the most minor of rearchitecturings.

Unity having its own build pipeline is a huge impediment. It all but forces
you to write custom scripts that do some of the most basic things, as if we
live in the Node hellscape of Gulp/Grunt/Webpack. And none of it is documented
well enough to get it right without hours of ping-pong with test runs.

------
eterps
Now release a native F# variant with rustup/cargo like tooling and a REPL and
I'm sold.

~~~
zamalek
Cargo[1]. REPL[2].

[1]: [https://ardalis.com/how-to-add-a-nuget-package-using-
dotnet-...](https://ardalis.com/how-to-add-a-nuget-package-using-dotnet-add)
[2]: [https://docs.microsoft.com/en-
us/dotnet/fsharp/tutorials/fsh...](https://docs.microsoft.com/en-
us/dotnet/fsharp/tutorials/fsharp-interactive/)

~~~
phillipcarter
Note: the REPL doesn't _quite_ work fully cross-platform with .NET Core yet.
But the work is ongoing and something we're (fairly) close to releasing. When
it's done, you can simply "reference a package" in a script or interactive
session, and it will resolve whatever that dependency graph is and let you use
it as if you were editing source code in a project in an IDE.

~~~
davidgrenier
I care about this a lot. All my respects for the efforts in that direction.

------
dzonga
Like I mentioned in another thread > 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.

------
bnt
Honest question: As someone who does web development and is looking to learn a
new programming language in 2018, would you recommend F# over Elixir (and
why)?

~~~
smush
This has been previously mentioned but F# gets all of the goodies that come
with being a .NET language. Elixir comes from Ruby land and thus has a
framework called Phoenix(?) which also has its fans.

The big difference is that F# is a statically typed functional language, while
Elixir is a dynamically typed functional language. Comparison of static vs
dynamic types -> [https://hackernoon.com/statically-typed-vs-dynamically-
typed...](https://hackernoon.com/statically-typed-vs-dynamically-typed-
languages-e4778e1ca55)

I personally opted for F# because of the domain modelling tools and the
offloading of various caveats and edge cases onto the compiler's stack rather
than the meatspace stack, but Elixir has many fans for a good reason no doubt,
but I'll defer to someone with more experience working with it to weigh in.

~~~
nickpeterson
Did you mean to say Elixir comes from Ruby? Surely you mean Erlang?

~~~
Multicomp
I think the poster got Crystal and Elixir confused. I do sometimes tbh

------
garfieldnate
Honestly I was super psyched to get into F# after finishing Dan Grossman's
programming languages class, but I abandoned it pretty quickly because setup
was so difficult on my Mac.

1) Multiple versions of .Net available (.Net Core, Mono...) and different
tutorials and documentation would apply only to one or the other. 2) I went
with .Net Core because the community seemed to have decided on that, but there
is no easy way to do a cross-platform GUI in F# using .Net Core. 3) I just
couldn't find find a simple tutorial taking me from beginner to intermediate
using a cross-platform toolchain and development environment. I stumbled
around with Visual Studio Code for a while, ran into some compatibility issues
with hundreds of lines of errors messages...

I'm sure it would have been fantastic if I had had an F# person help me get
set up and started, but the setup curve was too steep to be enjoyable
(actually, setting up is never enjoyable. I just want to get to the good part
of coding stuff!).

------
atombender
F# seems like such an amazing language every time I look at it — a modern
version of OCaml, with a clean syntax, some novel ideas, and fewer legacy
warts.

However, I wish that it had, like OCaml, a native AOT compiler that didn't
come with the baggage of the .NET runtime. Some people might consider this a
benefit, not baggage, of course. But it's the same reason I'm put off by
Scala.

From what I understand, to even run a compiled F# program you have to have
Mono installed? It does look like you can get AOT compilation with Mono [1],
but the limitations (e.g. no generics, apparently) seem too onerous.

[1] [https://www.mono-project.com/docs/advanced/aot/](https://www.mono-
project.com/docs/advanced/aot/)

~~~
javcasas
After being deeply burned by the .NET framework, I consider OCaml
significantly superior to F# just because it doesn't depend on .NET or
Microsoft.

And yes, somehow the OCaml guys have managed to implement generics and AOT
compilation to optimized machine code long before the .NET framework existed,
but now this is something "truly hard" on .NET.

~~~
atombender
My problem with OCaml that while the semantics are top notch, everything else
is stuck in the past.

The syntax is quirky, there's a bunch of legacy baggage (does anyone use the
OO stuff?), there's no SMP support (though I know this is being worked on),
the toolchain feels antiquated (the REPL still, to this day, doesn't come with
Readline support built in; rlwrap is required!), etc. Not to mention the lack
of modern libraries, frameworks, package management, etc.

Reason and BuckleScript are nice, though. Reason cleans up a lot of my
complaints, while still not being quite as elegant as F#. But there's this
sense that nobody really wants to make any groundbreaking effort here; there
doesn't seem to be any push to make Reason a first-class, new syntax for
OCaml, so it's stuck being a web-oriented veener for new users, while old
"industrial" users like Jane Street are content to continue with their thing.

~~~
rkido
Example of OCaml's object system in use by the creator of OCaml:
[https://github.com/xavierleroy/cryptokit/blob/master/src/cry...](https://github.com/xavierleroy/cryptokit/blob/master/src/cryptokit.ml)

OCaml's object and class systems are excellent; I prefer them to just about
anything else. They rarely get used for the simple reason that algebraic
types, functors, and first-class modules are better suited to modeling almost
any kind of domain logic.

Also, I like OCaml's extremely simple and direct syntax. I'm fine with F#'s
implicit `in`, though it requires whitespace-sensitivity. I think ReasonML
went in the wrong direction, cluttering it up with curly braces and ubiquitous
tuple-like syntax for function arguments.

OCaml actually has excellent tooling — among the best — and some (but not
many) great libraries. What it lacks most is great documentation...

~~~
plinkplonk
>OCaml actually has excellent tooling — among the best

I don't think even the core OCaml devs would claim this. Rust (and Java and
Microsoft) toolchains are examples of excellent tooling. OCaml, not so much.

That said, the tooling situation today in OCaml is much better than it was a
few years ago, which is real progress.

~~~
rkido
Yes and no. OCaml already has one of the fastest production compilers in the
world, acceptable error messages (better than Haskell's, anyway), a great REPL
(utop), a high-quality and well-documented build system (dune), a powerful
package manager (opam), and a very good language server for IDE integration
(merlin).

What it's sorely missing right now is higher quality documentation output.
Currently, it's hard to navigate the generated documentation (e.g., no search
bar), it's not held in a centralized online location, and it doesn't do a
great job dealing with complex module/functor hierarchies (especially in the
presence of destructive substitution).

Unfortunately, much of what I described above doesn't come out of the box. To
fix this, the OCaml community is seeking to emulate Rust's cargo tool via the
development of the ocaml-platform:
[http://ocamllabs.io/doc/platform.html](http://ocamllabs.io/doc/platform.html)

An aside: I didn't know Java had good tooling. I know it recently gained a
good REPL. But what is the official package manager, and where is the
centralized repository for packages?

~~~
atombender
I believe Maven is Java's package manager these days.

------
vumgl
(no/less functional) C --> Java --> C# --> Scala --> F# ---> Haskell (more/all
functional) \- form a talk by Martin Odersky

~~~
Timothycquinn
Do you know which talk this is discussed? I'm interested in watch his stuff.

------
urda
Do HN users have any F# references, books, or guides they recommend? I've
always been intrigued by F# but haven't found a good project / use case for
it, but I suspect that's because I need to know more about it first.

~~~
winkelwagen
I've really enjoyed

[https://www.manning.com/books/get-programming-with-f-
sharp](https://www.manning.com/books/get-programming-with-f-sharp)

Think it gives a good overview of the language and it's easy to read.
Considering that after a day of working I'm not that sharp anymore it was a
good read for me.

Also mentioned in the article, but Scott Wlaschin book really show the
strengths of the language. Most of his stuff is great actually, but his
website (FSharp for fun and profit) is not the most coherent read, I love
using it as reference. I also recommend his conference talks, it has quite a
bit wide range of topics.

[https://pragprog.com/book/swdddf/domain-modeling-made-
functi...](https://pragprog.com/book/swdddf/domain-modeling-made-functional)

There are also few courses on pluralsight, but cannot remember which ones I
really enjoyed.

~~~
urda
> Considering that after a day of working I'm not that sharp anymore it was a
> good read for me.

That's a great consideration you made, and I'm in the same boat. I'll check it
out thanks!

------
cflyingdutchman
If you want to get paid to learn F#, my team is hiring at Jet/WalmartLabs. If
you want to learn more, email me at cole@jet.com.

~~~
AchieveLife
Has the culture improved since the acquisition? Last time I interviewed there
I was treated like dirt.

~~~
cflyingdutchman
I'm genuinely sorry that you had a bad interview experience, feel free to
email me more details so that I can make sure the feedback is routed to the
right people.

Over several years now, I've been very happy with the engineering quality and
culture; I feel lucky to work with the people here.

------
cgrealy
While I really like the concept of functional programming and F# is definitely
on my list of practical useful languages to learn, this article is clearly
written by someone who doesn't know C# very well.

Take the "To hell with interfaces" example.

    
    
      public interface ISortAlgorithm
      {
        List<int> Sort(List<int> values);
      }
    
      public class QuickSort : ISortAlgorithm
      {
        public List<int> Sort(List<int> values)
        {
            // Do QuickSort
            return values;
        }
      }
    
      public class MergeSort : ISortAlgorithm
      {
        public List<int> Sort(List<int> values)
        {
            // Do MergeSort
            return values;
        }
      }
    
      public void DoSomething(ISortAlgorithm sortAlgorithm, 
      List<int> values)
      {
        var sorted = sortAlgorithm.Sort(values);
      }
    
      public void Main()
      {
        var values = new List<int> { 9, 1, 5, 7 };
        DoSomething(new QuickSort(), values);
      }
    

No, no, no, no, nope.

    
    
      public static class MergeSort
      {
        public static List<int> Sort(List<int> values)
        {
            // Do MergeSort
            return values;
        }
      }
    
      public void DoSomething(Func<List<int>, List<int>> 
      sortAlgorithm, List<int> values)
      {
        var sorted = sortAlgorithm(values);
      }
    
      public void Main()
      {
        var values = new List<int> { 9, 1, 5, 7 };
        DoSomething(QuickSort.Sort, values);
      }
    

No interface necessary.

Or immutability:

    
    
      "public struct Customer
      {
        public string Name { get; }
        public string Address { get; }
    
        public Customer(string name, string address)
        {
            Name = name;
            Address = address;
        }
      }

So far so good, but unless someone knows C# very well one could have easily
gotten this wrong."

Really?? This is beginner stuff.

I 100% agree that null sucks, functions should not need to be in classes and
immutability is great, but this kind of strawman doesn't help his point.

~~~
dustinmoris
Your sort solution limits which algorithms can be used, because you can't pass
in a Func which might need an additional parameter anymore.

This is why most C# developers would use an interface for this. With an
interface you add extra parameters or dependencies to the constructor of the
concrete implementation. If this example wasn't sort algorithms but password
hashing algorithms this would be clear.

So yeah.. it proves my point... writing good C# is not that easy, requires a
lot of experience and mistakes before someone knows how to write SOLID code in
C#. Thanks for helping my point!

~~~
algorithmsRcool
Just to be clear, you are arguing the superiority of partial
application/currying here right?

Because your F# example is the same except it's trading Func<List<int>,
List<int> for (int list -> int list)

~~~
AdeptusAquinas
Technically its passing 'a list -> 'a list, and only becoming an int array
because thats the final input value. The fsharp functions are closer to the C#
functions Func<List<IComparable>, List<IComparable>>

~~~
algorithmsRcool
Or to be even more pedantic it's

Func<T[], T[]> where T : IComparable<T>

But maybe all of that is just stronger arguments for F#'s inferred typing...

~~~
AdeptusAquinas
Or to be even mooooooore pedantic the fsharp functions would probably be
written to be seq<'a> -> seq<'a>, so that would be Func<IEnumerable<T>,
IEnumerable<T>> where T : IComparable<T> :)

------
sidcool
There's a thread every few months about 'Why You Should Learn X', and I feel
overwhelmed by it. I liked the one about Rust and got into the Rust boat. Now
I have no time and energy to learn F#. That's both frustrating and
debilitating. Personal Opinions.

------
crimsonalucard
I heard F# supports this newish thing called dependent typing which allows the
type checker to not only check for type correctness but logic correctness as
well.

I've never worked with dependent typing but is it true? Does the F# really
take away the need for all unit testing on a project?

~~~
rspeele
F# does not support dependent typing. And in general, because it has to
interop smoothly with .NET code written in C# and VB.NET, F# is not nearly as
hardcore on functional purity as something like Haskell or Agda, and
correspondingly cannot guarantee as much safety through its type system.

It is a wonderfully pragmatic language though and does guide the user towards
more reliable software patterns than C# does. It sort of bridges the gap to be
something you can actually use in production today, whereas the dependently
typed languages are still in the realm of experimentation and toy projects for
now.

------
agsdfgsd
No, if you are a functional developer from haskell, you will not be impressed
by F#. Why add silly things like this to your sales pitch if F# is your first
functional language, and you're still pretty new to it?

------
zenzen
There are a lot of claims about why F# is better and not much data to back
them up. I'd really like to learn F#, but are there proven benefits to code
quality / shipped defects / etc? For example, looking for research like:
[https://quorumlanguage.com/evidence.html](https://quorumlanguage.com/evidence.html)

------
Annatar
I don't touch anything that runs on CLR or a JVM: waiting for the world to
compile is unacceptable. For functional programming, I'll just continue
learning ANSI common Lisp which compiles straight to machine code, thank you
very much.

~~~
avisser
Any reason in particular why it's "unacceptable"?

~~~
Annatar
It's slow and bloated. For someone who grew up coding intros and cracking
protections in machine code on C=64 and the Amiga, such bloat simply won't
fly. It's an abomination. I hate wasting my life away waiting for slow
software.

~~~
nickpeterson
If it makes you feel better, the JVM and dotnet communities agree and have
been working on strategies to reduce the bloat a lot. They also offer a ton of
other resources to help tune things to your liking.

I'm sure you can hand write a piece of C or Common Lisp that is very fast. But
I'm sure you would also acknowledge that people that are good at JVM/Dotnet
could probably write a pretty fast piece of code in them as well. So at a
certain point you have to start weighing other things, like productivity,
safety, tooling, libraries, etc.

I find if I really dislike something, I try learning it, and at the end I find
that I may not prefer it, but I always learn something from the experience.
Think of it as an exercise in sharpening your debate arguments against
proponents of these platforms.

~~~
Annatar
I had a semester of Java and AWT programming at the university. The professor
was really good. My final project got a good grade. But after it was over, I
knew I'd never touch Java again: any language where I needed to instantiate
three different objects just to output a single message to the screen is crap.

Available libraries or lack thereof were never criteria by which I judge a
language. Chalk that one up to competing against other coders on the scene. If
someone disasembled one's intro code and found that one were using pieces of
someone else's code, one instantaneously lost face and would never be able to
live it down. It was plagiarism. 35 years later those same people still get
derided and laughed at. It's considered extremely lame, because it means one
wasn't capable of writing one's own routines. This is elitist in the extreme
and those are the stakes for making it to the elite programming circle that is
the scene. I'm perfectly fine with that, under the motto "it's lonely at the
top". And that's as it should be. IT doesn't need more programmers producing
so much bloated garbage; it needs the best programmers producing small, light
and fast software that's a joy to use to its users.

So for me, having been tempered by such an elitist, competitive environment,
library availability is never important. I understand that open source is
different and I understand the advantage of not duplicating code, so if it's
already been written and if it is good, clean code I'll use it, but I've no
qualms about rolling my own.

I would never allow for library availability to influence my choice of a
programming language: the language must stand on its own, including how easy
it is for the system administrator to install and upgrade my application
during its software managent lifecycle.

As programmers we should never make it easy or convenient for ourselves at the
expense of complicating users' life or wasting their time. Never ever is that
excusable.

~~~
rspeele
This point of view seems to have a lot to do with programming as craft, and
very little to do with programming as engineering.

Nothing wrong with that, but most developers are more concerned with the
latter. Writing your own (compression routines|HTML parser|stepper motor
driver|user interface controls|game engine) that's fast, cleanly designed, and
bug-free is an act of craftsmanship. But if it takes a week and working around
the quirks of one off the shelf takes an hour, and the resulting program meets
the same requirements either way, it's the wrong engineering choice.

~~~
Annatar
"But if it takes a week and working around the quirks of one off the shelf
takes an hour, and the resulting program meets the same requirements either
way, it's the wrong engineering choice."

(Un)fortunately, that's not how the world works: it never takes an hour to get
the work done even with the off of the shelf solution, and software which gets
put together this way usually ends up needing to be babysat and the long term
costs to maintaining it are exorbitant. Curiously, the quality of the software
ends up being extremely poor not because of using readily available
components, but because of the mentality of the people springing for such
solutions.

And somehow I have the impression that you and I have different defintions of
"engineer": a programmer is not and never had been one. An engineer (which is
what I do) gathers requirements, writes a technical specification based on
those requirements, designs the software architecture which meets the
specifications put forth, proceeds writing said software using scientific
theories and principles (the actual process of engineering) and finally writes
comprehensive documentation for that software.

------
steelframe
Someone I interviewed some years back did their interview in F#. I didn't know
F# and tried to make that abundantly clear to them, but they persisted
nonetheless. I had messed around with O'Caml back in college and so at least
had a passing familiarity with functional language concepts, but I really had
no idea if what the candidate produced could be considered quality production
code. That didn't help their chances of getting the job.

~~~
quickthrower2
Maybe they want to do F# in their job, in which case they successfully
filtered you out. Although it might have been smarter for them to ask about F#
in an earlier round, or pre interview.

