Live data from Hacker News

Why F#?

batsov.com

401–410 of 424 posts

Re: Why F#?

#401

Earlier quoted context omitted.

My two cents is that F# hasn't received the same care and attention as C# and working with it can be awkward. At the same time, a lot of the cool features (list comprehension, pattern matching, immutable records) have slowly trickled into c#, giving even less incentive to switch

I personally find the way these features were shoehorned into the C# syntax an eyesore, I have quite some C# experience, and I think the language is getting more and more convoluted and noisy, with ever less coherent syntax. On the other hand many of these features are really convenient and handy in F#. Adding many of the oh-my-gamedev-such-speed features from C# to F# also makes its syntax less pleasant to work with…

I have the opposite experience. Being able to write stuff like this is refreshing:

  public record Name(string First, string? Last = null);
  public record Register(Name[] Members);
  ...
  var register = new Register([new("John", "Doe"), new("Neo")])
It probably depends on what you're writing. I'm not using async much at all so I don't feel the pain of it.

Re: Why F#?

#402
post #60

Earlier quoted context omitted.

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.

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

Yeah, overall I agree. And I honestly can't imagine anyone who works with any popular javascript framework would flinch at the addition of a .sln file or /Properties folder lol...

Re: Why F#?

#403
post #59

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.

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

There's a draft spec out there for discrete unions in C# fwiw. I wouldn't be surprised to see it in another version or two.

And while I agree that I don't love some of the object initialization patterns C# allows--I respect that other people might have different style than me and don't mind ignoring that those styles exist when writing my own stuff :)

My general rule goes something like:

1. Use record types for any simple data structure

2. Avoid using primary constructors (even on record types).

3. Use { get; init; } properties for everything unless there's a good reason not to.

4. For things that need to carry internal state, have different methods for mutations, emit events, etc., use a class with regular old constructors and either { get; } (for immutable) or { get; private set; } (mutable) properties as needed.

Re: Why F#?

#404
post #367

Earlier quoted context omitted.

> static typing: 2 + "2" does not compile/parse (e.g. Python vs mypy, Typescript vs JS) I think this example is not correct, because static typing doesn’t affect how values of different types interact. And while I don’t know of any staticly typed language where specifically `2 + “2”` is a valid expression, statically typed languages definitely can be weakly typed: the most prominent example is C where one can combine…

Dynamic typing can forbid the latter (at runtime), but it's implementation dependent. There's a further distinction, Latent typing , which is where types are associated with values rather than variables . But a dynamic language can have types associated with variables, and it can forbid changing those types after their types have been checked the first time.

> But a dynamic language can have types associated with variables, and it can forbid changing those types after their types have been checked the first time.

So, like C++ with `auto`?

Re: Why F#?

#405

Earlier quoted context omitted.

'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 a…

The distinction in this case is utterly meaningless. This is about the ergonomics of the language. Which are lacking the minute to break out of pure functional land

Read this first: https://learn.microsoft.com/en-us/dotnet/fsharp/language-ref...

There are multiple alternate asynchronous computation expression implementations which give different ergonomics and behavior (like https://github.com/TheAngryByrd/IcedTasks). There's an entire CE extension to specifically enable this kind of convenience and flexibility too: https://github.com/fsharp/fslang-design/blob/main/FSharp-6.0...

None of this is possible in C#, at least without jumping through many hoops and ending up with extra boilerplate (and this is okay, C# has enough of its own complexity). As cjbgkagh noted, providing this type of control is the whole point and what makes F# so powerful.

Re: Why F#?

#406
post #401

Earlier quoted context omitted.

I personally find the way these features were shoehorned into the C# syntax an eyesore, I have quite some C# experience, and I think the language is getting more and more convoluted and noisy, with ever less coherent syntax. On the other hand many of these features are really convenient and handy in F#. Adding many of the oh-my-gamedev-such-speed features from C# to F# also makes its syntax less pleasant to work with…

I have the opposite experience. Being able to write stuff like this is refreshing: public record Name(string First, string? Last = null); public record Register(Name[] Members); ... var register = new Register([new("John", "Doe"), new("Neo")]) It probably depends on what you're writing. I'm not using async much at all so I don't feel the pain of it.

For me the pain is twofold:

a) it poisons all interfaces it touches (common trait of async in other languages as well)

b) C# async Task -s typically are created in Running state without any easy control over when, where and how they will execute. Controlling these things is far from trivial, and and requires lot of extra effort.

In F# the traditional async block is a builder for an async workflow, and you could then submit this workflow to an executor that is easy to configure for the execute model best suites you, eg. thread pool, single thread with continuations, maximum number of "operations" in flight, etc. The fact that it is not started right away also makes it easy to create your own executors.

Having to deal with backpressure in C# style async is way harder IMO. On the other hand when writing a UI app, always having to submit to an executor might seem inconvenient, and you generally don't have to handle thousands of concurrent requests all reaching out to a (different) backend and avoid DOS-ing it. This is why I wrote that this way made with a frontend-centric approach in my opinion.

Re: Why F#?

#407
post #85

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

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.

Just start. Use whatever style you are used to. Use controllers. Adapt your style as F# pulls you deeper inside the pit of success. You'll struggle the first couple of features, but you'll reach a sweet spot between your current style and functions relatively fast.

Re: Why F#?

#408

Earlier quoted context omitted.

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

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

There's also going to be quite a big ecosystem / standard library difference between languages that had fundamental type system features since the beginning vs. languages that added fundamental features 23 years later.

Imagine all the functions that might return one thing or another, which was inexpressible in C# (until this proposal is shipped), will all these functions release new versions to express what they couldn't express before? Will there be an ecosystem split between static typing and dynamic typing?

Re: Why F#?

#409
I work in an industry where F# is a non-starter but I still love to use it outside of work. Also what I learn from F# and functional programming still benefits me in my day job (mostly c++). I think I tend to write a bit safer code after understanding the benefits of a functional language.

Re: Why F#?

#410

Earlier quoted context omitted.

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…

My current preference is to use Elixir and its great ecosystem as the shell for my project, and implement the core business logic in Gleam.

Why? The business logic part is where Elixir outshines Gleam the most, isn’t it? What do you gain by doing this?

(I am genuinely curious and not trying to be snarky.)

Post reply on HN