4 ms·
You should never write code that's impossible to understand without fancy IDE features. If you're writing such code, the best thing you can do for yourself long
by alexvitkov 2y ago
You should never write code that's impossible to understand without fancy IDE features. If you're writing such code, the best thing you can do for yourself long term is switch to a text editor without LSP (read Notepad) right now, which will force you to start writing sane code.
This is true for any language, but it's especially true for C++, where most large codebases have tons of invisible code flying around - implicit casts, weird overloads, destructors, all of these possibly virtual calls, possibly over type-erased objects accessed accessed via smart pointers, possibly over many threads - if you want to stand any chance of even beginning to reason about all that you NEED to see the actual, concrete, scientific types of things.
- Jyaif 2y ago> You should never write code that's impossible to understand without fancy IDE features with Rust that ship has sailed
- jeltz 2y agoI code Rust just fine without any fancy IDE you should give it a shot. The languages I find hardest to code without fancy IDE features are C and C++ due to their implicit casts. Rust is typically easy to code without IDE features due to its strong type system, lifetimes and few implicit casts.
- zbentley 2y agoRust is one of my favorite new languages, but this is just wrong. > few implicit casts Just because it doesn't (often) implicitly convert/pun raw types doesn't mean it has "few implicit casts". Rust has large amounts implicit conversion behavior (e.g. deref coercion, implicit into), and semi-implicit behavior (e.g. even regular explicit ".into()" distances conversion behavior and the target type in code). The affordances offered by these features are significant--I like using them in many cases--but it's not exactly turning over a new leaf re: explicitness. Without good editor support for e.g. figuring out which "into" implementation is being called by a "return x.into()" statement, working in large and unfamiliar Rust codebases can be just as much of a chore as rawdogging C++ in no-plugins vim. Like so many Rust features, it's not breaking with specific semantics available in prior languages in its niche (C++); rather, it's providing the same or similar semantics in a much more consciously designed and user focused way. > lifetimes How do lifetimes help (or interact with) IDE-less coding friendliness? These seem orthogonal to me. Lastly, I think Rust macros are the best pro-IDE argument here. Compared to C/C++, the lower effort required (and higher quality of tooling available) to quickly expand or parse Rust macros means that IDE support for macro-heavy code tends to be much better, and much better out of the box without editor customization, in Rust. That's not an endorsement of macro-everything-all-the-time, just an observation re: IDE support.
- jeltz 2y agoHave you actually tried coding Rust without IDE support? I have. I code C and Rust professionally with basically only syntax highlighting. As for how lifetimes help? One of the more annoying parts of coding C is to constantly have to look up who owns a returned pointer. Should it be freed or not? And I do not find into() to be an issue in practice.
- adrian_b 2y agoWhile the C language has a lot of bad implicit casts that should have never been allowed, mainly those involving unsigned types, and which have been inherited by its derivatives, implicit casts as a programming language feature are extremely useful when used in the right way. Implicit casts are the only reason for the existence of the object-oriented programming languages, where any object can be implicitly cast to any type from which it inherits, so it can be passed as an argument to any function that expects an argument of that type, including member functions. The whole purpose of inheritance is to allow the programmer to use implicit casts. Otherwise, one would just declare a structure member of the class from which one would inherit in the OOP style and a virtual function table pointer, and one could write an identical program with the OOP program, but in a much more verbose way. (In the C language, not only the implicit mixed signed-unsigned casts are bad, but also any implicit unsigned-unsigned casts are bad, because there are 2 interpretations of "unsigned" frequently used in programs, as either non-negative numbers or as modular numbers, and the direction of the casts that do not lose information is reversed for the 2 interpretations, i.e. for non-negative numbers it is safe to cast only to a wider type, but for modular numbers it is safe to cast only to a narrower type. Moreover, there are also other interpretations of "unsigned", i.e. as binary polynomials or as binary polynomial residues, which cannot be inter-converted with numbers. For all these 4 interpretations, there are distinct machine instructions in the instruction sets of popular CPUs, e.g. in the x86-64 and Aarch64 ISAs, which may be used in C programs through compiler intrinsics. Even worse is that the latest C standards specify that the overflow behavior of "unsigned" is that of modular numbers, while the implicit casts of "unsigned" are those of non-negative numbers. This inconsistency guarantees the existence of perfectly legal C programs, without any undefined behavior, but which nonetheless compute incorrect "unsigned" values, regardless which interpretation was intended for "unsigned".)
- AlotOfReading 2y ago"Non-negative" unsigneds can be validly cast to smaller types. That's why saturating_cast() exists. There are modular numbers where casting to a smaller value is likewise unsafe at a logical level. Your LCRNG won't give you the right period when downcast, even if the modulus value is unchanged.
- 2y ago
- deleted 2y ago[deleted]