Comment by flohofwoe

Comment by flohofwoe a day ago

10 replies

> You put "just" in scare quotes

...I don't use them as "scare quotes", it's more like in "can't you just..." - e.g. something that looks simple from the outside but is hard to do / complex on the inside - e.g. I do recognize the work that went into Rust's memory safety, but I question the effort that went into it compared to more traditional memory safety methods, especially when looking at the restrictions that Rust imposed on the programmer - it's a pretty hefty tradeoff (IMHO of course).

> What bad ideas from C++ did Rust copy, in your opinion?

Mainly doing things in the stdlib that should be built into the language (e.g. Option, Result, Box, Cell, RefCell, Arc, and probably a dozen other types and traits...), resulting in what I call 'bird droppings syntax' of too many chained function calls to get to the thing you actually want (.unwrap, .into_iter, .iter, .iter_mut, .as_ref, .as_mut, .expect, .unwrap_or_else, .unwrap_or_default, .ok, .ok_or_else, .and_then, .or_else ... like, wtf?). The absurd amount of `::` and `<>` in typical Rust code. The missing separation line between stdlib and language (like for-loops using the Iterator trait, or more obviously: operator overloading). The stdlib doing memory allocations behind your back through a global allocator - which we know from C++ do be a really bad idea for decades already... etc etc... I think most Rust programmers are blind towards those issues the same way that C++ programmers are blind towards C++ issues (which is another thing both language ecosystems have in common though).

simonask a day ago

I mean, there's no winning here. Either the language is too complex and does too many things, or it's not complex enough and relegates fundamental things to the standard library.

I don't thing there is any substantial difference between `Option<Thing>` and `@Nullable Thing` or `Thing | null`, I don't think there's anything wrong with choosing `::` over `.` for namespace resolution (it means you can have local variables with the same name as a module), and you have to have some way to declare generic parameters.

Rust generally does not allocate behind your back, but custom allocators is a work in progress. The reason it takes time is precisely that they want to avoid the mistakes of C++. A couple of mistakes were already avoided - for example, async/await in Rust does not allocate behind your back, while C++ coroutines do.

  • tialaramex a day ago

    > I don't thing there is any substantial difference between `Option<Thing>` and `@Nullable Thing` or `Thing | null`

    I object to @Nullable and similar arrangements as a magic special case. If the sum types only solved this one issue then it's a wash but they do a lot more too.

    Either of the sum types, the concrete `Option<Thing>` or the ad hoc `Thing | null` are OK because they're not magic, less magic is better.

    • simonask a day ago

      I’m confused. You seem to think Option is magical? It is not, and neither is Result. They are regular sum types defined in the standard library, nothing special about them.

      • tialaramex a day ago

        That's certainly not what I was trying to get across. Perhaps I wrote something confusing, for which I apologise, but, since we're here anyway...

        Technically Option is actually magic, though it's for a subtle reason unconnected to the current topic. If you go read its source Option is a langitem, that is, Rust literally isn't allowed to exist without this type. Rust's core libraries are defined, so you shouldn't and most people never will use Rust without them, but the Rust language actually doesn't require that all of core exists, it does require a handful of types, functions etc. and those are called "langitems".

        So, why is Option a langitem? Well, Rust's language has for-each loops. But what it actually does (there's literally a compiler step doing this) is treat those loops as if they'd been written as a slightly clunky loop { } block making and then consuming an Iterator. To do that the IntoIterator and Iterator traits must exist, and further as the return type from the next call needed in Iterator is an Option the Option generic type must exist too!

        Technically this type wouldn't have to be called Option, the Rust compiler doesn't care what it is called, but it must exist or else the compiler doesn't know how a for-each loop can work.

  • throwawaymaths a day ago

    doesn't the llvm coroutines require c's malloc? this is part of the reason why zig scrapped async. i would suspect Rust's async/await does allocate behind your back