[HN Gopher] Why F#?
       ___________________________________________________________________
        
       Why F#?
        
       Author : bozhidar
       Score  : 299 points
       Date   : 2025-04-01 12:34 UTC (10 hours ago)
        
 (HTM) web link (batsov.com)
 (TXT) w3m dump (batsov.com)
        
       | nickpeterson wrote:
       | Because it's great, and people that think otherwise are dead to
       | me.
        
         | MrMcCall wrote:
         | Curried functions combined with that magnificent pipe operator,
         | overlaid on the .NET runtime. Don Syme et al knocked it out of
         | the park.
         | 
         | It's the one programming language that changed how I think
         | about programming.
         | 
         | I'm only talking about the version before type providers. Then
         | it got messy.
         | 
         | Before that, we could (and I did) recompile fsi.exe to do some
         | custom prompt manipulation. It was a slog, but it worked, but
         | then Microsoft faded from my life. Still, that early version (I
         | believe 2.0) F# is just magnificent.
        
           | munchler wrote:
           | F# is up to version 9 now, and has only improved over time,
           | IMHO. Type providers are a very small part of the story and
           | can be avoided entirely if you want.
        
             | jasonthorsness wrote:
             | I tried F# when it was first released and was not a fan,
             | but it sounds like that impression is a little outdated. C#
             | has come so far in that time it's almost a new language.
             | I'll have to take another look.
        
               | MrMcCall wrote:
               | I don't know what C# has for an interactive prompt
               | nowadays, but F#'s commandline environment, via its
               | fsi.exe, was a revelation back then. It prevented having
               | to have entire solutions to contain test projects to
               | explore different areas of the vast .NET framework,
               | especially when just learning how to use specific methods
               | or objects.
        
             | speed_spread wrote:
             | Why would type providers be avoided? It seemed to me like a
             | nice metaprogramming feature, akin to what Zig does with
             | comptime types (except runtime?)
        
               | Akronymus wrote:
               | Type providers can be extremely brittle IME. Altough, I
               | guess if it is referring to version controlled example
               | data that probably works better than referring to a DB or
               | something like that directly that the dev has to provide.
        
               | munchler wrote:
               | Type providers are very powerful but involve running
               | arbitrary external software at compile-time (e.g. a SQL
               | Server or Postgres database). This can be difficult to
               | set up and configure reliably in a multi-person project.
        
               | MrMcCall wrote:
               | For me, I already had all the featues I needed.
               | 
               | Plus, I'm not going to be downloading, configuring, or
               | running any separate code at runtime. The project is the
               | project, it's going to process some files, communicate
               | with some services, and communicate with the UI, if any.
               | 
               | If I need to consume a service, it should be defined such
               | that I manifest the interface module (perhaps via WCF)
               | and then connect to it progressively from stub to ever
               | greater functionality in test to final implementation.
               | Trying to write a program to do all that at runtime is
               | not sensible, IMO.
               | 
               | Metaprogramming via reflection, however, was useful for
               | exploring the vast .NET framework, and I used those to
               | great effect, especially in exploring .NET's various UI
               | frameworks (WinForms and Silverlight), but never to
               | create code at runtime via the emit functionality. No,
               | that's my job: to emit code that is tested and works and
               | is comprehensible.
        
               | Smaug123 wrote:
               | Yeah, they're terrifying. It's often not that hard to
               | generate the code (e.g.
               | https://github.com/Smaug123/WoofWare.Myriad/ is where I
               | pump out these things) for a bunch of what you would want
               | to do with a type provider, and that's much less
               | existentially terrifying if it's possible.
        
             | MrMcCall wrote:
             | I don't doubt it, but I don't run Microsoft software any
             | more. I've seen enough embrace, extend, and extinguish in
             | my lifetime to not depend on them for my code's execution
             | environment.
             | 
             | My current work needs nothing the .NET environment provides
             | that I can't use python's standard libraries to get done,
             | or bash and C if I need to.
             | 
             | But I'm lucky to no longer be in a corporate environment,
             | so I don't need to consume commercial services, which was
             | much easier using WCF within .NET. Back in my previous
             | life, constructing n-tiered services on top of SqlServer
             | using WCF was slick, indeed.
             | 
             | To any who are interested in how to construct such n-tiered
             | applications simply but securely and precisely, I highly
             | suggest Juval Lowy's IDesign system. He had three specific
             | videos that I watched three or four times each until I
             | understood his distillation of his vast expertise. Of
             | course, Mr. Lowy is one of the co-designers of WCF, which
             | was an excellent bit of tech.
        
               | munchler wrote:
               | FWIW, F# is an open source project controlled by the F#
               | Software Foundation, the .NET Foundation, and Microsoft.
        
               | MrMcCall wrote:
               | > controlled by the F# Software Foundation, the .NET
               | Foundation, and Microsoft.
               | 
               | It is controlled by Microsoft. It's not going on my Linux
               | or BSD boxes.
               | 
               | I know how they work, and I want nothing to do with them.
        
               | lunarlull wrote:
               | Do you make sure to run a linux kernel with all the MS
               | stuff patched out also?
        
           | akkad33 wrote:
           | It has great ideas but because of all these conveniences it
           | is very bad for performance based programming making it
           | slower than C#. I like the ideas in Roc language to make
           | functional programming as fast as imperative by controlling
           | allocations in things like closures
        
         | turtlebits wrote:
         | It might be great, but IME, MSFT docs and tooling are subpar,
         | and anything dotnet related is/was a disaster.
        
       | eknkc wrote:
       | As far as I can tell F# is one of those things where every single
       | user is extremely happy. This happens rarely and I really am
       | curious about the thing but never had time to get into it. I'm
       | also pretty well versed in the .net ecosystem so it's probably
       | gonna be easy.
       | 
       | Any tips? What kind of workflows might benefit the most if I were
       | to incorporate it (to learn..)?
        
         | piokoch wrote:
         | "As far as I can tell F# is one of those things where every
         | single user is extremely happy" Isn't it because language has
         | rather small community of passionate people, who are devoted to
         | their language of choice?
         | 
         | F# popularity is somewhere between CHILL, Clipper and Raku
         | langs, that are probably as obscure as F# for typical software
         | dev.
        
           | psychoslave wrote:
           | I know Raku from Perl fame, and F# because it's Microsoft,
           | but CHILL and Clipper are totally new to me, so in my own
           | humble experience these two latter look far more obscure. :D
        
             | orthoxerox wrote:
             | Clipper is old. It's dBase/xBase/FoxPro, pre-SQL DBMSs.
        
           | int_19h wrote:
           | I'm pretty sure that there's more production code written in
           | F# than in all those other three combined.
        
         | munchler wrote:
         | F# shines on the back end, where its functional-first style is
         | very adept at crunching data. Think about data flows in your
         | system: Any place where you use LINQ in C# today to
         | select/filter/transform data might be even better in F#.
         | Parsing is also a great F# use case (e.g. parser combinators),
         | although a fairly narrow niche.
        
         | pjc50 wrote:
         | The funny thing is that you can write very similar code in C#,
         | so maybe you don't need to switch which language you're using
         | as a CLR frontend.                   using System.Linq;
         | using System;              var names = new string[] {"Peter",
         | "Julia", "Xi" };         names.Select(name => $"Hello,
         | {name}").ToList().ForEach(greeting =>
         | Console.WriteLine($"{greeting}! Enjoy your C#"));
         | 
         | LINQ is such a good library that I miss it in other languages.
         | The Java stream equivalent just doesn't feel as fluent.
        
           | bob1029 wrote:
           | You can write a vast majority of your C# codebase in a
           | functional style if you prefer to.
           | 
           | All the good stuff has been pirated from F# land by now:
           | First-class functions, pattern matching, expression-bodied
           | members, async functional composition, records, immutable
           | collections, optional types, etc.
        
             | guhidalg wrote:
             | I don't know if there's a name for it but essentially F# is
             | where the language designers can push the boundaries and
             | try extremely new things that 99% of users will not want or
             | need, but eventually some of them are such good ideas that
             | they feed back into C#.
             | 
             | Maybe that's just research, and I'm glad that Microsoft
             | hasn't killed F# (I do work there, but I don't write F# at
             | work.)
        
               | debugnik wrote:
               | > F# is where the language designers can push the
               | boundaries
               | 
               | It really isn't, not anymore. F# now evolves
               | conservatively, just trying to remove warts and keep up
               | with C# interop.
               | 
               | And even then some C# features were considered too
               | complex/powerful to implement (e.g. variance, scoped
               | refs) or implemented in weaker, incompatible ways when
               | C#'s design is considered messy (e.g. F#'s non-nullable
               | constraints disallow value-types, which breaks for some
               | generic methods written in C#, sadly even part of the
               | System libs).
        
             | UK-Al05 wrote:
             | A language is just as much about what it can't do, then
             | what it can do.
        
               | bob1029 wrote:
               | Can you elaborate on what you mean by this?
               | 
               | I assume you are implying that too many choices could
               | confuse a junior developer, which I agree with. However,
               | I don't think this is a concern in the bigger picture
               | when talking about the space of all languages.
        
               | gonesurfing wrote:
               | My 2p's worth is that the whole of F# is more than the
               | some of its parts. When you say in your previous comment
               | "All the good stuff has been pirated from F#" it misses
               | the point of what it's actually like to use F#. The
               | problem is, it's almost impossible to communicate what
               | it's like. You have to try it and you have to keep going
               | until you get over the initial "WTF!?" hump. There will
               | be a WTF hump.
               | 
               | For example, C# may have cribbed the language features,
               | but F# is expression based and immutable by default. Try
               | using the same features in this context and the whole
               | game changes.
        
             | int_19h wrote:
             | I wouldn't say "all" - C# doesn't have discriminated unions
             | yet, which is kind of a big one, especially when you're
             | also looking at pattern matching. A
        
               | caspper69 wrote:
               | It has been in discussion for quite some time. I believe
               | they'll get there soon: (example)
               | https://dev.to/canro91/it-seems-the-c-team-is-finally-
               | consid...
               | 
               | In the interim, MS demonstrates how C# 8.0+ can fake it
               | pretty well with recursive pattern matching:
               | https://learn.microsoft.com/en-us/dotnet/csharp/language-
               | ref...
               | 
               | Not the same I know, and I would love me a true ADT in
               | C#.
               | 
               | Edit (a formal proposal): https://github.com/dotnet/cshar
               | plang/blob/18a527bcc1f0bdaf54...
        
               | feoren wrote:
               | While we wait for the official discriminated union
               | feature, the OneOf package is a pretty good stand-in:
               | https://github.com/mcintyre321/OneOf
        
           | klysm wrote:
           | This isn't a great example of what linq is good at. There's
           | no reason to do ToList there, and the ForEach isn't
           | particularly idiomatic
        
             | pjc50 wrote:
             | Yeah, I hit the problem that there isn't a null-type
             | equivalent of Select() for Action<T>, nor is there a
             | IEnumerable.ForEach (controversial), so that's a bit of a
             | hack. But I wanted to make it as close to the original
             | example as possible.
        
             | bob1029 wrote:
             | > There's no reason to do ToList there
             | 
             | In this case, I would move it to the very end if we are
             | concerned about the underlying data shifting when the
             | collection is actually enumerated.
             | 
             | Forgetting to materialize LINQ results can cause a lot of
             | trouble, oftentimes in ways that happily evade detection
             | while a debugger is attached.
        
               | klysm wrote:
               | > if we are concerned about the underlying data shifting
               | when the collection is actually enumerated
               | 
               | I'm not sure what you mean by this. You can fulfill the
               | IEnumerable contract without allowing multiple
               | enumerations, but that doesn't really have to do with the
               | data shifting around. Doing ToList can be an expensive
               | and unnecessary allocation
        
               | bob1029 wrote:
               | Imagine a live SQL query you are subsequently filtering
               | with LINQ.
        
           | voidUpdate wrote:
           | I love LINQ, maybe a little too much. I can end up writing
           | monster oneliners to manipulate data in just the right way. I
           | love list comprehensions in python too, since they can work
           | in similar ways
        
           | kkukshtel wrote:
           | Modern C# collection expressions make the definition of names
           | closer to F#:                 string[] names = ["Peter",
           | "Julia", "Xi"];
           | 
           | I know working on "natural type" of collections is something
           | the C# team is working on, so it feels possible in the future
           | that you'll be able to do this:                 var names =
           | ["Peter", "Julia", "Xi"];
           | 
           | Which I think would then allow:                 ["Peter",
           | "Julia", "Xi"].Select(name => $"Hello,
           | {name}").ToList().ForEach(greeting =>
           | Console.WriteLine($"{greeting}! Enjoy your C#"));
        
             | pjc50 wrote:
             | I did try that initially and got
             | <source>(5,1): error CS9176: There is no target type for
             | the collection expression.
             | 
             | .. which I took to mean that, because .Select is an
             | extension method on IEnumerable, the engine was unable to
             | infer whether the collection should be a list, array, or
             | some other type of collection.
             | 
             | It seems reasonable to have it default to Array if it's
             | ambiguous, maybe there's a downside I'm not aware of.
        
           | gibibit wrote:
           | For reference, Rust provides a similar experience
           | let names = ["Peter", "Julia", "Xi"];         names
           | .map(|name| format!("Hello, {name}"))             .iter()
           | .for_each(|greeting| println!("{greeting}! Enjoy your
           | Rust"));
        
           | psychoslave wrote:
           | As far as fluency goes, that's not very impressive.
           | %w{Peter Julia Xi}.map{"Hello, #{it}"}.each{puts "#{it}!
           | Enjoy your Ruby"}
           | 
           | That's of course trivial examples. And while Ruby now have
           | RBS and Sorbet, it's yet another tradeoff compared to a
           | syntax that has upfront static analysis as first class
           | citizen in mind.
           | 
           | That is, each language will have its strong and weak points,
           | but so far on "fluency" I'm not aware of anything that really
           | beat Ruby far beyond as Ruby does compared to other
           | mainstream programming languages.
        
             | int_19h wrote:
             | Ruby is dynamically typed, which makes "fluent" API design
             | that much easier at the cost of maintainability elsewhere.
             | If you want to compare apples to apples, you need to
             | compare F# to other statically typed languages.
        
               | psychoslave wrote:
               | That's exactly what I meant with the two last paragraphs.
        
         | JohnyTex wrote:
         | Personally I think F# is excellent for writing ye olde CRUD
         | applications, especially as the business logic becomes more
         | complex. F# is really good at domain modeling, as creating
         | types comes with minimal overhead. C# has improved a lot in
         | this area (eg record types) but it's still got a long way to
         | go.
         | 
         | I wrote a tutorial about how to get up and running with web dev
         | in F# that might be of interest:
         | https://functionalsoftware.se/posts/building-a-rest-api-in-g...
        
       | aloisdg wrote:
       | F# is corporate friendly ML. Love it.
        
       | lihaoyi wrote:
       | I learned F# in 2013 and had a lot of fun with it, some of that
       | code remains on Github (e.g. a 2D platformer game for windows
       | https://github.com/lihaoyi/FSharpMetro/tree/master/Applicati...).
       | 
       | My experience was that it was a surprisingly nice language with a
       | surprisingly warty user experience: papercuts ranging from naming
       | conventions and function call styles (`|> List.map` vs
       | `.Select`), basic syntax (`foo.[0]` to lookup arrays), type
       | system features (F# doesn't have covariance/contravariance even
       | though C# does), IDE support (back then was only Visual Studio,
       | whose support for F# was inferior to C#).
       | 
       | Ended up settling on Scala after that, as a language with its own
       | Warts, but one that somehow managed to feel a more cohesive than
       | F# did despite having largely the same featureset and
       | positioning.
       | 
       | F# was my first functional language and one that changed how I
       | look at programming, but at the same time I'm happy to not
       | actually have to use it for serious programming!
        
         | munchler wrote:
         | F# supports both functional and OO call styles. That's why you
         | have both `|> List.map` and `.Select`. It can be a bit
         | confusing at first, but the interoperability with C# is worth
         | it.
         | 
         | Array lookup in modern F# is just `foo[0]`.
         | 
         | Subtyping is much less common in F# than in C#, so the need for
         | covariance/contravariance is correspondingly lower. Personally,
         | I've never needed it.
         | 
         | F# support in Visual Studio is now excellent. You can also
         | develop F# in VS Code.
        
         | bozhidar wrote:
         | I think these days F# is probably a big more polished than what
         | you remember, so perhaps it's worth giving it another shot.
         | 
         | Being a hosted language always requires certain compromises
         | (something that was also apparent in Scala). I used to do Scala
         | professionally in its early days, but for me it felt it added
         | just as much complexity as it addressed. I focused on Clojure
         | back then (on the FP side at least), and I do think that F#
         | probably brings more to the table than Scala. (if one is not
         | constrained to Java, that is)
         | 
         | The tooling story is not great, but I've almost never seen
         | great tooling for a language that's not super popular. I'm
         | guessing what you get today with Rider is more or less as good
         | as what VS has to offer.
        
         | djtango wrote:
         | Interesting - I'm curious where your thoughts are now on using
         | FP/Scala in 2025?
         | 
         | I've always looked at F# with envy as it is a hosted ML that
         | will have extremely battle tested bindings to the important day
         | to day stuff via C# (Darklang's stories of struggling with
         | postgres and AWS when using OCaml was a good cautionary tale on
         | the risks of using less common langs as a startup)
         | 
         | Never had a chance to try out Scala but am a seasoned
         | Clojurian, as an outsider it seemed Scala suffered a little
         | from being not opinionated enough so the ML family has been
         | more appealing to tinker with even though Scala supports type
         | classes out the box and will also have great ecosystem support
         | via the JVM
        
           | hocuspocus wrote:
           | It's never been a better time to try Scala if you're
           | interested in the FP side. It's still very much "not
           | opinionated" but the community and ecosystem have benefited
           | from a certain convergence and given up on the "better Java"
           | front which is served by Kotlin more adequately. Of course
           | you can still _consume_ any Java library when needed but it
           | 's best to avoid it if possible. Today you can pick between
           | several ecosystems:
           | 
           | - Typelevel libraries: modern and more welcoming take on
           | ScalaZ ideas, rich and mature, extensible libraries that are
           | written in "tagless final" style.
           | 
           | - ZIO: concrete "super monad" with 3 type parameters, shuns
           | the Haskell baggage and category theory lingo but pretty much
           | the same concepts, compile-time autowiring dependency
           | injection, a bit less mature.
           | 
           | - Kyo: new effects system on the block, pushing Scala 3's
           | type system to the limit to stack effects using an "auto-
           | flattening" monad (sorry if I butchered the description).
           | 
           | - Li Haoyi's own ecosystem that sticks to the standard
           | library and JVM built-in mechanisms whenever possible,
           | focused on Python style expressiveness, only more functional
           | and with stronger types.
           | 
           | - I'd skip Akka/Pekko libraries but it's still an interesting
           | piece of software if you need actor based, stateful cluster
           | sharding.
           | 
           | Martin Odersky and the LAMP are focused on "capabilities" and
           | we should eventually see something like direct-style
           | algebraic effects, or like Kyo but without monads.
           | 
           | Also we have much better build systems than before (Scala-
           | CLI, Mill, sbt has improved a lot too), binary backwards
           | compatibility since Scala 3, and a very capable LSP backend
           | if you don't like IntelliJ IDEA.
        
             | tasuki wrote:
             | Very good summary, thank you! I've mostly stopped writing
             | Scala, but it's still close to my heart.
        
         | JohnyTex wrote:
         | FWIW I think writing F# is a really cohesive experience in day-
         | to-day work. While there are usually at least two ways to do
         | things, due to .NET interoperability requirements, it's usually
         | pretty clear which way is the "right" way to do something.
         | 
         | F# feels kind of similar to Python in this regard, where there
         | might be more than one way to do it, but there is community and
         | ecosystem consensus on what is the _right_ way.
         | 
         | I think a lot of credit should go to Don Syme for this; he
         | seems to have a very clear vision of what F# should and should
         | not be, and the combination of features ends up being very
         | tasteful and well composed.
        
       | Aldipower wrote:
       | "Why the F#?" perhaps would be a better title. :-)
        
       | oguz-ismail wrote:
       | >whitespace is significant, like in Python
       | 
       | hard pass
        
         | voidUpdate wrote:
         | I was with it until I heard no braces :/
        
           | pjc50 wrote:
           | I have some good news for you about C#.
        
             | voidUpdate wrote:
             | I love C#, its a great language
        
               | ahoka wrote:
               | Perfect for blub programmers!
        
             | BeetleB wrote:
             | C# doesn't require braces...?
        
         | fire_lake wrote:
         | Static typing removes the downside of whitespace.
         | 
         | Oh, and every language with line comments (so most of them) has
         | significant whitespace.
        
           | AnimalMuppet wrote:
           | > Static typing removes the downside of whitespace.
           | 
           | How so?
           | 
           | > Oh, and every language with line comments (so most of them)
           | has significant whitespace.
           | 
           | Technically true, but that's not what people mean by
           | "significant whitespace" in this context. So you're being
           | pedantic rather than saying anything meaningful.
           | 
           | But you made me think. The ultimate nightmare would be
           | significant _trailing_ whitespace - the spaces and /or tabs
           | after all the visible characters change the meaning of the
           | line.
        
             | fire_lake wrote:
             | > How so?
             | 
             | Well I don't know what issue you have with whitespace, but
             | the usual complaint is that programs with small typos are
             | syntactically valid but logically incorrect. This is why
             | CoffeeScript became so disliked. A static type checker
             | makes this scenario much less likely since it won't
             | compile.
             | 
             | I would also add that F# has some indentation rules
             | ("offside rules") and tabs are disallowed, further
             | shrinking the input space.
        
         | int_19h wrote:
         | F# has both "lightweight" (indentation-based) and "verbose"
         | syntax. If you don't like significant whitespace, you can just
         | use the latter.
         | 
         | https://learn.microsoft.com/en-us/dotnet/fsharp/language-ref...
        
           | sundarurfriend wrote:
           | That's an interesting idea and implementation.
           | 
           | I don't think being whitespace-significant is a "hard pass"
           | dealbreaker, but as someone who's not a fan of it, I'd say
           | this only goes a small way towards alleviating that - like
           | most "choose your preferred syntax" designs. Even if you're a
           | lone-wolf developer, you're gonna end up reading a lot of
           | example code and other material that's in the ugly
           | whitespace-sensitive style, given that:
           | 
           | > The verbose syntax is not as commonly used ... The default
           | syntax is the lightweight syntax.
           | 
           | And most people in practice are not lone-wolf devs, and so
           | the existence of this syntax helps them even less.
        
         | 110bpm wrote:
         | This isn't such a big issue in my experience. Auto-formatting
         | helps a lot, the code needs to be just syntactically correct.
         | 
         | The default F# autoformatter is bundled/supported by VS Code,
         | VS and Rider [0].
         | 
         | [0]: https://fsprojects.github.io/fantomas/docs/end-
         | users/StyleGu...
        
         | lunarlull wrote:
         | You never touch python code either?
        
       | this_user wrote:
       | Because you love using Microsoft's shitty technologies, but also
       | want to be completely unemployable?
        
         | pacoWebConsult wrote:
         | It's pretty baseless to claim that modern dotnet is inherently
         | shitty. They've made tremendous strides in the dotnet core era.
         | 
         | F# making you unemployable is debateable, but I don't see what
         | makes F# any less employable than most other FP languages. They
         | have some niche applications that make it useful rarely, but
         | when they're useful its a terrific tool for the job. F#'s
         | ability to interop with the rest of the dotnet ecosystem
         | positions it better than most functional languages for business
         | usecases.
        
         | gwbas1c wrote:
         | I've spent my entire career, 22 years, primarily in C#.
         | 
         | I'm quite employable.
        
           | wiseowise wrote:
           | > Because you love using Microsoft's shitty technologies
           | 
           | If we go by the joke in gp, this is you.
        
             | tialaramex wrote:
             | I don't have any problem with the idea that Microsoft's
             | technologies are "shitty" after all the response of my work
             | laptop to its mandatory Windows 11 upgrade was a _non-
             | copyable_ diagnostic message with an opaque code in it
             | which, as I understand it, is basically the equivalent of
             | "Huh, oops, maybe try again?" and my colleague spent a week
             | trying to uh, share data from a "Sharepoint" table.
             | 
             | But .NET's CLR doesn't seem especially shitty. It's not
             | awesome, I don't feel that RIIR urge when I work with C#
             | and I probably wouldn't with F# either but it's fine, it's
             | like Java again, or maybe Go or Python. It's fine. I don't
             | _hate_ it and that 's enough.
        
         | zem wrote:
         | I'm sure Microsoft has developed a lot of bad tech, but by and
         | large their languages have been great. msvc c++ compiler as a
         | possible exception, but f# in particular is excellent.
        
       | amelius wrote:
       | I have a few questions. Can it do GUIs well? How about mobile?
       | And how does it compare to e.g. Scala?
        
         | munchler wrote:
         | It can do GUIs well, although it takes some finesse to manage
         | user state in an immutable-first language. Check out Fable for
         | building web apps: https://fable.io/
         | 
         | I don't have much experience with Scala, but I think the two
         | languages are pretty comparable in their respective ecosystems.
         | The biggest difference I'm aware of is that Scala has
         | typeclasses and F# does not.
        
           | int_19h wrote:
           | F# is not really that strong on immutability, though. Sure,
           | variables and struct fields are immutable by default, but
           | making them mutable is one keyword away. Similarly with
           | classes - declaring readonly properties is more concise, but
           | when you need a read/write one, it's readily available.
        
         | pjc50 wrote:
         | Because it's a CLR language, it has access to all the same
         | technologies as C#. That is, all the Microsoft native ones plus
         | cross-platform with Avalonia.
         | 
         | https://fsharp.org/use/desktop-apps/
        
         | dagw wrote:
         | _Can it do GUIs well?_
         | 
         | I don't know if I would say 'well'. For simple GUIs it's OK
         | but, for non-trivial GUIs I would use the approach to write the
         | GUI frontend code in C# and have it call the F# 'backend'. If
         | for no other reason than that the support and documentation for
         | doing GUIs in C# is much better.
         | 
         |  _How about mobile?_
         | 
         | Never tried, but I'm guessing more or less the same story as
         | above. I would probably start by looking into .Net MAUI for
         | that.
         | 
         |  _And how does it compare to e.g. Scala?_
         | 
         | The biggest difference is that Scala is a much bigger and more
         | of a multi-paradigm language. F# feels smaller and more focused
         | and on its ML roots and functional programming. Not saying that
         | Scala is less 'functional' than F#, but Scala supports you
         | writing your code in a much more OOP way if you want. Yes you
         | can (and sometimes have to) do OOP in F#, but it doesn't feel
         | natural.
        
         | ivm wrote:
         | .NET for iOS and Android is very robust, I've been developing
         | with it since 2018. Just avoid using MAUI for interfaces
         | because it's still quite unfinished after the rewrite from
         | Xamarin.Forms.
        
         | jcmontx wrote:
         | Sprinkle some HTMX next to your favorite template engine and
         | you're g2g
        
           | Akronymus wrote:
           | Which is what I am doing with my personal website for the
           | most part. Elmish for the subpages where a lot of
           | interactivity is actually needed. Otherwise just using
           | Feliz.ViewEngine with htmx purely for enhancements
        
         | Lanayx wrote:
         | For web UI we have Fable and it's integration with well-known
         | js frameworks, also WebSharper (although it's less well-known)
         | and Bolero (on top of Blazor)
         | 
         | For mobile we have FuncUI (on top of Avalonia) and Fabulous (on
         | top of Avalonia, Xamarin and Maui). Most of these frameworks
         | use Elm architecture, but some do not. For example I use
         | Oxpecker.Solid which has reactive architecture.
         | 
         | Can't help with Scala comparison, but at least DeepSeek V3
         | prefers F# for UI https://whatisbetter.ai/result/F%23-vs-
         | Scala-9eaede00c7e4485...
        
       | protonbob wrote:
       | > which is quite odd for what is supposed to be the flagship
       | editor for F#
       | 
       | The flagship editor is Visual Studio, not vs code.
        
         | bozhidar wrote:
         | But it's Windows-only, so it's not an option for me.
        
           | GiorgioG wrote:
           | Rider is an option for you. Community edition is free too.
        
           | protonbob wrote:
           | Who said it was? It is the flagship editor though.
        
         | MaxGripe wrote:
         | The flagship editor is Rider
        
       | a-french-anon wrote:
       | Why would Lispers feel at home with its (whitespace delimited)
       | syntax? Quite the strange claim.
       | 
       | I know this isn't a common rant, but I hate so-called functional
       | language still bowing to the "infix mathematical operator special
       | case" dogma, when those are just binary (variadic in Lisp)
       | functions.
       | 
       | Always found it pretty appealing, otherwise. And no ";;"!
        
       | 7thaccount wrote:
       | F# is beautiful, but I could never crack the nut and get fluent
       | in it. I think the big problem is I only know a little C#, so it
       | is difficult to figure out the object oriented methods that F#
       | depends on. It was the same thing with Clojure and Scala for the
       | JVM. I have zero interest in first learning C# or Java, just to
       | use those platforms.
        
         | netdevphoenix wrote:
         | you are not supposed to do oop in f#
        
           | 7thaccount wrote:
           | I'm aware, but you need to understand the .NET ecosystem to
           | get anything practical done (at least when I was using it in
           | 2017). All the books written on it (I own 3) are also the
           | same way and assume you're a skilled C# dev.
        
             | miloandmilk wrote:
             | 100% this, I spent many months going through the most
             | recent books on F# including one which the latest version
             | was only released last year I think.
             | 
             | They all seem to try and shield you from the fact that you
             | are much better placed if coming from C# (which everyone
             | seems to refer to as .net these days) and have a solid
             | understanding of the .net class library.
             | 
             | All the main web frameworks sit on top of asp.net and
             | pretty much all official documentation for that is in c#
             | 
             | Such a shame because I learnt so much about types from
             | trying to crack f# for real world application.
             | fsharpforfunandprofit taught me heaps which I apply to
             | other languages, but I don't want to become a c# developer
             | which comes with all the years of changing best practices
             | to be able to really be productive in f#.
             | 
             | Sorry if I am coming across as bitter but I just can't see
             | learning f# in isolation from c# which is an absolute
             | shame.
        
               | neonsunset wrote:
               | What is the issue with learning C# alongside it, if only
               | the bits necessary to improve the F# experience? Both are
               | excellent languages.
        
               | miloandmilk wrote:
               | They are both excellent languages, I just literally don't
               | have the time to commit to do that at the moment.
               | 
               | I think if I ever have time for another go I would learn
               | enough to be proficient in c# before diving back in.
        
           | genter wrote:
           | Except that there's a huge number of libraries written in C#
           | that are available to F# (since both run on the CLR), and you
           | have to do OOP in F# to use them.
        
           | hajile wrote:
           | F# depends heavily on existing C# libraries and those are all
           | OOP.
        
             | smoothdeveloper wrote:
             | One way to look at it, but consuming OOP libraries doesn't
             | turn code into OOP.
             | 
             | Also, FSharp.Core (which most F# code leans heavily on) is
             | not OOP at all.
             | 
             | F# promotes object programming, doesn't proscribe
             | mutability, encourages function and data approach.
             | 
             | It offers simple access to the different paradigms, with
             | some opinionated choices (e.g. preventing leaning on OOP
             | beyond an arbitrary stretch, like no "protected", only
             | explicit interface implementation, etc.).
        
           | shortrounddev2 wrote:
           | FP and classes are not mutually exclusive
        
           | zem wrote:
           | oop is just another tool in your toolbox; if f# provides it
           | and it's the best way to express a given algorithm you should
           | definitely go ahead and use it. oop got a bad name due to
           | people trying to shoehorn it into places it was not the best
           | way to express something, and it seems like you're making the
           | inverse mistake here.
        
           | ninalanyon wrote:
           | Why not? It does it very well, better than C# in my opinion.
           | At least that was the case ten years ago when I last used C#
           | and played with F#.
        
         | diggan wrote:
         | > It was the same thing with Clojure and Scala for the JVM. I
         | have zero interest in first learning C# or Java, just to use
         | those platforms.
         | 
         | FWIW, I managed to learn Clojure without knowing anything from
         | Java/JVM before diving into it. I did have plenty of JS
         | experience which made ClojureScript easier to pick up I
         | suppose, but Java works more or less the same as every other
         | Algol-like and/or OOP language out there so if you have any
         | previous experience with something like that, basic Java is
         | trivial to pick up even accidentally.
        
       | rockyj wrote:
       | I did try F#, but I was new to .NET ecosystem. For 1 "hello
       | world" I was quite surprised by how many project files and
       | boilerplate was generated by .NET, which put me off.
       | 
       | I am all for FP, immutable, and modern languages. But then where
       | are the jobs and which companies care if you write good code?
       | 
       | Now everyone wants languages which are easy to use with AI, while
       | reducing workforce and "increased productivity". I have been
       | programming for 20 years and know 4-5 languages, in India it was
       | worse but in EU at-least I can make a sustainable living by
       | writing Java / TypeScript. I cannot even find jobs with Kotlin +
       | TypeScript which pay well, forget getting jobs in Elixir /
       | Clojure / F# (there maybe a handful of opportunities if I will
       | relocate for around 70K/year). That is why I have mostly given up
       | on learning niche languages.
        
         | djha-skin wrote:
         | I learn them as a fun hobby, with no salary expectations. It
         | keeps the dream alive, and I learn a lot from the Common Lisp
         | community that I do use in my job.
        
         | owenm wrote:
         | I hear you on the opportunity side and I can't see that
         | changing. The good news is in recent releases there's a lot
         | less boilerplate - "dotnet new console -lang F#" results in two
         | files, a short fsproj file and a single line of Hello World.
        
         | afavour wrote:
         | Opportunities do exist, even when they're few and far between.
         | I learned Rust in my spare time because I was really interested
         | in it. Then we stumbled across something that would have really
         | benefitted from a cross platform library and lo and behold, I
         | got to use my Rust knowledge, even though the vast majority of
         | my day job doesn't use it.
        
         | neonsunset wrote:
         | As sibling comment pointed out, it's just .fsproj manifest and
         | Program.fs file. What boilerplate do you speak of? It's on the
         | opposite end boilerplate-wise to projects made in e.g. Java or
         | TypeScript.
         | 
         | For F#, projects are needed to make full applications or
         | libraries. Otherwise, you can simply write F# scripts with .fsx
         | and execute them via 'dotnet fsi {SomeScript.fsx}'.
         | 
         | (obviously you can also specify dotnet fsi as shebang and
         | integrate these scripts into general scripting on Unix systems
         | - it's very productive)
        
           | twodave wrote:
           | I suspect they were either referring to pre-.NET Core days
           | before the new project formats came out or they're creating
           | projects in Visual Studio and checking all the optional
           | boxes. There indeed did used to be a lot more required
           | boilerplate to get some code running. Now you can run a .NET
           | project quite nicely in VS Code with 2 total files.
        
             | shortrounddev2 wrote:
             | Well also if you're using Visual Studio it will generate
             | solution files as well, not just fsproj. I grew up doing
             | C/C++ so boilerplate project/IDE/make files as well as
             | build objects are something I expect to see. I think people
             | who work in primarily JIT'd/interpreted languages are used
             | to just having a directory tree full of source files and
             | having some CLI tool manage everything for them. Maybe a
             | dependency list file as well, but that's about it. Python
             | is like this, and javascript CAN be like this
        
         | 8s2ngy wrote:
         | I understand your perspective. I like to view niche languages
         | as a medium for learning. For instance, I enjoy using Rust in
         | my personal projects--even if many of these projects may never
         | be released--because the lessons on immutability, functional
         | programming constructs, and trait-oriented programming
         | significantly enhance my day-to-day work. Therefore, I believe
         | that learning niche languages, even in the absence of a robust
         | job market, is worthwhile.
        
           | jen20 wrote:
           | I'm not sure I'd call Rust a "niche language" any more
           | (perhaps in ~2018) - it's in common use across many big
           | technology companies.
        
             | homebrewer wrote:
             | It is extremely niche outside of this bubble.
        
               | vlovich123 wrote:
               | F# will likely remain niche forever. It's likely that
               | Rust will not given its growing and accelerating adoption
               | by Microsoft, Google and the Linux Kernel.
               | 
               | It just takes time to defeat the 40+ years of c and c++
               | dominance.
        
               | johnisgood wrote:
               | Personally I will always prefer C's simplicity to Rust's
               | complexity. Could be just me.
        
               | kstrauser wrote:
               | I find Rust vastly simpler than C. If the code compiles,
               | it's probably a valid expression of the business logic I
               | encoded. I might've screwed up that logic, of course, and
               | no language can prevent me from messing that up. I know!
               | Many have tried, and I've defeated them with my ability
               | to misrepresent my ideas! But at least with Rust, I'm
               | reasonably confident that the code will actually do the
               | thing I asked it to do. I'm never confident like that
               | with C until I've run it a few hundred times without
               | crashing.
               | 
               | (Yes, I'm familiar with the rich ecosystem around helping
               | devs not write crummy C. I worked at Coverity at one
               | point. If anything, that gave me enormous fear and
               | respect of the hoops you have to jump through to be
               | reasonably sure C code isn't completely broken.)
        
               | mmoskal wrote:
               | According to Stack Overflow developer survey [0] Rust is
               | at 12.5%, roughly a half of C# or Java and a quarter of
               | Python. Also more than twice Ruby. So definitely not
               | niche.
               | 
               | [0] https://survey.stackoverflow.co/2024/technology#most-
               | popular...
        
               | askonomm wrote:
               | In my mind not niche means having jobs, and Rust has no
               | jobs, not in any meaningful amount at least, and none at
               | all in most countries. That puts it deep in the niche
               | category for me.
        
               | sterlind wrote:
               | MS is starting to use Rust pretty extensively internally.
               | That's a lot of developers outside the "bubble."
        
         | sodapopcan wrote:
         | > But then where are the jobs and which companies care if you
         | write good code?
         | 
         | Oh man, that is poignant :( They always say they do in the job
         | description, but it always a different story once you get
         | there.
        
         | raphinou wrote:
         | It is possible to start your project with the script
         | possibilities offered by F# (as mentioned in the blog post). It
         | is absolutely a viable approach and I even blogged about it a
         | couple of months ago: https://www.asfaload.com/blog/fsharp-fsx-
         | starting-point/
        
         | shortrounddev2 wrote:
         | I like F#'s syntax when all you're doing is pure logic. But
         | when you have to interface with any IO like a database or REST
         | call or something, you have to abandon the elegance of ML
         | syntax and use these ugly computation blocks. In C# you can do
         | something like this:                   var post = await
         | _postService.getById(id);
         | 
         | in F# the equivalent is basically                   let
         | getPostById id = async {             let! post =
         | blogPostService.getPostById id             return post
         | }              let post = getPostById 42 |>
         | Async.RunSynchronously
         | 
         | But not really, because RunSynchronously isn't the same thing
         | as `await`. Realistically if you wanted to handle the result of
         | an async computation you would need to create continuations. F#
         | isn't the only ML-family language to suffer from this; Ocaml
         | does as well. It always seemed to me like the pattern with any
         | asynchronous operations in F# is to either:
         | 
         | 1. Do all logic in ML-syntax, then pass data into a computation
         | block and handle I/O operations as the last part of your
         | function, then return unit OR
         | 
         | 2. Return a C#-style Task<> and handle all I/O in C#
         | 
         | Either way, ML-style languages don't seem like they're designed
         | for the kind of commercial CRUD-style applications that 90% of
         | us find ourselves paid to do.
        
           | smoothdeveloper wrote:
           | In C#, you can't use the await keyword in a non async method,
           | so I find the argument short sighted.
        
             | shortrounddev2 wrote:
             | I don't see how that changes things. You'd have to async it
             | all the way to the top but the syntax is still cleaner than
             | F#. If you're using an Asp.Net controller you just declare
             | the handler as async Task<IActionResult> and it's fine.
             | Even program main methods can be async these days
        
               | malakai521 wrote:
               | The syntax is exactly the same. You have `var x = await`
               | in C# and `let! x =` in F#
               | 
               | The controller handler is also the same. It will be
               | marked with `async` keyword in C# and `task` CE in F#
        
               | shortrounddev2 wrote:
               | It's absolutely not exactly the same; let! is only
               | available within a computation block. If you want to
               | return some value from the computation block and return
               | to Functional land without having to pause the thread you
               | need to use a continuation, which C# has built in
               | syntactic sugar for in async/await and F# does not.
        
               | sparkie wrote:
               | `await` can only be used in an `async` function. How is
               | that so different from `let!` only being available in a
               | computation expression?
        
               | shortrounddev2 wrote:
               | because an async function doesn't require you to change
               | syntaxes to get them to work
        
               | Smaug123 wrote:
               | It's actually sort of the other way round. C# has
               | hardcoded syntax for async/await. F#'s syntax for
               | async/await is a fully-general user-accessible mechanism.
        
               | xigoi wrote:
               | A computation block is the equivatent of an async
               | function;
        
             | jayd16 wrote:
             | If your code base is already using async await it's really
             | not an issue.
        
               | int_19h wrote:
               | The point is that it's not actually different from C#,
               | especially once you consider that F# also has task{}
               | blocks that give you a .NET Task directly.
        
           | malakai521 wrote:
           | `var post = await _postService.getById(id);`
           | 
           | the F# equivalent is
           | 
           | `let! post = _postService.getById id`
        
             | alternatex wrote:
             | You're missing the task {} block
        
               | neonsunset wrote:
               | This assumes the context is already a task computation
               | expression, which is what you'd have in asynchronous
               | code.
        
           | cjbgkagh wrote:
           | F# is a big language, it is a ML multi paradigm language that
           | interoperates with C# so there is a lot of necessary
           | complexity and many ways to do the same thing. A strong
           | benefit of this is the ability to create a working functional
           | paradigm prototype that can iteratively be refined to a
           | faster version of itself by hot spot optimizing the slower
           | parts with equivalent highly mutable functions while staying
           | within the same language. Similar how one would use python
           | and C++ and over time replace the python code with C++ code
           | where performance is important.
           | 
           | For the specific case of C# use of await it is unfortunate
           | that C# didn't design this feature with F# interop in mind so
           | it does require extra steps. F# did add the task builder to
           | help with this so the 'await' is replaced with a 'let!'
           | within a task builder block.                 let
           | getById(id:int) : Task<string> = failwith "never"       let
           | doWork(post:string) : unit = failwith "never"       let
           | doThing() = task {          let! post = getById(42);
           | doWork(post); }
           | 
           | Alternatively the task can be converted to a normal F# async
           | with the Async.AwaitTask function.                 let
           | getPostById1(id:int) : Async<string> = async { return!
           | getById(id) |> Async.AwaitTask }       let
           | getPostById2(id:int) : Async<string> = getById(id) |>
           | Async.AwaitTask        let getPostById3 : int ->
           | Async<string> = getById >> Async.AwaitTask
        
             | neonsunset wrote:
             | It is best to just use task CE full-time unless you need
             | specific behavior of async CEs.
             | 
             | The author of the original comment, however, does not know
             | this nor tried verifying whether F# actually works
             | seamlessly with this nowadays (it does).
             | 
             | Writing asynchronous code in F# involves less syntax noise
             | than in C#. None of that boilerplate is required, F# should
             | not be written that way at all.
        
               | cjbgkagh wrote:
               | F# is a big language so I think it is to be expected that
               | beginners will not know these things. I don't think the
               | fix is to simplify F# we should just understand that F#
               | is not for everyone and that is ok.
        
               | neonsunset wrote:
               | This is perfectly fine, but I think it's better to be
               | unsure about specific language feature than confidently
               | state something that is not correct (anymore).
               | 
               | Personally, I'm just annoyed by never-ending cycle of
               | ".NET is bad because {reason x}", "When was this the
               | case?", "10 years ago", "So?".
               | 
               | Like in the example above, chances are you just won't see
               | new F# code do this.
               | 
               | It will just use task { ... } normally.
        
               | shortrounddev2 wrote:
               | I understand that you CAN do this, I'm saying that it
               | makes your code look like shit and takes away some of the
               | elegance of ML
        
               | neonsunset wrote:
               | Please stop insisting on this. Task CE exists since F#
               | 6.0 and handles awaiting the CoreLib Tasks and ValueTasks
               | without any ceremony.
        
               | cjbgkagh wrote:
               | Are you saying you prefer Ocaml to F# or C# to F#? Your
               | example was indeed inelegant but it is also poorly
               | designed as you take 4 lines to reproduce a function that
               | is already built in, people can poorly design code in any
               | language.
        
         | tester756 wrote:
         | >" I was quite surprised by how many project files and
         | boilerplate was generated by .NET, which put me off.
         | 
         | With which language are you comparing with?
         | 
         | Because there's afaik csproj and maybe .sln
         | 
         | and both of them are let's be frank - foundational for almost
         | all projects that arent just hello world.
         | 
         | Otherwise you end up with some cmakes or something similar that
         | want to achieve something similar
        
         | Foofoobar12345 wrote:
         | F# is quite usable with AI. All AI models are perfectly capable
         | of generating idiomatic F# code. In fact, because it has a nice
         | type system, if you ask the AI to model the problem well with
         | types before implementing, hallucinated bugs are also easier
         | caught.
        
           | elcritch wrote:
           | Same with Nim. It works surprisingly well with AI tools. I
           | think both have more straightforward syntax so it's easy to
           | generate. I'm curious how more complex languages do like C++
           | / Rust.
           | 
           | Last time I tried C++ with Copilot it was terrible.
        
       | pdimitar wrote:
       | People will do anything except actually try Elixir. :D
       | 
       | ...I mean: pipes, immutability, transparent mega-parallelism...
       | helloooo?
       | 
       | I tried F# some years ago (after I was fired from a shop that
       | decided they will go all-in on Java and F# and dropping
       | everything else overnight) and I was not impressed. I mean the
       | language is really nice but the C# baggage and runtime was just a
       | bit much. And I was not left convinced that immutability alone is
       | worth the switch. I suppose we can call F# an FP gateway drug?
       | 
       | Now arguably you get a runtime and some baggage from the Erlang
       | runtime (the BEAM VM, where Elixir also runs), but the guarantees
       | and features you get are invaluable, and have proven themselves
       | many times over the last literal three decades.
        
         | weakfish wrote:
         | The shop went all in on Java and F#? Why not C# and F#? That's
         | really odd, unless there's context I'm missing.
        
           | pdimitar wrote:
           | I wish they told me. They cut ties with most of their
           | previous devs overnight, as if we were some enemies. Weirdest
           | firing in my life and career to this day.
        
             | weakfish wrote:
             | That's truly bizarre. Glad you're out of that situation,
             | doesn't sound quite healthy from what you're saying.
        
         | BiteCode_dev wrote:
         | If one need to get on Beam, is it better to start on Elixir or
         | Gleam?
        
           | pdimitar wrote:
           | Elixir's ecosystem is much farther ahead than Gleam, so if
           | you want to actually achieve stuff without pauses to fill the
           | gaps yourself, then Elixir is the way to go.
           | 
           | And don't get me wrong, I love the idea of Gleam, a lot (Rust
           | syntax, strong static typing, what's not to love?). But my PL
           | early adopter days are over.
        
         | johnnyjeans wrote:
         | > Elixir
         | 
         | For me, it's Erlang. I just really like its horn clause syntax,
         | it's so clean and readable. I know a common complaint is lack
         | of piping (and even though you can implement it trivially, the
         | order of arguments for some functions makes it of dubious use)
         | but it's a small price to pay.
         | 
         | > I mean the language is really nice but the C# baggage and
         | runtime was just a bit much
         | 
         | This was my experience with F#. Frankly, I've never been happy
         | with my experience with CLI on Linux, and the toolchain
         | inherits a lot of baggage from its C# heritage. Microsoft's
         | toolchains have a very distinct workflow to them. F# has some
         | interesting aspects to it like active patterns (something I
         | wish was more common in the ML-family), but tbh I'm more than
         | happy with ocaml.
        
           | innocentoldguy wrote:
           | I can't remember which version of Erlang was the most current
           | when I started learning Elixir, but I do know that it was
           | years before OTP 20, which fixed its string issues. Prior to
           | that, Erlang didn't have very good string support for
           | internationalization (I do a lot of Japanese language
           | programming). Elixir, on the other hand, did. Otherwise, I
           | may have gone with Erlang back then.
           | 
           | I like Erlang a lot, too. Both are great languages.
        
         | xigoi wrote:
         | Elixir is dynamically typed, which presumably many people are
         | put off by.
        
           | pdimitar wrote:
           | Yes, I agree that it's a big drawback.
           | 
           | Elixir made me more productive and gave me back my love for
           | programming, and I work with it professionally for 9 years
           | now. But the lack of static typing is getting so irritating
           | that I started upping my efforts to get [even] better at Rust
           | lately.
           | 
           | So I agree. It's one of the very top drawbacks of Elixir.
        
       | pimbrouwers wrote:
       | Our shop converted 6 years ago, from C# to exclusively F#. I also
       | author and maintain some packages (falco, donald, validus and
       | others). The language is tough to learn if you're coming from a
       | C-style language. But worth the effort and experience. It's
       | extremely concise a true delight to build programs in that are
       | fast, robust and durable.
       | 
       | There are a few drawbacks, depending on your perspective:
       | 
       | - compilation is slower than c# and hot reload isn't supported
       | (it's in progress)
       | 
       | - there are very few opportunities to use it professionally
       | 
       | - hiring devs can be challenging
        
         | cogman10 wrote:
         | How does the typing system work for F#?
         | 
         | From the article, it looks like it's mostly dynamically typed.
         | Or is it inferred? Or is it something else?
         | 
         | Like, if I write                   let hello value =
         | print value                  hello "world"         hello 2
         | 
         | Does that just work?
         | 
         | To me, that'd be a point that might steer me away from the
         | language. Deducible types seem vital to larger and long lived
         | projects.
        
           | neonsunset wrote:
           | F# is a statically typed language with gradual typing and
           | full type inference.
           | 
           | Given                 let hello value =           printfn
           | "%A" value                hello "world"       hello 2
           | 
           | The binding "hello" has "'a -> unit" signature where 'a is a
           | generic argument it accepts because the "printfn" binding
           | with a given format specifier is generalized the same way and
           | an unconstrained 'T (here 'a) is the most narrow type
           | inferred for "hello".
        
           | Nelkins wrote:
           | It's statically typed and inferred.
           | 
           | With regards to your example, the print/printfn (equivalent
           | of Write/WriteLine) functions are a bit funny in F#. They
           | don't actually take bound string values directly. You need to
           | specify the type (which could be a string, a number, obj,
           | etc)
           | 
           | https://learn.microsoft.com/en-us/dotnet/fsharp/language-
           | ref...
        
         | z5h wrote:
         | As a proficient Elm developer with industry experience, I'm
         | wondering what are the biggest challenges in hiring devs? Is it
         | the paradigm, learning the ecosystem, lack of interest? Are you
         | currently hiring?
        
           | Akronymus wrote:
           | As someone who quite likes f#: It seems like a chicken and
           | egg problem, not many companies doing f# because not many
           | devs know it and not many devs learning it because not many
           | companies are doing it.
           | 
           | I certainly wish I were doing f# professionally, but I only
           | ever found 1 job listing for it, and that was in vienna while
           | I am located like 200km away from it :(
           | 
           | Speaking of elm: I really like elmish for the frontend, when
           | I need to make a dynamic page in the first place. Maybe that
           | could be to your interest? (It transpiles to react under the
           | hood via fable, which you can webpack into a drop in bundle.
           | But I digress)
        
         | Foofoobar12345 wrote:
         | Hiring devs is perfectly fine if you don't look for F# skills -
         | just hire generally smart people, and allow them 1-2 weeks to
         | get comfortable with F#. Make them just solve problems from
         | project euler or something.
         | 
         | For those who have already done functional programming, they
         | wont take more than 2 days to start getting productive. For
         | those who have written a lot of code, it will take them ~2
         | weeks to pick up functional thinking.
         | 
         | Anyone who is still uncomfortable with F# after 1 month - well
         | that's a strong signal that the dev isn't a fast learner.
         | 
         | Additionally, I've never had anyone reject our job offer
         | because we do F#. I'm sure a whole bunch of people might only
         | be looking for python or javascript jobs, but that's fine
         | because I'm not looking for them. I always have more people who
         | I want to hire but I can't due to budget constraints.
         | 
         | Source: direct experience - I run a pure F# company with a team
         | size of ~80.
        
           | pimbrouwers wrote:
           | Hi Isaac ;) Of course you can train people. But in my
           | experience they take a lot longer to learn than you suggest.
        
       | GiorgioG wrote:
       | As a 20+ year C# developer I've tried several times to learn/use
       | F#. Despite being interested in FP, my brain is having trouble
       | figuring out how to structure my code in F#. In C# I'd either
       | build a service (or use the mediator pattern) for the domain and
       | a repository for data access. With F# it's functions all the way
       | down and it feels unnatural (as silly as that may sound).
        
         | jcmontx wrote:
         | The secret is currying. Replace your DI for currying and you'll
         | start to see somewhat similar patterns
        
           | Smaug123 wrote:
           | By the way, I consider
           | https://www.bartoszsypytkowski.com/dealing-with-complex-
           | depe... to be the canonically correct way to do DI when you
           | want to inject more than like two dependencies.
        
         | Akronymus wrote:
         | along with what jcmontx said: F# is structured bottom from top.
         | As in you can't reference something that is later defined
         | earlier. I find that naturally leads to getting a decent enough
         | structure "for free" because it forces you to have your basic
         | functionality early on and build on that later.
         | 
         | That also, IMO, makes untangling/splitting up parts of the
         | codebase easier as well.
        
         | MrMcCall wrote:
         | That makes sense when one is used to the Visual Studio
         | organization of solutions and projects, with some main method
         | somewhere being the entry point, unless it's a WCF service or
         | somesuch that gets run via a service manager.
         | 
         | I only used F# at its command line, fsi.exe, to give me
         | commandline access to .NET for exploration, testing, and
         | munging data. Over time, I built up quite a library of usable
         | functions that I'd have the fsi.exe program pre-load when I
         | kicked it off, leaving me at the prompt with all .NET
         | namespaces and my code ready and accessible.
         | 
         | Once you get access to your database's data, it's easy to write
         | queries against it and then play with the data. I could then
         | port the F# processing bits that worked into my C# projects as
         | necessary, but it was far easier to do it that way than to
         | write the logic deep within complex multi-project solution
         | files, where the various classes are spread throughout the
         | projects' files.
         | 
         | I also just really enjoyed using F#.
        
       | gwbas1c wrote:
       | > Why F#?
       | 
       | I'm kinda wondering if anyone here with decent C#/.net experience
       | can give their version of the answer?
       | 
       | ---
       | 
       | The article really didn't answer its own question. It basically
       | says "How" instead of "Why"...
       | 
       | ...Which as someone who's spent over 20 years in C#, and tends to
       | advocate for "functional" style, leaves me with more questions
       | than answers!
        
         | kowalgta wrote:
         | I've worked with .net professionally for almost 20 years. At
         | the beginning with C# while last decade almost exclusively with
         | F#.
         | 
         | F# is just a better language. Simpler, more concise, more
         | readable with stronger type safety. I will never go back to
         | writing C# as I'm finding it too frustrating at times and
         | unproductive.
        
         | malakai521 wrote:
         | A nicer, cleaner and simpler syntax, superior pattern matching,
         | active patterns, discriminated unions and computation
         | expressions
        
           | int_19h wrote:
           | C# has the equivalent of active patterns these days.
        
             | malakai521 wrote:
             | It does not
        
         | Foofoobar12345 wrote:
         | Everything is an expression (i.e. its an actual functional
         | programming language), and along with it comes a different way
         | of thinking about problems. Coupled with a really good type
         | system which has discriminated unions, you'll have much fewer
         | bugs.
         | 
         | Pro tip: don't write F# like you would write C# - then you
         | might as well write C#. Take the time to learn the functional
         | primitives.
        
           | arwhatever wrote:
           | if I may elaborate on "everything is an expression," F#
           | allows you to do things like (with apologies for being a tad
           | rusty with the syntax)                 let bar =
           | if foo then                7             else
           | 11
           | 
           | or                 let bar =            try             //
           | code that might throw             7           with ex ->
           | 11
           | 
           | and will ensure that both/all code branches return a
           | compatible type for the `let` binding.
           | 
           | Whereas in C# you have to do like                 int bar;
           | if (foo) {          bar = 7;       } else {          bar =
           | 11;       }
           | 
           | And C# will let you know if you omit the `else` on accident
           | ...
           | 
           | Except that most C# developers do                 int bar =
           | 0; // or some other default value`
           | 
           | to get the red squiggly to go away while they type the rest
           | of the code, unknowingly subverting the compiler's safety
           | check.
           | 
           | This doesn't seem like a big deal given these examples. But
           | it becomes a much bigger deal when the if/else grows super
           | large, becomes nested, etc.
        
       | gwbas1c wrote:
       | If you've had C# and F# co-exist in the same codebase, how do
       | they co-exist? Is it like C# and VB.Net where a project (dll) is
       | either C# or VB.Net, and they can reference each other?
       | 
       | Or: Is it more like the Swift / Objective C ecosystem where
       | Swift, Objective C, and even straight C can co-exist in the same
       | library?
       | 
       | In a mixed C# and F# codebase, generally when do you favor C#
       | versus F#?
       | 
       | Coming from a C# background, what are the areas where F# is a
       | better language?
       | 
       | Any success stories for F#, especially if it co-exists with C#?
       | Any horror stories?
        
         | neonsunset wrote:
         | You have likely heard "functional core, imperative shell". This
         | refers to having IO-heavy code that favors imperative patterns
         | be written in C# and then have the actual domain logic core
         | written in F# which is much better at expressing it. Because
         | both languages are hosted on .NET, you simply achieve it by
         | having two projects and having one reference another. It is
         | very seamless F# and C# types are visible to each other if
         | marked to be so.
         | 
         | The biggest advantage of F# is its gradual typing and full type
         | inference which allows to massively reduce the amount of text
         | required to describe application or domain logic. It is also
         | extremely composable and I find doing async in F# somewhat
         | nicer than in C# too. F# also has better nullability (or,
         | rather, lack of thereof) assurances and, in my opinion, better
         | UX for records.
        
           | gwbas1c wrote:
           | That's just like how C# and VB.Net can co-exist in the same
           | project. Would you pick the pattern of:
           | 
           | 1: C# Library with interfaces and/or abstract base classes
           | 
           | 2: F# library with implementations of those interfaces and
           | base classes
           | 
           | 3: C# _program_ (console, web service, GUI, ect) that
           | specifies the implementations in Dependency Injection
           | 
           | Or is there a simpler way for C# and F# to co-exist in the
           | same project (dll or exe)?
        
             | int_19h wrote:
             | You don't really need to split 1 & 2, since F# can define
             | .NET interfaces and abstract classes just fine.
             | 
             | For that matter, you don't even need the interfaces if you
             | wouldn't have had them in a C#-only solution. Just define
             | the class in F# and use it directly from C#.
             | 
             | You still need a separate assembly for F#, but that doesn't
             | imply dependency injection - again, just reference it and
             | use it.
        
               | gwbas1c wrote:
               | I've identified a possible use case for F# in a
               | preexisting product; I'm looking for the simplest way to
               | integrate F#.
        
               | Lanayx wrote:
               | F# excels in writing domain logic where main domain
               | entities are defined as records and discriminated unions
               | and logic is written in pure functions. Given that
               | product is preexisting and domain entities must already
               | be defined, I wonder what use case do you have in mind?
        
         | debugnik wrote:
         | Yes mixing is just like with VB.NET.
         | 
         | When mixing, you often write business logic as self-contained
         | F# libraries with a C#-friendly API; and use C# to integrate
         | them with whatever imperative, reflection-heavy and DI-heavy
         | frameworks .NET is promoting the current year, since those are
         | filled with interop edge cases for F# anyway.
         | 
         | You really want to avoid a language sandwich though (e.g.
         | C#/F#/C#), because you'll keep wishing to remove the middle
         | layer. Sadly, the addition of source generators make this
         | mistake even more appealing.
        
       | phplovesong wrote:
       | Last time i tried F# i got bit by the weird concurrency story.
       | There was async/task and somwhow they did not play well together.
       | Also the dev tooling (for vim) was subpar, compared to ocaml
       | (lsp). Compile times also was on the slower side.
        
         | neonsunset wrote:
         | If you use task { } CE's you will get really good UX (it is
         | recommended to use them over async CE's). They were introduced
         | in F# 6.0 to address outstanding interoperability issues. As of
         | now, writing asynchronous code is more convenient than C#
         | (which is more convenient than Go or other languages which are
         | less expressive w.r.t. writing highly concurrent code).
        
         | 110bpm wrote:
         | `async` is F#'s original implementation of async programming.
         | It is the precursor to C#'s await/async.
         | 
         | `task` targets the .NET TPL instead, which is also what C#'s
         | await/async and all of .NET *Async methods use.
         | 
         | While the `async` implementation still offers some benefits
         | over `task` (cold vs. hot starts [0]), my advice is - if you're
         | doing backend code on .NET, you should use task. The tigher
         | integration with the .NET ecosystem & runtime results in better
         | exception stack traces, easier debugging and faster
         | performance.
         | 
         | [0] https://github.com/TheAngryByrd/IcedTasks?tab=readme-ov-
         | file...
        
       | twodave wrote:
       | In the case of F#, the use cases are diminishing with every new
       | C# release, since C# is getting better and better at the things
       | F# is supposed to be strong at (record types, pattern-matching,
       | etc.). Better to write the thing in C# using modern features of
       | the more popular and capable language.
        
         | marcosdumay wrote:
         | You may start to get a point when C# gets a two-directional
         | type inference system. As it's now, any functional-looking code
         | requires so much boiler plate that it's shorter and less bug-
         | prone to copy your functions code everywhere you want to use
         | them.
        
           | int_19h wrote:
           | Can you give an example of said boiler plate?
        
         | arwhatever wrote:
         | Unions remain the killer F# feature missing from C#.
         | 
         | Also, basic object initialization in C# has turned into a
         | nightmare with recent versions. You need a flowchart to select
         | among the 18 syntax options which suite your current needs.
         | 
         | With F# (and other newer languages), record fields are either
         | `T` or `T option`. No need to worry about whether the value
         | needs to be computed in a constructor and then remain
         | immutable, whether it needs to be initialized by an object
         | initializer and/or a constructor or not, whether it needs to
         | remain interior-ly mutable throughout the life of the record,
         | and so on. (Although as I recall you do still need to consider
         | null values assigned to non-nullable references in your F# code
         | that consumes C#.)
        
       | fud101 wrote:
       | I want to ask a weird question. I'd love to learn ASP.net but i
       | can't bring myself to deal with Microsoft Windows and their tech.
       | Is F# a way for me to learn enough NET to make some money?
        
         | jcmontx wrote:
         | I'm .NET dev and haven't touch a windows device since 2019.
         | Work on Mac, deploy to Linux.
        
         | CharlieDigital wrote:
         | I am also a C# dev and haven't worked on a Windows machine in 5
         | years.
         | 
         | C# and F# both work fine with Rider or VS Code on Mac or Linux.
        
         | lunarlull wrote:
         | > i can't bring myself to deal with Microsoft Windows and their
         | tech
         | 
         | Even in a VM? Why not?
        
       | systems wrote:
       | The problem with F#, Clojure and Elixir (hosted languages)
       | 
       | For F# , you need some basic C# knowledge For Clojure, you need
       | some basic Java knowledge For Elixir, you need some basic Erlang
       | knowledge
       | 
       | I like all 3 languages but usually each vm have a primary
       | language, and each hosted language eventually become hosted on
       | that primary language not the vm
       | 
       | I understand that for many task simple, to medium complexity, you
       | might not need that, but it seem as you try to be more advanced
       | you hit the wall of having to learn you host vm primary language
        
         | skrebbel wrote:
         | > For Elixir, you need some basic Erlang knowledge
         | 
         | As an Elixir programmer, this does not resonate. Basically the
         | only thing I've ever felt I needed to understand Erlang for was
         | ets, but let's be honest, that's not really proper Erlang but
         | just the terrible ets query syntax. And all this requires is
         | "ability to read enough erlang term syntax to be able to
         | understand the ets manual". I don't think I could write a
         | single line of correct Erlang by heart.
         | 
         | I feel like that's different in F#, where you still need to
         | know lots of .NET internals which are all documented in C#y
         | terms with C# examples etc. Elixir wraps pretty much all good
         | Erlang/OTP internals in nice Elixiry modules, which solves that
         | quite nicely.
         | 
         | Elixir has its warts but this really isn't one of them.
        
           | graemep wrote:
           | Thanks. I know a bit of Erlang (put some effort into
           | learning, but never used it in real life, probably forgotten
           | what I learned) and want to learn Elixir which seems better
           | suited to what I want to do in the short to medium term.
        
         | graemep wrote:
         | Erlang is not a difficult language. Unusual, but actually quite
         | sane syntax. If you are already familiar with Elixir it would
         | probably be pretty easy to learn the basics of Erlang.
        
         | innocentoldguy wrote:
         | I worked with Elixir for over five years without knowing
         | anything about Erlang. I know Erlang now, but only because I
         | was interested in learning it, not because I needed to do so to
         | write Elixir code.
        
       | nudpiedo wrote:
       | Same as many, I had wonderful experience with F# in the past, I
       | would use it again if:
       | 
       | - fable would 100% detach from dotnet - keeps up yo the LLM rush,
       | specially vibe coding on cursor
       | 
       | Last LLM experience it generated obsolete grammar (not much but a
       | bit).
       | 
       | Such la gauges are key for vibe coding experience and modeling.
        
       | aaronmu wrote:
       | I've been using F# professionally for the past seven years across
       | different contexts. First in a small software shop and now while
       | bootstrapping a SaaS company. Some observations:
       | 
       | * It's easier to attract smart developers to an F# project than
       | to a [mainstream language] project. This was one of my driving
       | beliefs when I introduced F# seven years ago.
       | https://www.paulgraham.com/pypar.html. This is probably just as
       | true for languages like Elixir, Clojure, ... But F# is what we
       | went with.
       | 
       | Small Software Shop Context
       | 
       | * We operated in a small market where customers eventually
       | dictated our tech stack (.NET & React). In that market, F# was a
       | major advantage--it allowed junior developers to build apps that
       | "just worked" with minimal regressions. Even with mediocre code
       | quality, I felt confident that we could refactor safely at any
       | time.
       | 
       | * I constantly had to justify F# to clients, which was
       | exhausting. We always delivered decent results, so it worked out,
       | but my partners were never as confident in defending F#.
       | 
       | Bootstrapping a SaaS Company
       | 
       | * F# has been invaluable for shipping features quickly and taking
       | shortcuts when needed.
       | 
       | * Three years in, our codebase is large and contains its fair
       | share of messy parts. But we can still develop new features at
       | high speed with minimal regressions. Refactoring is relatively
       | safe and straightforward.
       | 
       | * Compilation speed is the Achilles' heel. If you don't monitor
       | it, the compiler slows down to the point where it impacts
       | productivity. Earlier this year, waiting over a minute for
       | feedback after a small change became unbearable. A lot of our
       | "clean-up" work focuses on optimizing compilation times. We're
       | still learning, but we're optimistic that we can restructure the
       | project to significantly improve build performance.
       | 
       | EDIT: maybe one more point. I see a lot of C# vs F# popping up
       | here. Yes, C# has all the features that F# has. But do not
       | underestimate how well designed F# is. It is an extremely simple
       | language to learn compared to C#. There is a very limited amount
       | of keywords to learn. And they compose extremely well. If you
       | learned F# 7 years ago, took a break, and came back today, you'd
       | simply write the same boring code that you would have written 7
       | years ago. And along the way you'd find out that some things have
       | gotten a bit nicer over time.
        
         | GiorgioG wrote:
         | As a 20+ year C# dev...where do I learn how to structure apps
         | in F#? In C# my ASP.NET Controller might use a service (or a
         | mediator) to execute some domain logic and that in turn will
         | use a repository pattern (or EF DbContext) to update/query a
         | database. How are dependencies injected in? It seems like there
         | are multiple ways of going about it, but I don't have enough
         | knowledge of F# to know 'the proper way' to do it.
        
           | JohnyTex wrote:
           | The situation is a bit more complex in F# than C#, as there
           | are multiple ways to do it. Scott Wlaschin has a good
           | overview post about it here:
           | 
           | https://fsharpforfunandprofit.com/posts/dependencies/
           | 
           | FWIW you can do it exactly the same way you do it in C#; it's
           | not "wrong", it might just feel a bit out of place.
        
         | nickpeterson wrote:
         | I'll add that features isn't really a constructive way to think
         | about the differences between C# and F#. C# has more 'features'
         | than most other programming languages. One of the core features
         | of F# is less features and churn. Also, I really appreciate the
         | way F# maintainers agonize over how to maintain the language
         | and keep it coherent. You don't get the feel they're chasing
         | features at all.
        
       | loxs wrote:
       | I tried F# some years back when I was searching for a language to
       | port my OCaml project in... It felt too much .NET-y and too much
       | MicroSoft-y. And back then .net for linux had just been released
       | and was somewhat unpolished.
       | 
       | It seemed that I had to learn C# in order to use F# properly and
       | it seemed that porting it to C# was the saner option. I went with
       | Rust after all and it seems to have been the right choice.
        
         | airstrike wrote:
         | This rings true to me as well. I'm not sure what I get out of
         | F# that I can't get from Rust, unless you specifically want
         | .NET, which I don't.
        
       | froggertoaster wrote:
       | Coming from a .NET developer - why NOT F#?
       | 
       | * Network effect, or lack thereof. Very few people use it. * Its
       | nature is contrary to the ecosystem. The CLR is fundamentally
       | resistant to the paradigms that F# creates.
       | 
       | Wonderful little language - one of my favorites - and we owe a
       | lot to it for the great features that C# has. But it just hasn't
       | picked up the critical mass it needs.
        
       | jonsagara wrote:
       | The killer feature for me is type providers. I need to read a lot
       | of CSV files of varying formats, and the CSV Type Provider lets
       | me make quick work of them in a type-safe manner.
       | 
       | https://fsprojects.github.io/FSharp.Data/library/CsvProvider...
        
         | Hojojo wrote:
         | Wow, that sounds awesome. I'm jealous.
        
       | raphinou wrote:
       | F# was for me the best functional language when I looked at
       | rewriting a Ruby on Rails app. I wanted to go with a functional
       | language, as it seems to better fit my thinking and reasoning,
       | and I looked at Haskell, Ocaml, Scala, F#.
       | 
       | Being a stranger to Microsoft technologies, F# was the least
       | likely to be chosen, but easily became the first choice.
       | Haskell's purity made it hard to adopt (for me), Ocaml's
       | ecosystem is subpar (there wasn't even a clear choice for a
       | library to interact with postgresql, I couldn't install the
       | latest version due to its reliance on an obscure tool whose name
       | I forgot and didn't get help on the forum), and Scala is seems
       | complex....
       | 
       | F# was surprisingly easy to get started with. The community is
       | mis-managed by a corporate-minded approach (requiring people to
       | become member of the F# software foundation to get access to the
       | official slack!), but its members are friendly, smart and ready
       | to help. The ecosystem is great with access to all the dotnet
       | libraries (some complain there's a mismatch as most of those are
       | developed for use with C#, but I rarely got in trouble for using
       | them).
       | 
       | There are also great libs and frameworks available. Like
       | https://github.com/SchlenkR/FsHttp to easily interact with http
       | servers, to the point that I find it easier to use than a
       | dedicated library. Or https://github.com/CaptnCodr/Fli , to run
       | commands. And last but not least, https://www.websharper.com/ is
       | the best web framework I have encountered across all ecosystems.
       | Their reactive approach to web ui really allows me to develop
       | complex interfaces in a maintainable way.
       | 
       | This became a longer message than I thought, probably due to my
       | enthousiasm for the language. For complete transparency, the
       | situation is not perfect, and in my experience the tooling is not
       | the best.
       | 
       | If you want more info, I blogged about it a couple of months ago:
       | https://www.asfaload.com/blog/consider-fsharp/
        
         | bozhidar wrote:
         | Great story! Thanks for sharing it!
        
         | kqr wrote:
         | Curious since you don't expand on it on the blog: in what way
         | did Haskell's purity make it difficult to you?
         | 
         | Having used Haskell in production for a bit now, I don't even
         | notice its purity. Most functions are in some kind of I/O
         | context making it similar as other languages, except with the
         | option of running without I/O capabilities for functions that
         | shouldn't need it.
        
           | raphinou wrote:
           | I honestly don't remember as it was +/-6 years ago. I had
           | started learning Haskell and got to that conclusion. Maybe
           | that I am now more versed in FP I would arrive at another
           | conclusion? I don't know.
           | 
           | Another thing that was hard to grasp for me were the special
           | operators like =<<, ., $, etc. I was using Xmonad, but those
           | operators create a barrier to understanding exactly what
           | happened in the file.
           | 
           | In the end, F# was in my (personal) experience much more
           | approachable, and it let me learn the functional concepts
           | along the way.
        
           | giraffe_lady wrote:
           | You gotta remember people are often picking languages based
           | on what they can easily find out about it and
           | extrapolating/guessing about what problems they'll run into
           | with their expected use.
           | 
           | A few years ago on here I had an interesting conversation
           | with someone who wasn't going to use rescript for something
           | because they didn't like how it handled object types. I can't
           | remember ever using an object type in rescript; we all just
           | convert js objects to record type in the extern binding. But
           | that's not information easily available to someone who has
           | never used the language.
           | 
           | Same thing here I think. If you don't already have
           | familiarity with this paradigm, it's hard to imagine what
           | using an IO monad for side effects is like. It's not easy to
           | tell how hard it'll be to learn it, how much it may affect
           | the rest of your code, etc. It's easy to imagine someone
           | (shit even me a few years ago) going "eh I'll take the
           | language with the big easy escape hatches just in case."
        
           | internet_points wrote:
           | For me, Haskell's image and ideal of purity are what made it
           | difficult when I started out. I tried learning the language
           | by reimplementing a program I'd previously done imperatively,
           | that was (in hindsight) obviously hard to do in a plain pure
           | way, ended up learning about zippers and knot-tying to do
           | something in a less efficient and more confusing way than
           | just using something like STArray because I had this idea
           | from reading about Haskell that this was not only a good way
           | to do things, but would be magically fast because GHC. (It
           | was not.)
           | 
           | These days I'd just do such a task more-or-less imperatively
           | in Haskell, and I would be well guided by the types in doing
           | so. But I also feel like you have to make a few such mistakes
           | if you want to get a good intuition and taste for when it's
           | good do things purely and when imperatively.
        
         | mike1o1 wrote:
         | There was a large group of folks that left Ruby on Rails for
         | Elixir (even has a similar looking syntax), yet it wasn't on
         | your list of languages to consider. Just curious, was there a
         | particular reason?
        
           | raphinou wrote:
           | I should have mentioned in the message, but I was looking for
           | a strongly typed language. I was an avid-user of dynamically-
           | typed languages, but that particular Ruby on Rails app became
           | unmaintainable, and part of the culprit was due to the
           | dynamic typing. I hoped that using a statically typed
           | language would make it easier to maintain a complex app in
           | the long term. And I must say that it totally materialised,
           | to the point that I don't want to develop in dynamically
           | typed languages anymore.
           | 
           | Here's an example: as I said in my original message, I was a
           | complete stranger to the dotnet ecosystem, and I learned the
           | F# language at the same time. And I decided to develop the
           | app as a library project to be used by the web app. I
           | completely missed the prevalence of the async approach in the
           | dotnet, and all my code was synchronous. One day, about half-
           | way in the project, I realised I needed to switch to async
           | code. Had this happened in a dynamically typed project, it
           | would have been hell for me. Maybe it's me that can't grasp a
           | project well enough, but I need the type-guardrails to find
           | my way in large refactorings. And with the strong types,
           | large refactorings can be done confidently. They don't
           | replace tests, but make the refactoring process much more
           | smooth.
           | 
           | The app is open source and its code is at:
           | https://gitlab.com/myowndb/myowndb It doesn't have a lot of
           | users, not the least due to lack of marketing and polishing
           | the user experience. But I am satisfied of what I learned
           | developing it!
        
             | tasuki wrote:
             | These days there's Gleam[0], as a strongly typed
             | alternative for the BEAM virtual machine. Of all the
             | languages I haven't used yet, it seems to hit the safe +
             | minimalistic + productive sweet spot the best. (Yes the
             | C-inspired syntax is slightly off-putting, but syntax is
             | the least important aspect of a language.)
             | 
             | [0]: https://gleam.run/
        
               | raphinou wrote:
               | I am also keeping an eye on gleam! I also regret that
               | they left the ml syntax behind, but as you say it
               | shouldn't be a blocking factor. If they adopt computation
               | expressions and make otp a priority it would probably
               | come beside fsharp in my toolbox!
        
               | neonsunset wrote:
               | Gleam, much like any language which primarily targets
               | BEAM, is slower by an order of magnitude or two when
               | compared to F#.
        
               | no_wizard wrote:
               | The appeal is the runtime model. I can't readily verify
               | if BEAM languages are meaningfully slower or really
               | slower at all but let's take the premise for the sake of
               | argument.
               | 
               | Even if is slower, the runtime model is incredibly
               | resilient and it's cheap to scale up and down, easy to
               | hot update, and generally does asynchronous work
               | extremely well across a lot of different processes.
               | 
               | F# has really good async ergonomics but it doesn't have
               | the same task/processing flexibility and Websockets are
               | kind of a pain compared to elixir or even erlang
        
             | DonaldPShimoda wrote:
             | This is a really minor point, but "strongly typed" and
             | "statically typed" are not interchangeable terms. In the
             | context of your comments here, you are exclusively
             | interested in the static nature of the type system, rather
             | than anything about the "strength" of it (which is
             | something totally different and inconsistently defined).
        
               | raphinou wrote:
               | You are absolutely right. Thanks for pointing it out.
        
               | DonaldPShimoda wrote:
               | Sure thing. Cheers!
        
         | breadwinner wrote:
         | Apache Spark, Delta Lake are written Scala. Being JVM based, it
         | has a large ecosystem. Scala seems like a better choice than
         | F#.
        
           | raphinou wrote:
           | I'm sure it can be the better choice, but for me it was not.
           | It seems there was some incompatibility between me and Scala.
           | I find it such a complex language and I never managed to wrap
           | my head around it. As I said F# was my last choice at the
           | start of my evaluation, and Scala was high on the list due to
           | the Java ecosystem. But in the end it didn't work out for me.
           | 
           | F# on the JVM would be great though!
        
             | flakiness wrote:
             | Is F# easier to learn than Scala? (I know a bit of Scala
             | (in the old 2.x days) but have no knowledge of F#.)
        
               | raphinou wrote:
               | It definitely was for me! The syntax is simple, it is
               | functional first but is not pure. I started with zero
               | experience with ml languages and got productive fast
               | enough to enjoy it. Of course my early f# code could be
               | improved, but it was working and while writing the code
               | the language didn't feel like a barrier.
               | 
               | One caveat though: it seems FP matches my way of
               | thinking. As an example, I always liked recursion, while
               | some others saw it as complexifying things.
               | 
               | Try fsharp as fsx scripts to avoid boilerplate (see blog
               | post linked in other comment) and you'll rapidly feel if
               | you like it or not.
        
               | neonsunset wrote:
               | At least the tooling should be way nicer. It is way more
               | of an OCaml language than Scala. Also much like having to
               | deal with JVM ecosystem in Scala, you'd need to deal with
               | .NET ecosystem in F#. In my opinion, the latter can be an
               | advantage. F# has a lot of depth but you do not need to
               | grasp it fully to be productive with it.
        
               | ecshafer wrote:
               | I have done a bit of both Scala and F#, I think F# is a
               | good bit easier to learn. Scala I think mixes OOP
               | concepts and mutability in a bit less gracefully.
        
               | spooneybarger wrote:
               | It was for me.
        
             | frakt0x90 wrote:
             | I agree with you. I tried Scala for weeks and found it far
             | too complex. Every line I wrote, I felt there were 5
             | different ways of doing it and I didn't know if I was
             | choosing the right one. Scala tries to be too many things
             | at once imo.
        
             | hurril wrote:
             | It runs on .NET, for god's sake. This is not a small
             | platform.
        
               | michaelcampbell wrote:
               | Basically everything runs on an OS, which is even more
               | complex.
        
             | michaelcampbell wrote:
             | Is Frege still being developed?
        
           | innocentoldguy wrote:
           | I think Clojure is the better option if you want to do FP
           | using the JVM ecosystem. The problem (for me, anyway) I've
           | run into with Scala is that it supports both functional
           | programming and object-oriented programming. Every code base
           | I've worked on in Scala has ended up being a hodgepodge of
           | both, which I find annoying.
           | 
           | However, the best functional programming language is, of
           | course, Elixir. :D
        
             | raphinou wrote:
             | Elixir getting a strong type system is interesting, but
             | watch out for gleam though
             | 
             | But they still miss the computation expressions, which open
             | interesting possibilities like
             | https://github.com/CaptnCodr/Fli and
             | https://github.com/fsprojects/FsHttp
        
               | innocentoldguy wrote:
               | Gleam lacks lisp-style macros, and its implementations of
               | BEAM and OTP are not exhaustive. For example, Gleam does
               | not support:
               | 
               | - Hot updates.
               | 
               | - Full distributed system support.
               | 
               | - Low-level process manipulation.
               | 
               | - Named processes.
               | 
               | - Advanced supervision strategies.
               | 
               | - Behaviours other than GenServer.
               | 
               | - Type-safe distributed messaging.
               | 
               | - And several other things that I value in BEAM and OTP.
               | 
               | I can't justify trading the full power of BEAM and OTP
               | for static typing. To be fair, though, I've written a lot
               | of code in both statically and dynamically typed
               | languages, and static typing isn't something I value much
               | (to the point that you might say I don't care about it at
               | all :D).
        
               | raphinou wrote:
               | I knew otp was still suboptimal in gleam, but thanks for
               | mentioning all these additional points!
               | 
               | Funny how preferences and priorities vary among devs, I
               | need my static type system! :-) But note even in static
               | type systems there are variations. I'm talking about an
               | hindley milner type system with its type inference like
               | the one in fsharp
        
             | dkarl wrote:
             | > Every code base I've worked on in Scala has ended up
             | being a hodgepodge of both
             | 
             | Is there something about that that has bothered you?
             | Working in Scala codebases, I've found the best ones to
             | work in are the ones that embrace Scala's multiparadigm
             | nature. When programmers try to solve every problem with
             | OO, they end up adding more and more layers to get the job
             | done. When programmers try to solve every problem with FP,
             | they end up resorting to sophisticated techniques that are
             | unapproachable for other engineers. I think the simple
             | parts of OO and the simple parts of FP go much, much
             | further together than simple OO or simple FP can go by
             | themselves. Have you seen something different?
        
             | michaelcampbell wrote:
             | Isn't Clojure similarly (or even moreso) multiparadigm?
        
         | Lanayx wrote:
         | For reference, F# slack is already dead, community has moved to
         | Discord https://discord.com/invite/fsharp-196693847965696000
        
       | shermantanktop wrote:
       | > Trivia: F# is the language that made the pipeline operator (|>)
       | popular.
       | 
       | I'm not a dabbler in exotic languages, so this definition of
       | "popular" was puzzling. I've literally never seen that operator
       | before. Maybe I need to get out more.
        
         | zdragnar wrote:
         | It exists in several similar languages such as elixir, and was
         | even a proposal for ecmascript, but never really got traction.
        
           | sundarurfriend wrote:
           | I'm familiar with it via Julia, and I believe recent versions
           | of R also have it.
        
           | WorldMaker wrote:
           | It made it to Stage 2, which is _some_ traction:
           | https://github.com/tc39/proposal-pipeline-operator
           | 
           | It has been "stuck" at Stage 2 for a while, though.
        
             | shermantanktop wrote:
             | Thanks for that link! Now I want pipe operators...
        
       | RKFADU_UOFCCLEL wrote:
       | F# is a very well-polished functional language. Think of it to
       | Haskell as C# is to Java. No worries about space leaks or purely-
       | academic syntax or monads (though you can get those if you need
       | them). All with tight integration into one of the biggest, well-
       | established ecosystem (CLI). It's managed by smart people who
       | know how to keep it from derailing as it grows.
        
       | jxjnskkzxxhx wrote:
       | Does anyone else find interesting that people who write blog
       | posts saying "my favourite language is X", it's never a
       | mainstream language..?
        
         | pantsforbirds wrote:
         | My favorite language is Python, but I wouldn't write a blog
         | post about it because no one would care.
        
           | jxjnskkzxxhx wrote:
           | My favourite language is also python, and I would love to
           | read your blog post on why your favourite language is python
           | :-)
        
         | siknad wrote:
         | New mainstream languages are rarer than new better (in some way
         | that can be favorable) languages.
        
         | mrkeen wrote:
         | Successful language designers select for what's popular, not
         | what's good.
         | 
         | C++ intersected the mass of C programmers with the new OO fad,
         | and kept all of C's warts. Had Stroustrup made C++ _better_ ,
         | he wouldn't have an army of adopters who already knew C. Maybe
         | merit will win out in the long run [1]? I'm not hopeful.
         | 
         | Java needed to be close enough to C++, and C# to Java. And
         | Brendan Eich joined Netscape to "put Scheme in the browser".
         | 
         | [1]
         | https://www.theregister.com/2025/03/02/c_creator_calls_for_a...
        
       | reverseblade2 wrote:
       | Here's a Saas that actually makes money written fully in F#
       | 
       | https://3dpack.ing
       | 
       | Here's a rust ray tracer compiled to web assembly written in F#
       | 
       | https://ncave.github.io/fable-raytracer/
       | 
       | source: https://github.com/ncave/fable-raytracer?tab=readme-ov-
       | file
        
         | stefanfisk wrote:
         | The navbar takes up half my screen on an iPhone 13 mini :/
        
       | justanotheratom wrote:
       | F# was my favorite language, but - You have to chose the language
       | of the Domain that you are working in, e.g, Swift for native iOS
       | Development. Supabase Backend requires TypeScript, etc. - LLMs
       | don't care about F#.
        
       | fnord77 wrote:
       | > Trivia: F# is the language that made the pipeline operator (|>)
       | popular.
       | 
       | laughs in clojure
        
       | lysecret wrote:
       | I worked a lot in F# and loved it. I love that it has a lot of
       | great functional ideas without being too pedantic about being
       | 100% functional all the time. (You can have mutating state or
       | just call arbitrary C#.) I took a lot of its insights into my
       | daily python code too. I especially love match.
        
         | mrkeen wrote:
         | There's no need to be functional 100% of the time, and it's not
         | pedantry.
         | 
         | You mark your functions and non-functions as such, so the
         | compiler can get your back.
        
       | BenGosub wrote:
       | Two nice things about F# are that you can introduce it into an
       | organisation using the dotnet ecosystem and that you can use all
       | libraries in dotnet, which is a huge advantage over OCaml.
       | 
       | Otherwise, I am happy with OCaml, but F# has also a place in this
       | world.
        
       | hurril wrote:
       | F# is a wonderful language, one that I write as my daily for the
       | second time during my carrier. It _baffles_ me how it isn't more
       | popular than it is because it truly is very very good. And I say
       | this as an experienced and avid functional programmer.
       | 
       | We even do the frontend in it using Fable and Elmish, which is to
       | say: we basically write our frontends in Elm, but the platform is
       | .NET.
        
       | darksaints wrote:
       | I'm completely convinced that F# (along with Scala, Haskell, and
       | OCaml) adoption has stalled due to having ridiculously bad build
       | systems. More significantly, they are being passed up in favor of
       | Rust, which is a great language but nonetheless a bad fit for a
       | lot of problem domains, simply because Rust has a superior build
       | system. Hell, 80% of the reason I choose Rust over C++ for
       | embedded work is because of the build system.
       | 
       | It baffles me that there are languages with non-profit
       | foundations and are financially backed by multiple corporations
       | which still have bad build systems. It is the most important
       | investment you can make into a programming language.
        
         | Lyngbakr wrote:
         | While I've never used it in anger, I really quite like dune.
         | Was there something specific that makes you characterise it as
         | "ridiculously bad"?
        
       | 110bpm wrote:
       | I put together a quick-start guide to F# Computation Expressions
       | -- showing how you can go from C# async/await all the way to
       | Result<> workflows with let!... and!... expressions, and even a
       | custom validation {} CE. [0]
       | 
       | This is a practical side of F# that doesn't get enough spotlight
       | -- but one I'm using daily.
       | 
       | [0]: https://news.ycombinator.com/item?id=42636791
        
       | kingkongjaffa wrote:
       | F# is great
       | 
       | Even if you never write a single line, it's a fantastic
       | illustrative language.
       | 
       | For example I refer to https://fsharpforfunandprofit.com/ all the
       | time for functional programming ideas.
        
       | sklivvz1971 wrote:
       | As a person who's worked with the author (a great guy!) and with
       | the F# community on a very large F# project: don't bother with
       | F#, professionally speaking.
       | 
       | F# has many theoretical qualities, which make it fun if you like
       | these things, but it also has some fundamental flaws, which is
       | why it's not getting a wide professional adoption.
       | 
       | - the build system was a mess last I checked (slow, peculiar)
       | 
       | - syntax is not c-like or python-like (a big deal for a lot of
       | people)
       | 
       | - you can't hire developers who know it (and certainly the few
       | are not cheap)
       | 
       | - the community is a bit weird/obsessed/evangelizing (a turn off
       | in a professional environment)
       | 
       | - it's clearly a second class citizen in the .net world (when
       | stuff breaks, good luck getting support)
       | 
       | On the other hand
       | 
       | - it has discriminated unions
       | 
       | - units
       | 
       | - etc.
       | 
       | but do you need this stuff (not want: need)? most people don't.
        
       ___________________________________________________________________
       (page generated 2025-04-01 23:01 UTC)