Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
September 05, 2013 Rust Code in the Wild | ||||
---|---|---|---|---|
| ||||
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. |
September 05, 2013 Re: Rust Code in the Wild | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | 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 |
September 05, 2013 Re: Rust Code in the Wild | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dylan Knutson | 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.
|
September 05, 2013 Re: Rust Code in the Wild | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | 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).
|
September 05, 2013 Re: Rust Code in the Wild | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jesse Phillips | 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. |
September 05, 2013 Re: Rust Code in the Wild | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | 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; } |
September 05, 2013 Re: Rust Code in the Wild | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | 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.
|
September 05, 2013 Re: Rust Code in the Wild | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | 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.
|
September 05, 2013 Re: Rust Code in the Wild | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | 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.
|
Copyright © 1999-2021 by the D Language Foundation