[rust-dev] C++ to Rust - Is that about right?

Robin Kruppe robin.kruppe at gmail.com
Mon Jul 14 12:33:40 PDT 2014


Two things I noticed:

This organization, or at least the way you present it, makes the most sense
when treating classes as your primary and (almost) only design element
("Kingdom of nouns"). While this is certainly a valid design paradigm, and
Rust should support it rather well, focusing on it is an indicator that
you're thinking in one paradigm exclusively while using in a multi-paradigm
language. This is okay, in fact expected, when coming from a
single-paradigm language (Java), or from an environment where a single
paradigm dominates (most C# and many C++ jobs and schools). It should
naturally decrease as one is exposed to other paradigms, for example by
interacting with people from such backgrounds. Just keep in mind that Rust
isn't making this hard on purpose, it just offers tools for different
(sometimes superior, sometimes inferior) designs too. These different
paradigms often give different lenses on, for example, what structs and
trait are and what belongs together into one file.

Second, the signature of MyClass::new() in your example is... unusual. The
return type unnecessarily narrow (returns a trait object instead of the
concrete type, even though callers have to know the concrete type anyway to
call new()) and does a pointless allocation as a consequence. Just return a
MyClass by value. If the call site needs polymorphism, it's trivial to add
(box MyClass::new() as Box<IMyClass>) and more flexible (can use different
smart pointers, or a borrowed reference for short-lived uses). If there are
numerous call sites and they all need need trait objects, your design MAY
be overly polymorphism-oriented for the taste of Rustaceans.

Cheers
Robin



On Mon, Jul 14, 2014 at 8:45 PM, Christoph Husse <
thesaint1987 at googlemail.com> wrote:

> Hi,
>
> I am just starting to think I have wrapped my mind around this type
> system shift introduced by rust. Now I just want to confirm that view
> to make sure I haven't missed something important.
>
> Declaring a C++ class in rust:
>
> #########################
>
> // MyMod/mod.rs - One monolythic file of all structs, enums and traits
> my "logical module" wants to define
>
> struct MyClass {
>    // all member variables go here
> }
>
> trait IMyClass {
>     // all functions (any "new" functions that is) go here
> }
>
> // MyMod/MyClass/mod.rs - Constructors and direct functions go here
>
> mod ISomeTrait;
>
> impl IMyClass for MyClass {
>     // My implementations go here
> }
>
> impl MyClass {
>     // My constructors go here
>
>     pub fn new() -> Box<IMyClass> {
>         box MyClass{} as Box<IMyClass>
>     }
> }
>
> // MyMod/MyClass/ISomeTrait.rs - Implementation of "ISomeTrait" for
> "MyClass" goes here
>
> impl ISomeTrait for MyClass {
>     // My implementation goes here
> }
>
> #########################
>
> Now I can hear the screams already :D. So I want to explain a bit
> about this choice.
>
> First, I find the rust source code I looked at so far pretty
> unstructured and confusing. Everything seems to be defined somewhere
> at will, without having a real concept (or I am just blind to see it).
>
> I think it is annoying to put exported types into submodules, because
> this will create a "use" nightmare. It is equally annoying to have
> those huge files as many rust projects have atm, by defining AND
> implementing various types in the same module.
>
> So my take on this is:
>
> 1) Use the "mod.rs" file to define all traits, enums and structs your
> module exports. This gives a clean and documented overview of what
> your modules exports, like an index... Or a previous C++ header file
> usually did.
>
> 2) Create subdirectories (if necessary) for each trait/struct defined
> in your modules, where you can distribute your implementations in a
> structured manner (like shown above). Since implementations are always
> imported (thank god) the user of your module doesn't need to create
> convoluted "use" paths to all spagetti parts of your submodule
> nightmare... And readers of your module can easily find what they are
> looking for too.
>
> 3) The "interface" naming makes most sense to me because right now I
> think that's what traits seem to be. Its a way of implementing an
> interface for classes or other interfaces that you do not control.
> Basically you are able to inject new functionality into existing types
> without having source code access to them. Which is great and reminds
> me a lot of C#'s extension methods, only that the RUST way seems much
> better...
>
> Right now the biggest issue for me is getting structure into a bigger
> rust project. Small clean files that do only few things (I don't want
> to have files bigger than a few hundred lines at MAX). But I don't
> want to have a "use" nightmare either. A "package" like in Java should
> be consumed by "use path.to.package.SomeType" which is already verbose
> enough. But for Rust this seems to mean that I have to put all my
> types into one file, which isn't exactly what I want...
>
> Maybe a lot of this is implicitly covered by the tutorial but for all
> of us who come from languages like Java, C++ and C#, I think its hard
> to really wrap around this "new" concept.
>
> Any comments ;)?
> Thanks
> _______________________________________________
> Rust-dev mailing list
> Rust-dev at mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140714/e6fd3245/attachment.html>


More information about the Rust-dev mailing list