6 ms·
It's not "I have no clue". It's about what do you mean by "clue", i.e. semantics discussion. I'm trying to figure out what does pjmlp really means by OOP. From
by Ygg2 2y ago
It's not "I have no clue". It's about what do you mean by "clue", i.e. semantics discussion. I'm trying to figure out what does pjmlp really means by OOP. From what I've seen, it's basically a checklist of features, and the more features you check out, the more OOP you are. What I've learned in uni was basically languages derived from Simula/Smalltalk lineage.
If you presume for a moment, pjmlp is 100% in right. Then it's difficult to find a language that isn't OOP. What is the informational contents in saying well C is OOP, Java is OOP, and Rust is OOP? I mean, you could with a straight face claim that Assembly is OOP, since it has some ad-hoc polymorphism.
Why is this important? If the informational content of a statement is low, "language is OOP" approaches the value of "language is language". An utterly useless statement.
You can say the sky is blue - that's a useful statement, based on that you can predict sunny weather. Or "sky is red" again useful, you can predict it's probably sunset. But if you say "sky is in one of visible colors", that's useless.
Is this really different from other language paradigms? I can quickly identify and recognize a structural vs non-structural language (presence of if/else/while, lack of dedicated GOTOs). But because the OOP property of language is so nebulous, it's difficult to identify it. And knowing something is OOP doesn't help you.
----
It's in my opinion, much better to look at what languages can do or can't do. With that in hand, you start to see how Rust OOP is nothing like Java/C#. And how C OOP is nothing like Rust or Java OOP.
Want to implement DOM in Rust? You're going to have a terrible time because it depends on the presence of some kind of inheritance mechanism. And that's very useful for a programmer because it's information you can use for reasoning.
- neonsunset 2y agoC# is way more similar to Rust than Java, please do not bundle it together: proper generics, async, iterator expressions, trait composition (through interfaces), extension methods, higher order functions, low-level control with `unsafe` syntax when necessary, slice types.
- Ygg2 2y agoC# the project that's basically follow up to Microsoft's failed EEE (MS Java Virtual Machine) of Java, is closer to Rust than Java? Bold statement. As Java programer that used both, adaption to C# was hours, while Rust took months if not weeks. > Proper generics Rust and C# generics are not the same. Rust uses monomorphization, C# uses reification, Java uses type erasure. > Async The syntax is the same, because Rust copied. The mechanisms aren't, but fine. Point for you. > Iterator expressions Other than syntax, not really. I do know Rust iterator are highly optimized as in bound checks are elided, but don't know enough about iterator expressions to make of this point. > Trait composition Traits and interfaces have little in common. The sooner you empty your head from such nonsense the better. As extra points Traits + Generics enable a style of programming that's not achievable in C#. Try implementing interface for type that implements another interface and doesn't implement another. Oh. Java feature is similar, albeit it uses type erasure for now. > Extension methods Rust doesn't have this. It has impl blocks and implementing traits. For example you can't implement a method for type without owning Trait or Type. > High order function Yeah it has those. Same as Java. > Unsafe block It's named similarly. But the meaning is completely different. pointer access vs undefined behavior. > Slice types. Sure.. Fair point. So you raise two and a half points. And you completely omit what makes them grossly different: ADT, monomorphic generic, lack of GC by default, trait solver, mutability xor sharing, lack of nulls...
- neonsunset 2y agoMaybe, but Java programmer would have a lot of issues the moment they go beyond regular LOB application code. Or even when they stay there, the expectation of "it's another Java" would lead to them encountering a lot of surprises. They would also use C# completely ineffectively if they would need to write performance-oriented code. Compared to that, switching from C# to Rust feels like a systems programming focused upgrade, with more than half of the moving parts being familiar the moment you get used to the syntax and understand how they map to C# concepts. And no, C# has generics, like in Rust, while Java has "generics". Generic arguments of class type in .NET result in method body sharing, yes, and represented in the generic signature as __Canon, this is quite close to dispatching by Box<dyn Trait> in Rust. On the other hand, struct generics in C# and struct generics in Rust have identical behavior codegen-wise - they are monomorphized. CoreLib and many other high-performance libraries heavily leverage this fact to make their internal and external abstractions zero-cost. For example System.Numerics.Tensors which is pure C# BLAS package: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.SoftMax.cs https://github.com/dotnet/runtime/blob/main/src/libraries/Sy... combines two operators that are then statically dispatched as it's no different than using traits in Rust save for less convenient syntax. The biggest drawback to .NET generics is that C# type system is not full Hindley-Miller + ability to specify associated types, so the generic signatures can end up being clunky. But this is not an area where work is done and future C# version will see improvements to generic type inference to reduce effort to write zero-cost abstractions and improve simplicity of generic composition. I find the mention of .NET origins as an argument unfortunate, because events that happened more than 20 years ago have no relevance whatsoever to what .NET (the non-Framework one) is today. Async mechanism is closer than you might think as Rust futures are, in a way, state machine step groups, while C# tasks are a more granular and lightweight version of Rust tasks. ValueTasks blur the line slightly due to conditional state machine box allocation. In either case this will lose relevance once runtime handled tasks project is done in one of the future versions which will change the implementation details once more. In general, if you think that low-level and performance-oriented features are comparable with Java, I'd like to ask you to look into this again. Unsafe syntax in Rust allows relaxed memory safety techniques and enables additional syntax, C# is very similar, there are differences, sure, but the latter too exposes full-blown C syntax for pointers, structs with explicit layout and fixed buffers, safe and unsafe variants of stackalloc (Rust lacks it out of box, heh) and more. It's not just pointer syntax. I could also mention FFI and how the amount of boilerplate even with the Panama project is still laughable. Writing interop for either of the two is quite comparable - declare exports/imports and map language-native types to FFI-safe, or pass them as is as if they are already, with the calls being more or less direct, possibly statically linked. Not the case with Java. C# extension methods are Rust associated functions. Also, C# has Kotlin-style nullability, but nullable structs (e.g. int?) are a sugar for Nullable<T> which is similar to Rust's Option<T>, and can be pattern matched (nullable reference types too, but because this was not built into the language at its inception, there is this divide between nullable reference and value types when it comes to type system representation, particularly felt around generics, which is unfortunate).