8 ms·
> 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
by sevensor 2y ago
> 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 2y ago> 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 2y ago> 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 2y agoYes, 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 2y agoWhat do you mean by "minimal syntax for console and APIs"?
- metaltyphoon 2y agoProbably top level statements and minimal APIs from ASP.Net Core
- CharlieDigital 2y agoMinimal 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/minimal-apis?view=aspnetcore-8.0 https://learn.microsoft.com/en-us/aspnet/core/fundamentals/m...
- ngrilly 2y agoHaving recently joined a company using C#, and with a background using Go, Python, Node, and similar, I was worried about heavy "enterprise-style" APIs. I was happy to discover the new minimal web API while reading .NET Core documentation.
- jodrellblank 2y agoYou no longer need imports, or namespace, class and main method boilerplate to write a basic C# program; there’s now a way to simply write some lines of code in a file with some implicit imports, and compile/run them like it was more of a scripting language. https://learn.microsoft.com/en-us/dotnet/csharp/tutorials/top-level-statements https://learn.microsoft.com/en-us/dotnet/csharp/tutorials/to... (If there’s other syntax changes, I don’t know them, AFAIK it’s the same C# you write)
- SideburnsOfDoom 2y ago> If there’s other syntax changes, I don’t know them The new syntaxes that come to my mind are: * File-scoped namespaces * "global using" * "using static"
- 2y ago
- Modified3019 2y agoYep, 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 2y agoI 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 2y agoThere 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/single-file/overview 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 2y agoAlso, 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.
- telgareith 2y agoNope, have always been able to ship the redist installers. Just like VC++. https://www.microsoft.com/en-us/download/details.aspx?id=21 https://www.microsoft.com/en-us/download/details.aspx?id=21 (scroll down to 'Installation Instructions') After all, not being able to ship the runtime with the software to buyers would have been... Bad. In the early '00s
- tbrownaw 2y ago> 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?
- ngruhn 2y agoI’m definitely one of these people. Maybe I should give .NET a chance.
- CharlieDigital 2y agoIt's quite nice now. Tooling is way nicer than it was 10 years ago. My team is all Apple silicon Macs and we deploy to AWS Arm64 instances. Unit tests in GH run on Linux workers.
- monkaiju 2y agoI encountered this within the last week...
- Kinrany 2y agoLess than 50% of software engineers ever used .NET for anything, so the answer is almost certainly yes?
- sevensor 2y ago> 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 2y agoThere’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.”
- akra 2y agoMy hypothesis is that F# is somewhat self selecting at senior/lead dev's who would have a lot of choice in the language that they get to choose not the army of "code monkey's" as you call them. Generally this would mean higher code quality on average.
- algorithmsRcool 2y agoC# 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)
- runevault 2y agoThe c# team is supposedly putting in serious work on Discriminated Unions. I'm really interested to see how it turns out because f# already does a great job with them.
- Turskarama 2y agoDiscriminated unions is probably the last "must have" feature I've been waiting for in C#. Better pattern matching would be nice to have but honestly not as much of a gamechanger.
- WorldMaker 2y agoThe C# team for several reasons decided "rock solid" pattern matching was a higher priority than discriminated unions because good discriminated union code needs good pattern matching. In the last few versions of C# I think pattern matching has gotten really good. List Patterns finally exist now, and that influenced the new iterable collection initializers, which are also pretty good now. Last I checked, the C# team was still debating Dictionary/Hash key lookup Patterns and Dictionary/Key-Value initializers, and that's maybe my last big request in pattern matching other than native discriminated unions, of course.
- zamalek 2y agoSadly 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 2y agoI’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 2y agoMaybe 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.
- emn13 2y agoThe default C# style has always preferred a large dose of unnecessary runtime flexibility. Sometimes that comes in the form of lots of dynamic dispatch, sometimes it's DI, sometimes it's non-sealed overly large base-class types, and sometimes its some combination thereof - but the net effect is that it's not possible to reason about code by just reading it. Tooling becomes worse and/or less valuable because tooling too cannot reliably trace all possible code paths. Additionally, Microsoft has an outsized influence on the C# ecosystem. As a result, they wrote quite a few architectural and style guidelines that, naturally, target themselves. It makes sense for a hyper-widely distributed library to consider things like binary compatibility as critical features, but the design rules that follow from that have zero utility for apps, and low utility for most libraries. The C# ecosystem also has an unhealthy veneration for MS provided code. While I'm sure most of the authors are quite competent, there's less experimentation and fewer hidden gems because the ecosystem is tilted towards being followers behind the framework providers path. As a result, it's much harder to refactor code in that style than code in a less (runtime) flexible style, and it's worse when the libraries heavily used are frameworks that have so many extension points. There's a tradeoff between runtime flexibility and codebase flexibility, and the default .NET C# style heavily leans towards runtime flexibility, which isn't a good tradeoff for most software.
- the5avage 2y agoWhat 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__ 2y agoC# 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 2y agoThat's a function of the team, not the language.
- mhh__ 2y agoHuman behaviour in programming is of course totally independent of language and tools, indeed
- bigstrat2003 2y agoIt is, in fact, independent. You can create horrible monstrosities in any language, or create great code in any language.
- kristopolous 2y agoBoth. 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.
- CharlieDigital 2y agoI mean, you can do the same in JavaScript and TypeScript as well as any number of other languages.
- trallnag 2y ago> relatively easy to teach to anyone that is already familiar with JS or TS. What about Java?
- throwaway675867 2y agoIn my experience having mentored devs into F# on very large projects its easier to learn F# if coming from a JS, Python, Go, etc background than C# or Java even without previous .NET exposure. Not due to a skill issue, but more of a psychological one. IMO to be productive in F# code code tends to be simpler - many patterns that dev's valued learning in a OO context become a little obsolete or less needed as a whole. This is my anecdote but it is the C#/Java/etc crowd that tend to have the most negative immediate reaction to F# - they ask "where is X" and often I immediately say "X is bad, you shouldn't need X - think about why". They associate X with some kind of power/productivity gain, but don't realize there is many ways to do things. Kind of follows the paradigm of "frameworks/patterns are missing language features". If they keep at it then it eventually clicks but there is almost a psychological "unlearning" that needs to be done which at least in the C# camp creates an almost tribal tension between the two camps - its just too unfamiliar. Whereas for example TS dev's seem to find it somewhat familiar in parts; even people only ever done JS previously I've found have become good F# dev's. Could be because the flow more suits the way you would code in a dynamic language while still being strongly typed (e.g. REPL's, type inference, static modules, functions over classes, etc).
- Multicomp 2y agoVouched for this dead comment. If this really should be flagged to death, could I get a quick refresher on what parts are boring reading or off-topic? The comment is an anecdote and not data, but this does not seem like a flamey post, or a low effort post, or a strawman post.
- mkl 2y agoProbably automated. If someone creates a new account then immediately posts big comments, lots of comments, or links, the comments end up dead by default and need vouching. The dead spam comments often found at the bottom of threads are why.
- bmitc 2y agoF# is much easier to teach and learn than C#.
- fuzztester 2y ago>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/ https://www.linqpad.net/
- modernerd 2y agoDownsides: 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 https://github.com/fsprojects/Avalonia.FuncUI There are good actively maintained web frameworks: https://fsharp.org/guides/web/#web-frameworks https://fsharp.org/guides/web/#web-frameworks There are some passionate people writing great books about F#: https://fsharpforfunandprofit.com/ddd/ 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://www.reddit.com/r/dotnet/comments/16m0wdj/why_dont_you_just_use_f/ https://www.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 2y agoF# 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-interactive/ 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 https://github.com/ieviev/fflat