Live data from Hacker News

Why F#?

batsov.com

381–390 of 424 posts

Re: Why F#?

#381

Earlier quoted context omitted.

It is extremely niche outside of this bubble.

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...

> According to Stack Overflow developer survey [0] Rust is at 12.5%, ... So definitely not niche.

The annual survey is very popular in the Rust community. Its results are often used for advocacy. Participation by Rust developers is very high. So what you have is a classic case of a selection bias.

Re: Why F#?

#382

Earlier quoted context omitted.

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?)

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.

You're not entirely wrong, but when it comes to SQL, the trade-offs are unavoidable. You either embrace a conventional, not-SQL approach with all its limitations, or you treat the database as the single source of truth (SSoT). Both have downsides, but configuring a designated local or shared database for this purpose is no less reliable than conventional approaches.

As for type providers in general, I don't think databases are the best example of their typical use case. Most type providers don’t interact with external systems; they usually parse schemas, configuration files, or other structured data to generate strongly typed representations. The database-backed approach is just one variant, not the norm.

Re: Why F#?

#383

Earlier quoted context omitted.

I'm saying that I wish computation blocks looked better in F#. Instead of: let foo id = async { let! bar = getBar id return bar } I would prefer let async foo id = let! bar = getBar id bar or even something like let async foo id = getBar! id So that computation blocks don't feel like you're switching to an entirely different language. Just wrap the ugliness in the same syntactic sugar that C# does. As it is, C# can a…

Your criticism is rather incoherent and it is difficult for me to make sense of it. You don't even have to use the computation block for that and can use the built in functions as I mentioned earlier and gave 3 examples of. You're both complaining about extra keywords while trying to make the case of adding yet another one. Thus your complaint boils down to F# not picking the exact keywords that you like - that the l…

> You're both complaining about extra keywords while trying to make the case of adding yet another one

I did no such thing. async is already a keyword in F#, I'm just saying they should drop the brackets and remove the required return statement.

> In language design there are always tradeoffs but I'm unable to see how your suggestions would improve the language in the general case or even in your specific case

It would make the language easier to read, for one, and would reduce the amount of specialized syntax needed for specific features. It would preserve the original ML-style syntax for an extremely common operation and not force users into wrapping anything upstream of an async call in a computation block, which is the ugliest syntax feature of F#

> Computation expressions are a generalized concept which are there to add the exact kind of syntactic sugar that you're after

I understand that, and my argument is they failed to do so. The syntax looks bad. They could keep it for all I care, but they should add even more sugar on top to make it not look so bad.

Re: Why F#?

#384
post #321

Earlier quoted context omitted.

weak typing: 2 + "2" is 22

could also be "4" or 4! 4 seems like it would be the most evil option, honestly

or the most sane, depending on context... e.g. awk and perl do this.

Re: Why F#?

#386

I've found that as C# gains much of the features that F# has and will soon gain more (pattern matching, functions as first class data types, great fp libraries, etc) the "moat" that F# has over C# has gotten smaller. I write most of my c# code in a primarily functional style, but I still have the advantage of using the libraries in their own native ways that follow the examples given by microsoft and other vendors.

[dead]

Re: Why F#?

#387

Earlier quoted context omitted.

I would call .NET build system excellent.

Lets settle on a finally good enough. I can give honest compliments on learning from the past problems and from the better examples in the indsutry. You may not remember the early .net core times with yeoman and other then-current javascript ecosystem originated things applied in really cumbersome, half-assed ways, with lacking docs and always being in flux for years. The project.json era was terrible. Also msbuild w…

Whats pretty interesting is how outdated opinions of .NET are so sticky. Are we talking about what javascript was like 10-15 years ago?

I guess Microsoft could really make some headway if they got more folks to try it today.

Re: Why F#?

#388

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...

Agreed. Type providers bring metaprogramming to F# in a way that’s both powerful and innovative. The concept is amazing, enabling a new frontier for dynamically extending type safety. My only surprise is how little fanfare it has received since its introduction.

For a more pragmatic take on static metaprogramming, the manifold project[1] for Java is worth a look. Unlike F#, which leans toward expansive schemas, Manifold focuses on contained, compile-time integrations—handling JSON, XML, SQL, GraphQL, and even other languages in a seamless, type-safe way.

1. https://github.com/manifold-systems/manifold

Re: Why F#?

#389

Earlier quoted context omitted.

Your criticism is rather incoherent and it is difficult for me to make sense of it. You don't even have to use the computation block for that and can use the built in functions as I mentioned earlier and gave 3 examples of. You're both complaining about extra keywords while trying to make the case of adding yet another one. Thus your complaint boils down to F# not picking the exact keywords that you like - that the l…

> You're both complaining about extra keywords while trying to make the case of adding yet another one I did no such thing. async is already a keyword in F#, I'm just saying they should drop the brackets and remove the required return statement. > In language design there are always tradeoffs but I'm unable to see how your suggestions would improve the language in the general case or even in your specific case It wou…

'async' is not a keyword in F#, it's a builder instance no different to the ones that you can create. It's just built in to the standard library.

The return statement is only required if you want to return something form the computation expression. In your example you use async { let! x = f(); return x}, which can be reduced to async { return! f()}, which can be reduced to f().

The rest is your opinion that I don't agree with.

Re: Why F#?

#390

Earlier quoted context omitted.

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 le…

Also C#: bar = foo switch { true => 7, false => 11 }

Ah yes that is definitely a nice addition to the C# language, albeit still with a couple of shortcomings compared to F#:

1. It doesn’t support code blocks, so if you need multiple lines or statements you have to define a function elsewhere. 2. To get exhaustiveness checking on int-backed enums you have to fiddle with compiler preprocessor directives.

And for #2 any data associated with each enum variant is left implied by C# and has to be inferred from a reading of the surrounding imperative code, whereas in F# the union data structure makes the relationship explicit, and verifiable by the compiler.

Post reply on HN