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 reply "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
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 reply "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
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 parent reply 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
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