|
> There are way too many variants of the same thing: records, classes, struct records, tuples, struct tuples etc, [...] > At the end I went with Rust because it has one way of doing such stuff. I haven't looked at C# in 20 years, but Rust certainly has a LOT of ways to do similar things too: struct Foo { x: f64, y: f64 } // Struct
struct Foo(f64, f64) // Tuple Struct
let f = (1.0, 2.0) // Tuple
enum U { Foo(f64, f64) } // Enum Tuple
enum V { Foo { x: f64, y: f64 } } // Enum Struct
[ 1.0, 2.0 ] // Size-2 Array
&[ 1.0, 2.0 ] // Slice
vec![1.0, 2.0] // Vec
Then possibly wrapping those in Rc, Arc, Gc, Box, Cow, Option, Result, RefCell, RefMut, Cell, OnceCell, LazyCell, UnsafeCell, Weak, and so on... that's a multiplicative product of possibilities. And you still need raw pointers for interop with C libraries.Anyways, I haven't used Rust in a few years now either, and I'm sure I've made some mistakes and omissions above, but I don't remember it as the poster child for Python's "There should be one-- and preferably only one --obvious way to do it". |
I don't know, I'm not too bothered by this. If you take struct tuple and struct, Yes synctacticqlly they are different but functionally they are quite similar. You have values lying in memory. There's no reason to prefer one to the other except convenience. Program behaviour will not change. This is not the the case for fsharp classes and records and structs. Same way Fsharp has two types of lists. It also has an array type and all these are different but they look the same. In rust case they all have different names but behaviour wise they are same: data stored in contiguous memory with some differences in what you can do with them. I do like fsharp as a language but it can't go full on its promises because of dotnet. One glaring one is nulls. The language itself claims to be null safe. Except if you use dotnet types like strings. Then the compiler doesn't warn you. Honestly Kotlin does this better with non nullable types and null chaining