Live data from Hacker News

Why I rewrote the mesh generator of Dust3D from Rust to C++

blogs.dust3d.org

211–220 of 283 posts

Re: Why I rewrote the mesh generator of Dust3D from Rust to C++

#211

Three problems with this: 1. You still have to fight with borrow checking in Rust as in C++, it’s just not automated. You have to consider moves and copies, borrowed references, etc. As the author points out, if you’re used to writing C or C++, it’s going to take a while before responding to the borrow checker is second nature. The point is that the borrow checker is a computer and doesn’t make mistakes the same way…

> Also, Rust is an open source ecosystem, and people using it should feel compelled to consider writing the missing pieces they need for the benifit of the community. It’s also odd to say that Rust doesn’t have what you need, it sounds like there are C libraries that already do what you want, and Rust can wrap C.

This sounds like a great idea, but not everyone has the time and resources to port libraries from one language to another. It should be trivial to wrap C libraries, but errors do show up, and a once one day task now takes a week to iron out. If you have 4 or 5 libraries that are missing, you've now lost a month of development work that could have been spent adding new features.

Additionally, not everyone wants to maintain open source projects. There's a huge amount of responsibility that comes with being a maintainer, and the OSS community isn't always a friendly, fun place. Rachel has some great examples in her blog [1].

[1]: https://rachelbythebay.com/w/2018/10/09/moat/

Re: Why I rewrote the mesh generator of Dust3D from Rust to C++

#212

Earlier quoted context omitted.

> The downside that the author points out seem to be often neglected. Constant interruption and battling with the type system during development, when mental overhead is a problem. Dunno about Rust specifically, but I have written a little Haskell, and a significant amount of OCaml. I found that the type system reduces my cognitive overhead, compared to looser languages like Python or Lua. The compiler is disciplined…

I worked professionally in Haskell for a long time and I cannot disagree with you more. This is always the promise of strict functional languages but in a business setting where the very nature of what you build has to be arbitrarily mutable at the whim of competing interests between stakeholders, engineers, customers, etc., it just doesn’t work. You end up with the same spaghetti code messes, unexpected runtime erro…

> in a business setting where the very nature of what you build has to be arbitrarily mutable—

I just don't use Haskell there. I personally use OCaml for my data in, data out problems (compilers, generators…), but for inherently interactive and mutable stuff I just do imperative programming. Of course the type system (and the performance characteristics of the runtime!) must be suited to the problem domain.

> burying details deep in type class patterns, relying on dozens of special case compiler directives to enhance Haskell...

Looks like someone went overboard. I think you (your team?) should have been more conservative with the compiler directives, and less abstraction loving with the type classes.

Re: Why I rewrote the mesh generator of Dust3D from Rust to C++

#213
post #206

Earlier quoted context omitted.

It was first for a bank, later for a data analytics start-up, and then also for an education technology company. I had many skilled functional programmers on my team too, including a few people who had done work on GHC itself. I’ve also see code messes in many languages. It’s a business culture problem, has nothing to do with the language or paradigm. I’ll greatly dispute with about Python though. It has been a langu…

Very interesting. I suspect we may even have worked for the same bank! I'd love to discover how we came to such opposing conclusions. To give you a Python example, it encourages stuff like: def send_email(recipients, contents): if type(recipients) == str: send_one_email(recipients, contents) else: for recipient in recipients: send_one_email(recipient, contents) That is a flavour of convenience that people commonly im…

I disagree very much. The Pythonic way would be to do something like map(send_email, list_of_addresses), and have send_email raise an exception if not passed precisely a single string, and presumable raise exceptions when you validate that the email address is of an acceptable format, etc.

It would not be Pythonic to make the function superficially handle different arities of argument through explicit handling on the list type with isinstance, precisely because you’d need to handle different meanings of different types that implement the Iterator Protocol. That’s not something Python generally encourages, it’s just a mistaken implementation. And particularly not making careless assumptions when basing branches on isinstance behavior (for example, you could always encounter custom classes that have overridden __instancecheck__ or __subclasshook__ special methods.

Re: Why I rewrote the mesh generator of Dust3D from Rust to C++

#214

Earlier quoted context omitted.

I found that strict compile time checks speed up my exploratory phase. That's because the type system provide an even tighter feedback loop than a REPL, and effectively cuts down the search space. Other people seem to have experienced the opposite, though. I have no idea why.

To me, the question is whether the time spent dealing with compiler errors is due to fixing real problems that the compiler is pointing out, or whether that work is mostly reworking a correct program to satisfy the compiler when it cannot yet see that the program is correct.

I don't think humans have anything major in their toolkit for reasoning about memory management / aliasing that the Rust compiler doesn't; when non-trivial code cannot be expressed in terms of single-ownership at any given point, code loses correctness-at-a-glance. There are cases where a safe Rust abstraction is built on unsafe code, including most of Rust's collections; the API contract of every stdlib collection is: the collection owns its elements. Interestingly, such a contract can generally be implemented safely, but would have different performance characteristics; e.g. doubly-linked List could use indexes into a Vec. This example mirrors a pattern seen in languages that discourage mutation: break the rules internally for performance optimizations, but maintain the invariants at API boundaries to contain the cognitive overhead. Even when Rust's rules need to be broken, they are useful to contain complexity.

Re: Why I rewrote the mesh generator of Dust3D from Rust to C++

#215
post #206

Earlier quoted context omitted.

Very interesting. I suspect we may even have worked for the same bank! I'd love to discover how we came to such opposing conclusions. To give you a Python example, it encourages stuff like: def send_email(recipients, contents): if type(recipients) == str: send_one_email(recipients, contents) else: for recipient in recipients: send_one_email(recipient, contents) That is a flavour of convenience that people commonly im…

I disagree very much. The Pythonic way would be to do something like map(send_email, list_of_addresses), and have send_email raise an exception if not passed precisely a single string, and presumable raise exceptions when you validate that the email address is of an acceptable format, etc. It would not be Pythonic to make the function superficially handle different arities of argument through explicit handling on the…

It's certainly a poor use of Python's flexibility, but I've seen that kind of thing written at two completely different companies by completely different, yet smart, people so I suspect it's prevalent. Haskell does a much better job of nudging smart people to write good code. Gabriel Gonzalez explained it better than I could: http://www.haskellforall.com/2016/04/worst-practices-should-...

Re: Why I rewrote the mesh generator of Dust3D from Rust to C++

#216
post #150

Earlier quoted context omitted.

Actually they do, because Blueprints need to support graphical debugging and profiling as well. Some studios don't want to mess that much with Unreal's C++. Then Unreal has their own C++ runtime to allow for a tracing GC.

Still, Epic does not have to commit the same amount of resources. That is my point. The Unreal Build Tool and Unreal Header Tool do not come for free, but this is still less than two sets of optimizing compilers in my book.

IL2CPP resuses the platform C++ compiler, and Burst builds up on LLVM.

It is not like Unity is building their compilers from scratch.

And the fact that the Insomiatic guys felt it was a good project speaks for it, given how they are respected in the gaming industry regarding engine optimization.

Also some of this work influenced C# 7.x features.

Re: Why I rewrote the mesh generator of Dust3D from Rust to C++

#217
post #161

Earlier quoted context omitted.

Depending on the situation a write unsafe fast fix later maybe the more economic approach. Especially if the code is more exploratory, changes a lot and large parts will be finally discarded.

I've found that more often, it should be reworded as "unsafe fast, painfully maintain without the resources to ever fix later".

The number of TODO's that litter code in general, or issues file to "cleanup" are generally significant. You're making a great point that accruing technical debt at the cost of safety, is quite possibly technical debt, like all other, that will never be paid down over the life of the software.

I completely agree.

Re: Why I rewrote the mesh generator of Dust3D from Rust to C++

#218

Earlier quoted context omitted.

> I don't care if the author is a Rust expert or total newb. Someone who can write a 3D modeler in C++ is someone who should be able to use any new Algol-derived language with ease in short time, regardless if they hasn't seen a line of code in that language before. This statement is absurd. It implies that you believe that there are only cosmetic differences between languages, that no language can ever introduce any…

> This statement is absurd. It implies that you believe that there are only cosmetic differences between languages, that no language can ever introduce any useful new concepts. Well, the fact that you've missed the whole "Algol-derived language" is more absurd to me. Rust, in the end, is C++-streamlined plus fighting with the borrow checker. Not some huge new paradigm shift in how we construct programs (as would be e…

> In an ideal world, Rust's lifetime management would be automatically derived by the compiler (in several cases, when it's simple, it already is).

This is exactly the type of work that's gone into the language over the last few years. It's actually quite rare with non-lexical lifetimes (and the advancements before it) that you need to explicitly call out the lifetimes anymore.

I think the language is moving in the direction you want.

Re: Why I rewrote the mesh generator of Dust3D from Rust to C++

#219

Earlier quoted context omitted.

Are you suggesting that Rust is not as safe as it claims? Or that C++ is as safe as Rust? There’s a lot of research to disagree with either of those positions.

No, not at all. Rust is a very good tool and is useful in many situations. I believe it offers better automatic memory safety. However, there are many cases when Rust is not a good tool for the job, and when specifically having greater manual control of memory or thread safety is a better choice. Additionally, in many applications you can build almost everything in a fully dynamically typed language, often interprete…

A vocal and significant fraction of any community of reasonable size is going to be populated by blowhards.

Re: Why I rewrote the mesh generator of Dust3D from Rust to C++

#220
post #74

Earlier quoted context omitted.

And are proposing it alongside C# and Core Guidelines compliant C++ for new systems software.

Do you have a link?

Sure. Check the presentation slides.

https://github.com/Microsoft/MSRC-Security-Research/tree/mas...

Post reply on HN