3 ms·
C# developer here, with a long history of OCaml development (and I'm still using OCaml knowledge as a filter for recruiting C# developers). First-class functio
by victorNicollet 11y ago
C# developer here, with a long history of OCaml development (and I'm still using OCaml knowledge as a filter for recruiting C# developers).
First-class functions in C# are nice, nearly as good as those in OCaml. The main annoyance is the incompatibility between Action<> and Func<> (and, in general, the fact that C# uses void rather than unit).
--
Immutability: for every mutable class in our code base, there are three or four immutable classes, and `readonly` is likely the most frequent keyword. Among these, we have an entire hierarchy of dozens of classes that are entirely immutable (and make heavy use of immutable containers from Microsoft) because it's still the easiest way to implement a multi-reader, single-writer thread-safe data structure. You can survive without immutable-by-default, you can survive without OCaml's
{ record with a = b ; c = d }
syntax, but it gets very, very annoying to work without
{< self with a = b ; c = d >}
in an object-oriented language.
Algebraic data-types: I'm mostly writing compilers (yes, in C#, don't ask), and instead of writing a simple
| SetLineOp of param * param * index
I have to define a new class, three readonly fields, a constructor to set them, equality operators (R# helps, but still...), and five or six lines of visitor pattern boilerplate in order to get the "you missed a case" warning in pattern matching. This gets very annoying very quick, and there is no practical benefit to having all those classes here.
--
Type inference: C# does manage to be fairly clever, although not as clever as OCaml. I have seldom found it to be lacking in general use, aside from the ability to define local functions (var f = a => { ... } does not work, you have to spell out the type of f). There have been a handful of times when I was trying to do something very clever and found myself limited by the type system, and had to write annotations myself.
And one time, I had to reimplement GADTs with generics and reflection. It was painful, but it works.
However, with a few minor tweaks (e.g. an option type), I would rather have the C# type inference than the OCaml one. The reason is that, if I want to do something very clever, I will not find myself limited to code that I can actually prove to the OCaml compiler as correct: I have, time and time again, resorted to reflection and code generation to work around such situations. In other words C#'s Obj.magic is a lot more powerful (and safe, and expressive) than OCaml's.
A fairly good example is Eliom's way of expressing the parameters of a service. In C# you would write in a PageController class
public Details Update(PageId id, UserId user, [PostBody] Details body)
and have your web framework automatically bind this to POST /page/update/{id}?user={user} with the appropriate serialization for PageId and UserId. And writing such a framework is easy: a couple hundred lines of code, with run-time type safety.
In OCaml you have to understand the entire Eliom_parameter framework: https://ocsigen.org/eliom/4.2/api/server/Eliom_parameter https://ocsigen.org/eliom/4.2/api/server/Eliom_parameter
Just think of the mental firepower needed to create that framework in the first place!
- pjmlp 11y agoI actually like the idea of writing compilers in C#. :)