Hacker News new | ask | show | jobs
by banashark 310 days ago
Well there are the 3 you mentioned (records, classes, and tuples) which should be easy enough to differentiate from each other. The struct versions aren't necessary to use in most cases, and are an optimization.

The thoughtful, but not breakneck speed of changes within the language is one thing I appreciate a lot. Things do get added (there are proposals and discussions that are fairly regular in the GitHub repo for language design matters). A recent example is adding a spread operator.

1 comments

Yeah those examples I gave are not the best. But why records and classes when records can also have methods. What I was getting at was the language looks good until you dive deeper and get into all those rough edges of dotnet interoperability. An example I can think of is functions/methods. I think F# style is to write curried functions (no brackets for function inputs), except class methods are written mostly non curried. Computation expressions are non curried also even though that is an F# only features. Then there are two ways of writing generics: C# reified generics and rust like monomorphised generics (with inline keyword) and they used to have two different syntaxes until recently
Yeah typically if you're exposing F# code out to C# as a library, you'd want to keep the external API utilizing features that have better interoperability (classes), whereas code that's written in F# and only expected to be called by F# can use things like currying and such.

In practice, this ends up being mostly simple to deal with.

In the other direction, consuming C# libraries historically hasn't had too much trouble other than they don't really design them with any functional-leaning in mind. The real problem that's growing recently is the dotnet teams move towards C#-centric features. Things like source-generators, roslyn, etc that are "C# features" and not "dotnet features". These types of things could create a big enough rift to break practical usage of F# as a dotnet interoping language if it goes unchecked.

> But why records and classes when records can also have methods.

Records have built in equality logic, Classes don't.

And, because of the interop story, they wanted to be able to define classes.

> C# reified generics and rust like monomorphised generics (with inline keyword) and they used to have two different syntaxes until recently

I almost prefer the old way, where SRTPs required the other syntax. On the other hand I guess between 'inline' and constraints the compiler makes the 'best choice' now...

Also, just minor pedantic comment, both C# and F# will monomorphize for struct of T

> Records have built in equality logic, Classes don't.

I'm aware of this but i feel this is confusing. Just putting () changes semantics a whole lot

> Also, just minor pedantic comment, both C# and F# will monomorphize for struct of T

I wasn't aware thanks