My theory as an outsider: F# is strongly tied to the Windows world, the corporate world, where a conservative approach is always preferable, on your tech stack and if you need to hire peons coding all day. The corporate world isn't leaving OOP anytime soon, because it's what 95% of engineers focus on, the silent majority which do not frequent HN or play with functional languages in their weekends. The corporate world runs on Java and C#.
If F# had been released in the open-source, flashy and bustling world of Linux and macOS developers, it would have had a much greater success.
I know you can run F# on Linux, but just like running Swift, it feels like outsiders I wouldn't want to bet my business on if I were a Linux-only shop (which I am), however nice it feels. Also a decade ago when it had a chance to take root, Microsoft was still the Embrace Extend Extinguish company. It's not good enough to risk it, just like I'm not gonna use SQL Server for anything.
I think you are grossly overestimating the degree to which the programming language you choose to use to solve a business problem constitutes "betting your business on." How would your business fundamentally change if your first 10k lines of code was in F# as opposed to Go, or Java, or Python, or TypeScript? These are also all languages I've been paid to use, and have used in anger, and with the exception of Java were all learned on the job. This comment in general has big "M$ bad" vibes and if you take those pieces out I'm not sure what the actual criticism is (maybe there is none)?
F# looks wonderful, but unless you’re already in the MS ecosystem, dotnet just feels bad and out of place. And I guess if you are already in the MS ecosystem you’re using C#.
I think the situation is clear-cut: until recently, you couldn't really run .net on anything else than Windows, so the only people using it were those already invested in the ecosystem.
Among the people invested in the windows ecosystem, many (most ?) are large "non-tech" companies who hire people who mostly see their jobs as a meal ticket. These people don't have the inclination (for lack of curiosity, or time, or whatever reason, doesn't matter) to look into "interesting" things. They mostly handle whatever tickets they have and call it a day. Fiddling with some language that has a different paradigm wouldn't be seen as a good use of their time on the clock by corporate, or during their time off work by themselves, since they'd rather spend that time some other way.
Hence, F# never really got any traction.
It's pretty simple, really. I am a Linux engineer, and it is not a great investment of time and money for me to get into .NET. I knew F# was cool, but is it cool enough to want to feel a second class citizen, running it on the OS and platform it is not intended to run on? It makes no business sense at all.
I'm not a software engineer myself, nor a Windows person, so I don't know the specifics, but FWIW, my client runs production .Net code of the C# variety on Linux, connected to pgsql. It's some kind of web service for checking people's tickets (think airport gates where you scan your ticket to enter), so not exactly a toy, even though it's nowhere near unicorn-scale. It seems to work fine, in the sense that I've never heard anyone complain about anything related to this setup. No "works for me but is borken in prod" or "thingy is wonky on Linux but OK on Windows so have to build expensive workaround".
The devs run VisualStudio (non Code) on their Windows laptops. Code is then built and packaged by Azure Pipelines in a container and sent to AWS to be run on ECS.
But it never was a tier 1 platform during its growth. So most non-Windows devs put their focus on other platforms. There is nothing wrong with that.
I could learn .NET now, but I don't really have an interest to do so at this point; Also, the devs you talk about are on Windows, using their tier 1 IDE (Visual Studio) that only runs on Windows, which is my point exactly.
I tried to dip my toes into F# out of curiosity, and it worked by following some tutorial and VS Code. But it did seem somewhat bare bones. Although I'll admit I'm spoiled by Rust and IntelliJ.
As with almost all "vibes"-related comments, this doesn't hold up. There isn't any criticism; just a positing that the sort of corporate, process-heavy companies that will major on Microsoft programming languages will be the last ones to want to try functional programming languages.
As long as it has a base capability (libraries, maturity) and when people join they can be productive with it in a month or so then the risk is pretty low. For F# most .NET developers, even Node developers IMO will get used to F# relatively quickly. From my anecdotal experience with a number of languages its probably one of the easiest to onboard out of the FP langs balancing the FP methodology while trying to be practical/pragmatic. It has a large ecosystem via the .NET platform and supplements it with FP specific F# libraries where pragmatic to do so.
When I was at Jet and Walmart, I never really felt "limited" by F#. The the language was extremely pleasant to work with, and I think most importantly, it was opinionated. Yeah, you can write Java/C#-style OOP in F# if you really want, but it's not really encouraged by the language; the language encourages a much more Haskell/OCaml-style approach to writing software.
Even calling C# libraries wasn't too bad. MS honestly did a good job with the built-in .NET libraries, and most of them work without many (or any) issues with the native F# types. Even third-party libraries would generally "just work" without headache. .NET has some great tools for thread-safe work, and I'm particularly partial to the Concurrent collections (e.g. ConcurrentDictionary and ConcurrentBag),
I also think that F# has some of the best syntax for dealing with streams (particularly with the open source AsyncSeq package); by abusing the monadic workflow ("do notation" style) syntax, you can write code that really punches above its weight in terms of things it can handle.
Now, on the JVM side you something like Scala. Scala is fine, and there are plenty of things to love about it, but one thing I do not love about it is that it's not opinionated. This leads to a lot of "basically just Java" code in Scala, and people don't really utilize the cool features it has to offer (of which there are many!). When I've had to work with Scala, I'm always that weirdo using all the cool functional programming stuff, and everyone else on my team just writes Java without semicolons.
But the basic point of the article does make a reasonable point; part of the reason that Scala has gotten more traction is because Java is just such a frustrating language to work with. Scala isn't perfect but being "better than Java" is a pretty low bar in comparison.
C# is honestly not too bad of a language; probably my favorite of the "OOP-first" languages out there. The generics make sense, the .NET library (as stated before) is very good, lambdas work as expected instead of some bizarre spoof'd interface, there are some decent threading utils built into the language, and it's reasonably fast. Do I like F# more? Yeah, I think that the OCaml/Haskell style of programming is honestly jsut a better model, but I can totally sympathize with a .NET shop not wanting to bite the bullet on it.
https://github.com/scala/scala-xml/wiki/Getting-started
The "opinionated" Scala are the Typelevel and Zio stacks, which are very cool.
The problem with the "better Java" approach is that although it has helped Scala's growth a lot, it has also made it susceptible to Kotlin. The Scala code that doesn't use the advanced type magic can be straightforwardly rewritten in Kotlin instead. Kotlin also stops your bored developers from building neat type abstractions that no one else understands.
People who use Scala only has a "better Java" can now use Kotlin has a "better "better Java"".
People who are writing Clojure likely aren't looking at Kotlin as an "alternative"; while they superficially occupy a similar space, I don't think Clojure has any ambitions of being a "better Java", but rather a "pretty decent lisp that runs on the JVM with some cool native data structures and good concurrency tools". I do like it better than Java, but that's because I like FP and Lisp a lot; if I needed a "better Java" right now, I would unsurprisingly probably reach for Kotlin.
Kotlin's whole point is a "better Java", so it's going to grab people who went to Scala for a "better Java". Also Java actually has a sane roadmap and methodology to get better too, so there's that now too - with the preview/incubating JEPs, people can see what is coming down the pipeline.
Clojure makes no claims of being "Java++". It's a lisp first and foremost that focuses on embracing the host platform and being broadly compatible with existing libraries and strong concurrency protections.
What do you mean by this?
"But remember that you need the TemplateExplicative and NullUnderstanding compiler extensions!"
brilliant! lol
And I would really like if OCaml would have had the possibility to add the needed PPXs names to the source file (like Haskell's compiler extensions). So as to not have to read the Dune (or whatever build system is used) file to get to know where `foo%bar` or `[@@foo]` is coming from and what is doing. But at least the usage of `ppxlib` nowadays should make PPXs "compose" aka. not stamping on each other's feet.
https://ocaml.org/docs/metaprogramming http://ocamlverse.net/content/metaprogramming.html
The syntax superficially looks a lot like OCaml, but it doesn't do the cool stuff with OCaml functors and modules; you write it a lot more like Haskell most of the time.
Don Syme began with a port of Haskell to .Net, but SPJ convinced him that this is a bad idea, so he did choose OCaml. ("The Decision to Create F#", Page 9)
[1] https://hackage.haskell.org/package/base-4.18.0.0/docs/Debug...
No need for extensions, just compile and run your program slightly differently. That's the power of declarative languages.
Also, a link to a useful library is not a bad thing for anyone curious about Haskell. Thus, there's a bit of education there.
If it looks like improv, I am here every evening till Friday.
I also object to that "everywhere". It is far easier to just dump an extra 'print' line somewhere inside a for-loop than into a `foldl (*) 1 $ map (+ 3) [17, 11, 19, 23]`. And that is an easy one...
I develop with Haskell professionally. That foldl example of yours is pretty rare and usually dealt with the QuickCheck [1], mother of all other quickchecks. Usually, the trace will be outside of the foldl application, but you can have it there in the foldl argument, of course.
So actually not everywhere. And QuickCheck does something else entirely.
The foldl example of yours should be split into a property checking and controlling for expected properties of the input. The first part is done via quickcheck and second part usually is done with assertions and/or traces.
But nothing preclude you from having your trace there, inside foldl argument. This is clearly wrong place to have it, but still you can have it there.
So I repeat, you can have your traceEvents everywhere.
The "correct" answer to `foldl` would be `scanl` and printing the result of it.
https://hackage.haskell.org/package/base-4.18.0.0/docs/Prelu...
In my opinion, eventlog traces make much better logging than almost anything I've seen.
Right now, developing with C++, I miss the power of Haskell's RTS.
Haskell's (GHC's) Eventlog is nice, but a binary format and not comparable to text output.