www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Rust Code in the Wild

reply "Meta" <jared771 gmail.com> writes:
While browsing Hacker News I came across this announcement of a 
physics engine written in Rust. Just browsing through the code, I 
noticed that it looks extremely arcane. I guess after awhile it's 
something you could get used to, but it seems somewhat ironic 
that the author says that C++ will die of ugliness, when Rust 
already has syntactic monstrosities such as these:

pub struct BodyWorld<N, LV, AV, M, II, CM> {
     world: World<N, Body<N, LV, AV, M, II>, Constraint<N, LV, AV, 
M, II>>,
     forces:  mut BodyForceGenerator<N, LV, AV, M, II>,
     integrator:  mut BodySmpEulerIntegrator<N, LV, AV, M, II>,
     detector:  mut BodiesBodies<N, LV, AV, M, II, BF<N, LV, AV, 
M, II>>,
     sleep:  mut IslandActivationManager<N, LV, AV, M, II>,
     ccd:  mut SweptBallMotionClamping<N, LV, AV, M, II, BF<N, LV, 
AV, M, II>>,
     joints:  mut JointManager<N, LV, AV, M, II>,
     solver:  mut AccumulatedImpulseSolver<N, LV, AV, M, II, CM>
}

This stuff is downright arcane. I'd say that D is in a far better 
situation right now in regard to being syntactically easy to 
parse and understand for the average coder.
Sep 04 2013
next sibling parent "Dylan Knutson" <tcdknutson gmail.com> writes:
On Thursday, 5 September 2013 at 03:22:17 UTC, Meta wrote:
 While browsing Hacker News I came across this announcement of a 
 physics engine written in Rust. Just browsing through the code, 
 I noticed that it looks extremely arcane. I guess after awhile 
 it's something you could get used to, but it seems somewhat 
 ironic that the author says that C++ will die of ugliness, when 
 Rust already has syntactic monstrosities such as these:

 pub struct BodyWorld<N, LV, AV, M, II, CM> {
     world: World<N, Body<N, LV, AV, M, II>, Constraint<N, LV, 
 AV, M, II>>,
     forces:  mut BodyForceGenerator<N, LV, AV, M, II>,
     integrator:  mut BodySmpEulerIntegrator<N, LV, AV, M, II>,
     detector:  mut BodiesBodies<N, LV, AV, M, II, BF<N, LV, AV, 
 M, II>>,
     sleep:  mut IslandActivationManager<N, LV, AV, M, II>,
     ccd:  mut SweptBallMotionClamping<N, LV, AV, M, II, BF<N, 
 LV, AV, M, II>>,
     joints:  mut JointManager<N, LV, AV, M, II>,
     solver:  mut AccumulatedImpulseSolver<N, LV, AV, M, II, CM>
 }

 This stuff is downright arcane. I'd say that D is in a far 
 better situation right now in regard to being syntactically 
 easy to parse and understand for the average coder.

Somewhat related; just yesterday an individual on the rust-dev mailing list started a discussion on how to neatly format complex types: https://mail.mozilla.org/pipermail/rust-dev/2013-September/005457.html
Sep 04 2013
prev sibling next sibling parent "Meta" <jared771 gmail.com> writes:
On Thursday, 5 September 2013 at 03:46:41 UTC, Dylan Knutson 
wrote:
 Somewhat related; just yesterday an individual on the rust-dev 
 mailing list started a discussion on how to neatly format 
 complex types:

 https://mail.mozilla.org/pipermail/rust-dev/2013-September/005457.html

I'm subscribed to the Rust mailing list, and I remember seeing that email. I think they have a bigger problem, though. There's just too many damn symbols. Some of the more complex code is almost like reading hieroglyphics.
Sep 04 2013
prev sibling next sibling parent "Jesse Phillips" <Jesse.K.Phillips+D gmail.com> writes:
On Thursday, 5 September 2013 at 03:22:17 UTC, Meta wrote:
 pub struct BodyWorld<N, LV, AV, M, II, CM> {
     world: World<N, Body<N, LV, AV, M, II>, Constraint<N, LV, 
 AV, M, II>>,
     forces:  mut BodyForceGenerator<N, LV, AV, M, II>,
     integrator:  mut BodySmpEulerIntegrator<N, LV, AV, M, II>,
     detector:  mut BodiesBodies<N, LV, AV, M, II, BF<N, LV, AV, 
 M, II>>,
     sleep:  mut IslandActivationManager<N, LV, AV, M, II>,
     ccd:  mut SweptBallMotionClamping<N, LV, AV, M, II, BF<N, 
 LV, AV, M, II>>,
     joints:  mut JointManager<N, LV, AV, M, II>,
     solver:  mut AccumulatedImpulseSolver<N, LV, AV, M, II, CM>
 }

 This stuff is downright arcane. I'd say that D is in a far 
 better situation right now in regard to being syntactically 
 easy to parse and understand for the average coder.

I don't really know Rust, but is D really any better. It looks like you are defining variables with templated types: struct BodyWorld(N, LV, AV, M, II, CM) { World!(N, Body!(N, LV, AV, M, II), Constraint!(N, LV, AV, M, II)) world; ... There has been some Rust code I've seen where a few symbols populate most of the code (GC something something). As an outsider it looks really horrible, but it did seem to convey useful information had I known what things meant. Math is another example of this, symbols provide great detail with little said; and it is horrible, because without continues use, someone somewhere is going to use a symbol you'd forgotten even existed (they have the nice benefit of being well defined from centuries of use though).
Sep 04 2013
prev sibling next sibling parent "David Eagen" <davideagen mailinator.com> writes:
I've briefly looked at Rust and so far the pointer ownership 
system is the only thing that appeals to me. If that could be 
somehow integrated in D it would be great. If I recall, a similar 
system was proposed for D by Bartosz Milewski.
Sep 05 2013
prev sibling next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 09/05/2013 05:22 AM, Meta wrote:
 While browsing Hacker News I came across this announcement of a physics
 engine written in Rust. Just browsing through the code, I noticed that
 it looks extremely arcane. I guess after awhile it's something you could
 get used to, but it seems somewhat ironic that the author says that C++
 will die of ugliness, when Rust already has syntactic monstrosities such
 as these:

 pub struct BodyWorld<N, LV, AV, M, II, CM> {
      world: World<N, Body<N, LV, AV, M, II>, Constraint<N, LV, AV, M, II>>,
      forces:  mut BodyForceGenerator<N, LV, AV, M, II>,
      integrator:  mut BodySmpEulerIntegrator<N, LV, AV, M, II>,
      detector:  mut BodiesBodies<N, LV, AV, M, II, BF<N, LV, AV, M, II>>,
      sleep:  mut IslandActivationManager<N, LV, AV, M, II>,
      ccd:  mut SweptBallMotionClamping<N, LV, AV, M, II, BF<N, LV, AV,
 M, II>>,
      joints:  mut JointManager<N, LV, AV, M, II>,
      solver:  mut AccumulatedImpulseSolver<N, LV, AV, M, II, CM>
 }

 This stuff is downright arcane.

Why? I cannot spot any syntax I wouldn't get used to quickly in this example. (AFAIK the are going away in favour of a library solution with more verbose syntax though.) In D something similar would look like this: struct BodyWorld(N, LV, AV, M, II, CM){ World!(N, Body!(N, LV, AV, M, II), Constraint!(N, LV, AV, M, II)) world; BodyForceGenerator!(N, LV, AV, M, II)* forces; BodySmpEulerIntegrator!(N, LV, AV, M, II)* integrator; BodiesBodies!(N, LV, AV, M, II, BF!(N, LV, AV, M, II))* detector; IslandActivationManager!(N, LV, AV, M, II)* sleep; SweptBallMotionClamping!(N, LV, AV, M, II, BF!(N, LV, AV, M, II))* ccd; JointManager!(N, LV, AV, M, II)* joints; AccumulatedImpulseSolver!(N, LV, AV, M, II, CM)* solver; } Afaics there is not much of a difference. Arguably, having the identifiers conveniently aligned to the left is actually a slight advantage of rust's syntax. Of course, the code contains a certain amount of duplication I wouldn't really want to write down, and this could be improved in D: struct BodyWorld(N, LV, AV, M, II, CM){ private alias Args = Seq!(N, LV, AV, M, II); World!(N, Body!Args, Constraint!Args) world; BodyForceGenerator!Args* forces; BodySmpEulerIntegrator!Args* integrator; BodiesBodies!(Args, BF!Args)* detector; IslandActivationManager!Args* sleep; SweptBallMotionClamping!(Args, BF!Args)* ccd; JointManager!Args* joints; AccumulatedImpulseSolver!(Args, CM)* solver; }
Sep 05 2013
prev sibling next sibling parent "Dicebot" <public dicebot.lv> writes:
On Thursday, 5 September 2013 at 13:50:59 UTC, Timon Gehr wrote:
 Of course, the code contains a certain amount of duplication I 
 wouldn't really want to write down, and this could be improved 
 in D:

 struct BodyWorld(N, LV, AV, M, II, CM){
     private alias Args = Seq!(N, LV, AV, M, II);

     World!(N, Body!Args, Constraint!Args)    world;
     BodyForceGenerator!Args*                 forces;
     BodySmpEulerIntegrator!Args*             integrator;
     BodiesBodies!(Args, BF!Args)*            detector;
     IslandActivationManager!Args*            sleep;
     SweptBallMotionClamping!(Args, BF!Args)* ccd;
     JointManager!Args*                       joints;
     AccumulatedImpulseSolver!(Args, CM)*     solver;
 }

This actually a pretty good highlight how even simplest compile-time facilities can make code much more readable and maintainable. If proxying is all it does, using variadic template parameters may be even better. But I tend to agree. I don't see anything inherently wrong with Rust syntax here other than lacking (not using?) better meta facilities.
Sep 05 2013
prev sibling next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Thursday, 5 September 2013 at 13:50:59 UTC, Timon Gehr wrote:
 On 09/05/2013 05:22 AM, Meta wrote:
 While browsing Hacker News I came across this announcement of 
 a physics
 engine written in Rust. Just browsing through the code, I 
 noticed that
 it looks extremely arcane. I guess after awhile it's something 
 you could
 get used to, but it seems somewhat ironic that the author says 
 that C++
 will die of ugliness, when Rust already has syntactic 
 monstrosities such
 as these:

 pub struct BodyWorld<N, LV, AV, M, II, CM> {
     world: World<N, Body<N, LV, AV, M, II>, Constraint<N, LV, 
 AV, M, II>>,
     forces:  mut BodyForceGenerator<N, LV, AV, M, II>,
     integrator:  mut BodySmpEulerIntegrator<N, LV, AV, M, II>,
     detector:  mut BodiesBodies<N, LV, AV, M, II, BF<N, LV, 
 AV, M, II>>,
     sleep:  mut IslandActivationManager<N, LV, AV, M, II>,
     ccd:  mut SweptBallMotionClamping<N, LV, AV, M, II, BF<N, 
 LV, AV,
 M, II>>,
     joints:  mut JointManager<N, LV, AV, M, II>,
     solver:  mut AccumulatedImpulseSolver<N, LV, AV, M, II, CM>
 }

 This stuff is downright arcane.

Why? I cannot spot any syntax I wouldn't get used to quickly in this example. (AFAIK the are going away in favour of a library solution with more verbose syntax though.) In D something similar would look like this: struct BodyWorld(N, LV, AV, M, II, CM){ World!(N, Body!(N, LV, AV, M, II), Constraint!(N, LV, AV, M, II)) world; BodyForceGenerator!(N, LV, AV, M, II)* forces; BodySmpEulerIntegrator!(N, LV, AV, M, II)* integrator; BodiesBodies!(N, LV, AV, M, II, BF!(N, LV, AV, M, II))* detector; IslandActivationManager!(N, LV, AV, M, II)* sleep; SweptBallMotionClamping!(N, LV, AV, M, II, BF!(N, LV, AV, M, II))* ccd; JointManager!(N, LV, AV, M, II)* joints; AccumulatedImpulseSolver!(N, LV, AV, M, II, CM)* solver; } Afaics there is not much of a difference. Arguably, having the identifiers conveniently aligned to the left is actually a slight advantage of rust's syntax. Of course, the code contains a certain amount of duplication I wouldn't really want to write down, and this could be improved in D: struct BodyWorld(N, LV, AV, M, II, CM){ private alias Args = Seq!(N, LV, AV, M, II); World!(N, Body!Args, Constraint!Args) world; BodyForceGenerator!Args* forces; BodySmpEulerIntegrator!Args* integrator; BodiesBodies!(Args, BF!Args)* detector; IslandActivationManager!Args* sleep; SweptBallMotionClamping!(Args, BF!Args)* ccd; JointManager!Args* joints; AccumulatedImpulseSolver!(Args, CM)* solver; }

That's a pretty clear win for D, although there may be a way to do something similar in rust.
Sep 05 2013
prev sibling parent "Meta" <jared771 gmail.com> writes:
On Thursday, 5 September 2013 at 13:50:59 UTC, Timon Gehr wrote:
 Why? I cannot spot any syntax I wouldn't get used to quickly in 
 this example. (AFAIK the   are going away in favour of a 
 library solution with more verbose syntax though.)

 In D something similar would look like this:

 struct BodyWorld(N, LV, AV, M, II, CM){
     World!(N, Body!(N, LV, AV, M, II), Constraint!(N, LV, AV, 
 M, II)) world;
     BodyForceGenerator!(N, LV, AV, M, II)* forces;
     BodySmpEulerIntegrator!(N, LV, AV, M, II)* integrator;
     BodiesBodies!(N, LV, AV, M, II, BF!(N, LV, AV, M, II))* 
 detector;
     IslandActivationManager!(N, LV, AV, M, II)* sleep;
     SweptBallMotionClamping!(N, LV, AV, M, II, BF!(N, LV, AV, 
 M, II))* ccd;
     JointManager!(N, LV, AV, M, II)* joints;
     AccumulatedImpulseSolver!(N, LV, AV, M, II, CM)* solver;
 }

 Afaics there is not much of a difference. Arguably, having the 
 identifiers conveniently aligned to the left is actually a 
 slight advantage of rust's syntax.

 Of course, the code contains a certain amount of duplication I 
 wouldn't really want to write down, and this could be improved 
 in D:

 struct BodyWorld(N, LV, AV, M, II, CM){
     private alias Args = Seq!(N, LV, AV, M, II);

     World!(N, Body!Args, Constraint!Args)    world;
     BodyForceGenerator!Args*                 forces;
     BodySmpEulerIntegrator!Args*             integrator;
     BodiesBodies!(Args, BF!Args)*            detector;
     IslandActivationManager!Args*            sleep;
     SweptBallMotionClamping!(Args, BF!Args)* ccd;
     JointManager!Args*                       joints;
     AccumulatedImpulseSolver!(Args, CM)*     solver;
 }

Just looking at the code, it looks very dense. The multiple nested <> brackets (D was right to get rid of these) and the mut really bog down the code (I am aware that mut has been moved to a library solution now). Like I said, Rust coders no doubt get used to parsing and understanding the different symbols, but to an outsider it's a lot to take in. Note that this is only one example. I found several other instances such as this in the codebase that were difficult to make sense of at first. The thing that trips me up the most, I think, are the lifetimes.
Sep 05 2013