Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

We're an F#-first company and I'd like to share our experience here.

All our new code is in F#, we started off from a C# codebase, so that made the transition somewhat manageable, as new F# code can be directly called from C#, and vice versa (still took over 2 years). All new frontend apps are also being written in F# (using Fable), as of 6 months back, migrating away from TypeScript, this forces everyone into a "design your model first, and well" paradigm. We've written quite a bit of code to blur the lines between traditional backend and frontend development roles, so what we have now are:

- product engineers (who write application logic on both frontend and backend to serve business needs)

- platform & framework engineers (who write the underlying persistence/serialization/versioning/frontend-backend-sync websocket/load balancing/IDE extensions/deployment etc)

- component designers who focus on visuals

Platform/framework engineers try to encapsulate as much magic as possible into computation expressions (F#'s monads), so product engineers can focus simply on writing out business intent, with readability given very high priority. We also make ample use of quotations to do some cool tricks (like predict the future states some type can take, based on current state + available transitions).

Our code written in F# has an order of magnitude fewer bugs when it makes it to production, given the amount of thought we pour in modelling the problem domain accurately, and thanks to functional programming itself. They're also more amenable to business requirements changing, simply because they've been modelled well to start with. Nothing that can't be achieved in other languages, but with F#, this happens more naturally.

Almost everyone in our team has learnt F# on the job, and overall, everyone's experience has been extremely positive. There's a bit of difficulty in the first 2-3 months, as junior devs get introduced to functional thinking, but if you've generally being doing functional programming, this is just about learning new syntax, tooling and F#'s choice of operator naming (map/bind/pick/collect/choose/..). Typically, based on prior experience, we ask newcomers to spend two weeks to a month, solving the first 100 problems on Project Euler in F#, without using the mutable keyword, and we assign a mentor to point out best practices and review their code.

The hiring pool for F# devs is much smaller than the regular applicant pool, but if a candidate shows genuine interest in F#, they are usually 10x more likely get through our interview process. If they've discovered F#, it means they find something lacking with mainstream languages, so they're likely to have many years of experience under their belt, and they've found a way to grow. That said, we don't restrict our hiring to simply F# devs.

For more info about us, see chaldal.tech (YC/S15).




Amazing! I’d be interested- the problem I have in the FP space is not getting the F# or Haskell experience so you have to “keep up in your spare time” and with other commitments I have to choose what to keep up with and the rarity of FP jobs means it makes more sense to say learn Redux, Sagas, that kind of stuff etc. So I think it’s good if companies like yours would take pure enthusiasm with proven knowledge of other programming languages and desire to learn F#. But I guess it depends as you may have a queue of people wanting a FP job so you can be choosy!


I find the same thing. Getting the experience can only happen in time I direct. I have scope to use F# at work but still fear that choice is not the best for the company I work for. Yes I will love the tooling and right now I'm there but it won't always be that way. They won't be able to find contractors to make changes in the future. I have to give them solutions they can run with in the future or they will be forever regretting me once I'm gone.


If you're on a .NET stack, F# is a secret sauce; its just not many have bothered to look :) Maybe discuss with your CTO and make a collective decision to invest in it by understanding what it brings to the table, and don't worry too much about the future, like having to hire F# devs. As I described above, guiding existing devs to learn F# is the equivalent of training them to think better (as PG/Eric Raymond quote, it will "make you a better programmer for the rest of your days"). If a small handful of you within the company develop expertise, you can guide others. And what's more; if you do pick up F#, many skills are transferable to other FP jobs (like Scala). There's a leap-of-faith element involved, but it has been paying us dividends.

Also, I really like this post: https://fsharpforfunandprofit.com/posts/low-risk-ways-to-use...


Please can you sure more about this?

> We also make ample use of quotations to do some cool tricks (like predict the future states some type can take, based on current state + available transitions).


Here's is a simplistic example of a state machine:

  let transition (state: State) (action: Action) : State option =
     match (state, action) with
     | (StateA, ActionA) -> Some StateB
     | (StateA, ActionB) -> Some StateC
     | (StateB, ActionA) -> Some StateB
     | _ -> None
If you get the quoted representation of the transition function, it can be visualized as a tree data structure (like code-as-data in LISP). You can analyze that tree to understand that if current state is StateB, only ActionA can be applied on it.

Couple this with another realization: "Any sufficiently complicated model class contains an ad hoc, informally specified, bug-ridden, slow implementation of half of a state machine." (not sure where I read this quote).

This means all the entity framework/ORM crap work that we do can actually be neatly represented as transforms on a F# state machine, which suddenly makes the application more powerful if you give it this structure.

We use this technique to auto-generate admin panels.


> "Any sufficiently complicated model class contains an ad hoc, informally specified, bug-ridden, slow implementation of half of a state machine." (not sure where I read this quote).

Can’t tell you where you read it, of course, but believe it originates from Braithwaite/raganwald:

http://raganwald.com/2018/02/23/forde.html


Do you blog any of this or do any sort of writing on the topic. I think I could learn a lot from the way you are doing things.


Not yet, it has been on my list for a long time. Meanwhile I recommend this blog that collates all good F# content from around the web weekly:

https://sergeytihon.com/category/f-weekly/


Take a look at F#'s type solver code especially wrt to Extension Typing: https://github.com/dotnet/fsharp/blob/main/src/fsharp/Extens...

You can do similar things with other Ocaml or Lispy Langs, depending on how you want to do it. All you need is a function that returns possibleTypeTransitions for givenType(type, enclosedLexeme, type.validTransitions). A gradually typed lang sitting in top of a prototype-based blob also makes this easy to do (see typescript) in-codo.

See also MacKay (RIP)'s classic book: http://www.inference.org.uk/itprnn/book.pdf


How's your experience with Fable, especially when using third party JS libraries?

I'm really having fun experimenting with F# for my API server, but I hesitate to use it on the front end.


That's a good pitch!


Maybe it's my unsophisticated mind talking here, but programming in F# is pure joy.Among the languages I use only Ruby gets close to provide that feeling.


Yes :) That moment when it simply clicks, it's not something that goes away. It has certainly made my day-to-day programming work a lot sweeter, hence I can't shut up talking about it. And it's not like I write some esoteric ML or data science code, a lot of these are boring line-of-business applications, yet it is so satisfying designing those in F#.


Does interop with c# get easier?

Trying to figure out how to map to an overloaded C# callback (maybe hidden in an *.extension doc!) has wasted hours of my time.

F# (the ml family in general) is my favorite language right now but, man, the .net APIs are rough.

Lacking the same UX I’m used to in Node, Ruby, and Elixir.


Interop is janky. It works, but there are some gotchas that need to be worked around. It works in 95% of the cases without much mucking around, but it's not pretty, so you're better off tucking that away in some dark corner.


Can you explain the interop a bit more? I’ve been looking into an F# job. Having a functional background, the language looks nice, but I’m wondering about the ecosystem. Can you not use .Net libraries as easily as you can from C#?


Yes. Typically interop is very straightforward. You look in the api docs and copy paste.

Example here is the String doc[1]. Way down you see all the methods. Some of the methods have overloads (multiple variants). Pretty straightforward here. (E.g. `"mystring".Contains("ring")`)

Where it gets more verbose and finicky is when the API takes a C# callback. Even more complex is if it’s asynchronous so it takes a C# callback as a Task.

An example being the `.Use` method for defining server middleware.[2]

To see how it’s done, here’s a gist I found.[3] Notice how the function for requestHandler is verbosely annotated with Func<> and RequestDelegate, etc.

Luckily this isn’t the norm, most APIs are less complicated. Even so, you write a wrapper (abstraction) around that complexity and only look at your wrapper. Which is why someone in this thread said to leave them in a dark corner.

[1]: https://docs.microsoft.com/en-us/dotnet/api/system.string?vi...

[2]: https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnet...

[3]: https://gist.github.com/kspeakman/7870a75283f6942dd96ff34a03...


I think it will get better in F# 5.1, which adds native C# Task support... https://github.com/fsharp/fslang-design/blob/master/RFCs/FS-...


In the meantime, you can use the fantastic TaskBuilder.fs for C# Task support and interop.

https://www.nuget.org/packages/TaskBuilder.fs/ https://github.com/rspeele/TaskBuilder.fs


Thanks. I appreciate the explanation.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: