[HN Gopher] What's New in F# 9
___________________________________________________________________
What's New in F# 9
Author : neonsunset
Score : 171 points
Date : 2024-11-10 17:20 UTC (5 hours ago)
(HTM) web link (learn.microsoft.com)
(TXT) w3m dump (learn.microsoft.com)
| sevensor wrote:
| > There is also a new compile-time error for classes with over
| 65,520 methods in generated IL. Such classes aren't loadable by
| the CLR and result in a run-time error. (You won't author that
| many methods, but there have been cases with generated code.)
|
| The mind boggles.
|
| At any rate, F# is a terrific language. After excel, probably the
| second best thing Microsoft has ever released. Turns .NET into a
| reasonable platform.
| CharlieDigital wrote:
| > After excel, probably the second best thing Microsoft has
| ever released. Turns .NET into a reasonable platform.
|
| I feel like C# is quite underrated. Very productive language
| that's relatively easy to teach to anyone that is already
| familiar with JS or TS. Used in a variety of contexts from game
| engines to enterprise backends to desktop apps.
|
| A few fumbles by Microsoft early on stunted its growth, IMO,
| but it's a really good and relatively easy to learn general
| purpose language.
| brtkdotse wrote:
| > A few fumbles by Microsoft early on stunted its growth
|
| Microsoft really, _really_ missed out on a huge opportunity
| to rebrand .NET into something else when they did the
| Framework -> Core transition. Despite .NET being cross
| platform for over ten years and winning benchmarks left and
| right people still see it a the "slow enterprisey framework
| that only runs on Windows".
| CharlieDigital wrote:
| Yes, big time fumble.
|
| I've met a handful of folks who used it in the .NET
| Framework days and hadn't kept up with the changes in Core
| (multi-platform, object-functional hybrid, minimal syntax
| for console and APIs, etc.).
| ngrilly wrote:
| What do you mean by "minimal syntax for console and
| APIs"?
| metaltyphoon wrote:
| Probably top level statements and minimal APIs from
| ASP.Net Core
| CharlieDigital wrote:
| Minimal web APIs are structured a lot like Express
| (whereas .NET web APIs are more like Nest.js)
|
| https://learn.microsoft.com/en-
| us/aspnet/core/fundamentals/m...
| Modified3019 wrote:
| Yep, I literally only learned it was cross platform last
| year when I noticed it as a package dependency.
|
| Mind you, I'm not a coder, and more just a Linux homelab
| hobbyist.
| sundarurfriend wrote:
| I was going to ask what the multiplatform deployment
| story was like, it seems like you've partially answered
| it - it seems like you ship it with .NET Core as a
| dependency, kinda like JRE for Java programs?
|
| How heavy of a dependency is it?
|
| And is there a dependency hell situation, if different
| programs require different versions of .NET Core?
| int_19h wrote:
| There are quite a few knobs there. You can AOT-compile
| the bytecode, as well, and you can ship the whole thing
| as a single binary: https://learn.microsoft.com/en-
| us/dotnet/core/deploying/sing...
|
| Size very much depends on what you actually use in the
| app, but on the order of tens of megabytes.
| ethbr1 wrote:
| Also, one of the major changes in the Framework -> Core
| (now just .NET) shift was making it legally permissible
| to redistribute the runtime?
|
| So you can ship .NET code with a .NET runtime all in your
| installer.
|
| Afaik, Framework was only distributable from Microsoft.
| tbrownaw wrote:
| > _Despite .NET being cross platform for over ten years and
| winning benchmarks left and right people still see it a the
| "slow enterprisey framework that only runs on Windows"._
|
| Do these people I've never heard of outnumber the people
| who did upgrade but wouldn't have if it had been branded as
| a separate product?
| sevensor wrote:
| > I feel like C# is quite underrated
|
| That's fair, I consistently underrate it myself. Last time I
| worked with C# was a big messy codebase written by mostly
| junior developers who didn't understand what entity framework
| was doing behind the scenes. I came away from that experience
| with the impression that C# is a terrible language.
| aithrowawaycomm wrote:
| There's an interesting problem with "practical" functional
| languages that we don't really know what a crappy
| enterprise F# / OCaml / Haskell codebase looks like -
| though maybe Haskell is sufficiently popular in crypto
| these days that there's some examples. But generally
| software in these languages is written by highly motivated
| developers with a lot of flexibility. OTOH a lot of bad C#
| and Java is written by developers with bad technical
| management who treats devs as code monkeys. Further a lot
| of the "technical enablers" of bad C#/Java are bespoke
| enterprise frameworks that simply don't exist for
| functional languages. But in principle, enterprise Haskell
| could be quite vulnerable to a "productivity-boosting"
| language extension that locks older Haskell codebases into
| horrible typeclass golf.
|
| I say all this as someone who loves F# and would only take
| a C# job if I needed the money. But certainly a lot of the
| enterprise antipatterns can be clumsily implemented in F#,
| while a well-written C# codebase is usually pleasant and
| productive. In particular F# doesn't totally escape
| problems like "the Nuget service locator is overengineered
| for our needs, but we are on a deadline and an excessive
| abstraction is better than hard-wiring everything."
| algorithmsRcool wrote:
| C# these days is GREAT, but F# still has features that C#
| doesn't like unions and much more powerful (and ergonomic)
| pattern matching.
|
| And line for line, F# is more effective at getting things
| done (and i would argue with less bugs)
| zamalek wrote:
| Sadly modern idiomatic C# is a bit of a nightmare these days.
| It's a heavily abstracted/"indirected" style, where you are
| basically forced to use a debugger to determine where a
| method call actually goes. The goal seems to be to make
| things as emergent as possible, with reflection and IL emit
| determining code flow as much as possible.
|
| I think that F# goes a long way to prevent this, by nature of
| being functional.
| snoman wrote:
| I've written a lot of modern C# and I don't know what you
| mean - especially with regards to your comment about F#
| being different.
|
| Are you taking about the popularity of the mediator pattern
| (via Mediatr)?
| zamalek wrote:
| Maybe you're just extremely lucky.
|
| MediatR is part of the problem, yes. Way too much
| attribute/reflection magic there.
|
| One particularly good example is: attempt to add full
| support (i.e. query text generation) for PERCENTILE_CONT
| to EF. That will give a good idea of just how bad the
| idiomatic C# style can get. Now take the EF style of
| code/architecture and apply it to an entire product
| codebase - which is completely a understandable _mistake_
| to be made (it 's not unreasonable to assume that EF
| would be a good example of C# code). You know you have a
| problem when you throw in the towel and have
| ThingDependencies classes all over the place. The
| aspnetcore internals don't vary too much from the
| abomination that is EF.
|
| "Just don't code like that," you might say. The problem
| with that argument is that pre-existing code exists,
| people don't code in isolation, and the cargo cult has a
| ton of momentum behind it.
|
| > your comment about F# being different.
|
| You'll struggle to write that style of code in a
| functional language. There is such as thing as healthy
| friction. F# has its own problems, but this is not one of
| them.
| the5avage wrote:
| What is also great about C# is that the language server for
| editor support uses the real compiler. I once set that up
| with emacs and it is by far the best experience I had in
| emacs with any language.
| mhh__ wrote:
| C# is sort of underrated but gets a ridiculously easy ride
| for actively _encouraging_ bloat and abstraction-ism.
|
| What should be "do a thing" is now design a thing to do a
| thing then call the thing-do-er IDoAThing.
|
| Alone this would not be so bad but the problem is that you
| _only_ have this. Extension methods? Fuck off (but don 't
| take them away).
|
| Roslyn is great though.
| CharlieDigital wrote:
| That's a function of the team, not the language.
| mhh__ wrote:
| Human behaviour in programming is of course totally
| independent of language and tools, indeed
| kristopolous wrote:
| Both. The language can afford that usage through the
| design decisions.
|
| I kind of think the best languages would be those that
| make creating layers of spaghetti indirection nearly
| impossible. In practice, it's usually much more specious.
| Names like "CreatorImplementer", "FactoryAbstrator",
| "DeviceAccessory" and a half dozen equally amorphous
| things calling each other as if Thomas Pynchon was
| writing software.
|
| I think I've seen it in all languages I've worked on
| professionally. Maybe not in Perl.
| fuzztester wrote:
| >At any rate, F# is a terrific language.
|
| Any downsides, in your opinion?
|
| I had toyed with it a few years ago, using that lightweight IDE
| called LINQPad, IIRC, but did not follow up, or keep track of
| its pros and cons or progress later.
|
| https://www.linqpad.net/
| modernerd wrote:
| Downsides: lack of jobs, libraries, learning materials, small
| community, little promotion by Microsoft outside of "what's
| new in F#" and other announcements.
|
| It's a shame because F# is a beautiful language -- it's fun
| to read, write and maintain. .NET now works well cross-
| platform with editors other than Visual Studio. General perks
| of .NET like cross-platform compilation are a nice bonus, for
| example, on macOS I can: brew install
| dotnet dotnet new console -lang F# -o
| HelloWorldApp cd HelloWorldApp
| dotnet publish -c Release -r osx-arm64 --self-contained
| dotnet publish -c Release -r osx-x64 --self-contained
| dotnet publish -c Release -r win-x64 --self-contained
| dotnet publish -c Release -r linux-x64 --self-contained
|
| To get self-contained binaries (that don't need .NET to be
| installed locally) for those platforms.
|
| There is a decent multi-platform UI framework called
| Avalonia: https://github.com/fsprojects/Avalonia.FuncUI
|
| There are good actively maintained web frameworks:
| https://fsharp.org/guides/web/#web-frameworks
|
| There are some passionate people writing great books about
| F#: https://fsharpforfunandprofit.com/ddd/
|
| Most of F#'s adoption issues seem to be because:
|
| 1. It's tough to convince people outside of the .NET
| community to use .NET.
|
| 2. Most of the people using .NET use C#.
|
| 3. It's hard to convince C# users to adopt F#. (See https://w
| ww.reddit.com/r/dotnet/comments/16m0wdj/why_dont_yo... and
| similar threads.)
|
| I'd love to work with F# full-time, but -- short of starting
| my own company using it or convincing Microsoft to pay me to
| help them showcase its benefits -- it's been hard to find
| work with F#, which drove me to spend time with other
| languages.
| neonsunset wrote:
| F# can also be compiled with NativeAOT. The main thing this
| target complains about is printfn and especially printfn
| "%A" which uses unbound reflection. So as long as you just
| Console.WriteLine instead it may not emit warnings:
| dotnet publish -o {folder} -p:PublishAot=true
|
| Note that -c Release is no longer required - it is now a
| default for 'publish'. Also, if you are doing a self-
| contained/non-AOT build, you may want to do it as follows
| to retain compact binary size: dotnet
| publish -o {folder} -p:PublishSingleFile=true
| -p:PublishTrimmed=true
|
| All the properties above can also be defined within
| respective .csproj/.fsproj files inside PropertyGroup
| blocks as e.g. <PublishAot>true</PublishAot> so you don't
| have to add them to a command every time.
|
| F# also has excellent support for scripting with fsi and
| .fsx format: https://learn.microsoft.com/en-
| us/dotnet/fsharp/tools/fsharp...
|
| Someone even made a tool for it which builds on top of
| bflat allowing to compile F# script files into native
| binaries directly without project setup:
| https://github.com/ieviev/fflat
| modernerd wrote:
| Thanks for the tips! I had thought there were still some
| other gotchas with AOT and F# but it looks like the list
| is smaller than last time I looked.
| https://github.com/dotnet/fsharp/issues/13398
| lihaoyi wrote:
| I persoanlly found the syntax weird and the IDE support poor
| when i was playing with it in 2013
|
| Both of these are surprising to me. It is an indentation
| language, similar to Python which I love. And it was by
| Microsoft, which makes Visual Studio which I also loved
|
| Yet I found the syntax a lot odder than Python: multiple ways
| to call methods (C# style and Ocaml style), a wide selection
| of strange brackets, `.[i]` for array lookup instead of `[i]`
| (i think they fixed this eventually). And despite Visual
| Studio being great for C#, its support for F# wasnt up to
| scratch
|
| I ended up settling on Scala, which is semantically very
| similar, but with an easier syntax (not perfect, but better)
| and decent Intellij suppory (again, nowhere near perfext!)
| neonsunset wrote:
| The biggest difference happened between 2020 and 2024. I
| encourage you to give it a try - F# support with Ionide in
| VS Code is excellent.
|
| There is no other platform like .NET in capability to cover
| both high and low level scenarios.
| smartmic wrote:
| Not necessarily my opinion, but here is an interview [1]
| about someone who gave up F# in favour of Odin ... maybe of
| interest here in the subthread
|
| [1] https://odin-lang.org/news/newsletter-2024-10/#interview-
| wit...
| neonsunset wrote:
| Not sure what's up with the author but from our brief
| interactions on X I have gotten an impression that they did
| not understand performance at a sufficiently low level and
| implications of using each language (and their compilers!)
| despite being adamant about the opposite, resulting in
| technical decisions driven by inaccurate conclusions. It
| was quite unfortunate and seemed like an emotionally-driven
| choice.
|
| It's perfectly fine to use an LLVM-based language where it
| matters, but it's sad when C# could have been used to solve
| the problem without throwing the baby out with the
| bathwater.
| no_wizard wrote:
| I feel like going from one niche language to another even
| more niche language is risky, even if the performance
| improvement demonstrably true.
|
| I suppose it's a chicken and egg problem for languages that
| want to grow their communities (if nobody takes risks on a
| language it won't see adoption) but I'm surprised given
| their problem domain they didn't go with something more
| widely known
| OptionOfT wrote:
| Since F# is primarily meant as a functional language, and
| thus is written as such, learning it through examples when
| you have no functional language knowledge, there is quite the
| learning curve.
|
| Compare that to starting to read Python when you come from
| C#, it reads as English.
|
| F# omits much more in its code.
| sevensor wrote:
| You know how seasoned lisp programmers say the parentheses
| eventually disappear? I felt like F# was the opposite.
| There were invisible parentheses everywhere and once I
| figured out where they were, the language made a lot more
| sense.
| fuzztester wrote:
| Thanks to those who replied. Good info. That cross-
| compilation feature is cool.
| FrustratedMonky wrote:
| The lack of jobs, that is only downside. Would use it all the
| time if I could, but not many companies want to switch.
| egamirorrim wrote:
| This looks like a good set of improvements but goddamn F# is an
| ugly looking language
| pohl wrote:
| To each their own, I guess. I find the various modern ML-
| influenced languages to be among the best looking.
| sprkv5 wrote:
| I agree with you. The best looking ones are Gleam, ReScript
| and F#
| munchler wrote:
| Really? It's a classic ML language. What about it specifically
| do you find ugly?
| neonsunset wrote:
| Note - F# 9 also benefits from practically all performance
| improvements in .NET 9 itself, especially around object escape
| analysis:
|
| https://devblogs.microsoft.com/dotnet/performance-improvemen...
| fumeux_fume wrote:
| Had a crypto class that let us choose any language that used
| .NET. My homework in F# was so much easier to read than everyone
| elses. Would def use it more, but nearly 100% of my data science
| work is Python.
| gnarlouse wrote:
| That's so cool.
| arunc wrote:
| What is the state of F# a replacement for C# to create GUI apps
| on Windows? Are there companies using F# for this purpose?
| neonsunset wrote:
| There are a few options:
|
| https://github.com/fsprojects/Avalonia.FuncUI
|
| https://fabulous.dev/ (which targets Avalonia/MAUI/Xamarin)
|
| https://github.com/kekyo/epoxy (Avalonia and WPF)
|
| > Are there companies using F# for this purpose?
|
| I can ask around if you're interested.
| stackskipton wrote:
| I'm in this world, few companies are doing GUI apps at all
| these days. Most have long converted to Web Apps.
|
| Since it's pretty tiny minority of .Net users use F#, I'm
| sure someone somewhere is using F# for GUI but it's going to
| be tiny shop somewhere.
| arunc wrote:
| Appreciate it, thanks!
| fluid_ident wrote:
| I really miss working in F#, such a productive language. But I
| still enjoy keeping tabs on the updates.
|
| I always thought the tooling was quite good, given the size of
| the community and Microsoft's apparent apathy towards it at
| times. The biggest pain point for me was accuracy in code test
| coverage.
| sundarurfriend wrote:
| How does the versioning for F# work? These seem like a bunch of
| nice quality-of-life improvements, but a major version change
| doesn't seem warranted in terms of semantic versioning - no
| breaking changes - nor in terms of a major leap in terms of
| language features that a non-semver project might use as a reason
| to go version 8 to version 9.
|
| Another comment mentions .NET9 that recently came out, is that
| the reasoning here, to keep in stride with .NET version numbers?
| guhidalg wrote:
| For both C# and F#, the version of .NET indicates the version
| of the build tooling (msbuild, compilers, nuget packages,
| etc...) that will be used to build the code whenever you invoke
| `dotnet build`.
|
| That means, for example, that the F# team _could_ have shipped
| a language change between versions 8 and 9, but if they didn't
| then at least they could have shipped a compiler change or an
| msbuild change that required .NET 9 for whatever reason.
|
| For developers, usually you can just update your code to the
| latest available runtime version unless you have to wait for
| your deployment environment to have the latest .NET version
| installed. Nowadays that's not necessary due to MSBuild changes
| to create self-contained deployments, but something to know.
| jbjbjbjb wrote:
| A new NET version comes out yearly and the C# and F# versions
| align with the yearly version but C# is ahead by 4. Semantic
| versioning is overrated anyway.
| sbelskie wrote:
| So .NET and C# have moved recently-ish to yearly single digit
| incremented releases and I'm guessing F# is doing the same. Not
| sure if they intentionally made the switch when it would line
| up with the .NET version or if that's just a coincidence. C#,
| for example, released version 13 for .NET 9.
| jfausdfwsdfa wrote:
| > let notAValue: string | null = null
|
| When did F# get unions?
| datadeft wrote:
| It had it since the first version as far as I know.
| ctenb wrote:
| You're probably referring to Disciminated unions aka
| sumtypes? That's not what the parent meant
| datadeft wrote:
| I thought those are the same and I realize that there is a
| difference.
| jfausdfwsdfa wrote:
| Damn. It's only for nulls: https://github.com/fsharp/fslang-
| design/blob/main/RFCs/FS-10...
|
| Wonder if they will generalize:
| https://github.com/fsharp/fslang-design/blob/main/RFCs/FS-10...
| ctenb wrote:
| At least they chose a syntax that makes it possible to
| generalize, which is a smart choice imho :)
| robertlagrant wrote:
| Yeah it looks a lot like Python's PEP 604[0].
|
| [0] https://peps.python.org/pep-0604
| oDot wrote:
| Since the null-related blog post isn't published yet, anyone here
| knows the reason to implement null rather than write middle-layer
| in C# for whatever you want to use?
| neonsunset wrote:
| At this point, almost all community and all standard library
| APIs use nullable reference types (and types that aren't NRTs
| are obviously expected to always have a value).
|
| This change in F# makes it able to interoperate with C# NRTs,
| where C#'s T? becomes F#'s T | null and vice versa.
|
| I feel like the ease of integration of F# into existing
| codebases is one of the major selling points. You don't need to
| write wrappers in order to consume most existing C# code,
| which, for example, enables writing a core with business logic
| in F# while keeping the IO in C# if necessary.
| algorithmsRcool wrote:
| F# has chosen this approach of implementing compatibility
| with newer C# features such as support for ValueTuple<T> and
| Span<T>. It has been pretty successful at keeping F# inside
| the compatibility story.
|
| ---EDIT---
|
| Mean to post this under the GP
| wodenokoto wrote:
| How is the F# story on Linux/MacOS?
|
| Is it like a windows thing that you can also do on Linux or does
| it feel like a fully supported language?
| algorithmsRcool wrote:
| F# is full supported on Windows, MacOS and Linux via CoreCLR
| and several more platforms via Mono, just like C# is
| LAC-Tech wrote:
| Never noticed anything odd using in in linux.
| ducdetronquito wrote:
| I only toyed with F# recently, but coming from Python I _really_
| like that I can also use a REPL to experiment stuff: I wonder if
| experienced F# devs use it too.
|
| I hope to have time to build a small web backend project this
| winter, to get to know the language and ecosystem better.
|
| I heard good things about Oxpecker for the http part; do you have
| any recommendation for a good postgresql client/driver ? (I don't
| like ORMs)
|
| Cf: https://lanayx.github.io/Oxpecker/
| yawgmoth wrote:
| Npgsql is the popular C# driver, and has an F# wrapper. I'd
| start there.
| ducdetronquito wrote:
| Thanks :)
| throw234234234 wrote:
| As an polyglot dev who has the chance to use F# dev at times
| the REPL is how I POC most things - if I'm not sure of an API,
| even inlined into my actual codebase just hit the "Send to F#
| interactive" and it runs there and I can try things inside a
| module. Or when I want to try a new library, or when I want to
| do a quick benchmark, or as a substitute to a PS script, etc.
| You can even make F# scripts executable with the shebang
| `#!/usr/bin/env -S dotnet fsi` which we do a lot for scripts
| around our projects as an alternative to bash/python in our
| .NET projects where we already know a dotnet-sdk is installed.
| Just my anecdote opinion - the syntax and idioms of F# lean
| themselves more to REPL programming then C# which typically
| needs more OO structure rather than small code snippets strung
| together.
| algorithmsRcool wrote:
| F# has been my favorite language since I first encountered it in
| uni. F# was/is waaaay out ahead of C# with features like unions,
| null safety, pattern matching, records, more powerful type
| inference and generic constraints.
|
| Over the years C# has been implementing these features too, which
| is good, but they have been implementing them in incompatible
| ways, which isn't very good. Since the investment in F# has been
| much smaller than in C#, it hasn't been innovating as fast as C#
| and has been left behind in some ways.
|
| But it is still a great language and remains broadly compatible
| with the ecosystem and can deliver equal performance to C# with
| far less boiler plate
| neonsunset wrote:
| Most incompatibilities can be summarized to "source generators"
| and tooling that relies on other forms of code generation. This
| can be fairly easily dealt with by writing a helper C# project
| with the necessary "glue".
|
| Other than that, is there something specific you have in mind?
|
| F# 9 even supports consuming ref struct generic arguments
| recently added to C# and plans to introduce their definition in
| F# itself AFAIK (which is likely going to be a nicer experience
| than in C#!). It has been doing impressively good job at
| keeping up thus far and deserves way more recognition for this.
| hansvm wrote:
| Off the top of my head, async is monstrous to integrate
| between the two languages. Even when it works it's slow.
| neonsunset wrote:
| This was addressed in F# 6: https://learn.microsoft.com/en-
| us/dotnet/fsharp/whats-new/fs...
|
| Asynchronous sequences (IAsyncEnumerable) support is
| provided via
| https://github.com/fsprojects/FSharp.Control.TaskSeq
|
| F# is a very capable language - a broad spectrum of _tasks_
| can be solved by just implementing a new CE, something I
| could not even think of in C#.
| srid wrote:
| For WebAssembly, there is Bolero:
|
| https://fsbolero.io/
|
| Unfortunately, maintenance seems to have stopped since Jan,
|
| https://github.com/fsbolero/Bolero/releases
|
| (I tried creating a sample project on Linux which didn't work to
| begin with)
| xiaodai wrote:
| ...and who cares?
| asdf123qweasd wrote:
| I dont know, i have used F# for a while now. My problem with it-
| is discoverability and reuseability of the created code. It is
| very hard to read and get in - compared to classic OO and its
| hard to reuse something created and custom tailored. My 2 cents,
| may be worth even less, due to my limited experience and a
| propably wrong approach by me.
| munchler wrote:
| It takes a while to shed one's existing OO expectations, but
| after that, I think you'll find well-organized F# code to be
| easier to use than C#. Immutability and lack of side-effects
| makes it much simpler to reason about what someone else's code
| is doing, and then reuse it.
|
| If you have any specific examples of
| discoverability/reusability issues in F#, I'd be curious to
| hear them.
| blastonico wrote:
| I love F#, but it depends almost exclusively on Microsoft, which
| is not a main priority. What if Microsoft decides to stop
| developing it?
| munchler wrote:
| It's an open-source project with its own F# Software
| Foundation. If Microsoft drops it, I think it would continue.
|
| https://fsharp.org/
| gnarlouse wrote:
| What's new in F# 9? Well of course that would be G#.
___________________________________________________________________
(page generated 2024-11-10 23:00 UTC)