fanf: (Default)
[personal profile] fanf

Having tried to make practical use of my multivector multiply, I'm adding a health warning to my notes on vanishing zeroes. (This is my shamefaced grin.)

There's a general rule with Rust that if the compiler is making things hard for you, it's usually right, and you should pay attention.

The problem with my type system hackery is kind of right there in my description of what was difficult about making it work: the requirements in the trait bounds have to be spelled out in full.

I had trouble with the enormous trait bounds that I needed in order to use the small Zero and Num overloads; the same trouble will occur, but bigger, for anyone who tries to use the overloaded multivector multiply in a generic way.

This means that application code will only be tolerable if it uses concrete types at function boundaries, and avoids generic overloading except to support type inference within functions. This is not very far from what I had in mind, but less flexible.

It's worse for mid-level code which provides higher-level multivecor operations. I wanted to combine generic multivector primitives into generic higher-level operations, but the types make this too awful to contemplate. It might be possible to rescue it by extending the wide-and-shallow approach to these operations, i.e. define them all in the same style as multiplication.

So it's sad and somewhat embarrassing that it didn't work out, but I did learn quite a lot about Rust in the process :-)

Anyway, after reflecting on my mistakes, I'm putting this aside for now, and I'm circling around to vector in on my 3D graphics project from another angle.

Date: 2020-12-08 16:50 (UTC)
simont: A picture of me in 2016 (Default)
From: [personal profile] simont
Anyway, after reflecting on my mistakes, I'm putting this aside for now, and I'm circling around to vector in on my 3D graphics project from another angle.

groan4 :-)

Date: 2020-12-08 20:14 (UTC)
jack: (Default)
From: [personal profile] jack
Ah! Seeing this follow up I went back to read the first post in a bit more detail. I asked myself, if I'd been doing that in C++, what would I have done, and then I followed a lot further through the explanation :)

Yeah, I see. I feel like you *should* be able to do this. In this case, this is clearly library-implementation-magic, but you might well want to multiply an arbitrarily-shaped vector of an arbitrary number-ish type -- you might usually expect that if you're doing number theory the types of each element would be homogeneous, but they might legitimately some weirder configuration. The ability to just say, "regardless of what you put in it, if they implement the * and + operators necessary to perform the calculation, it should work" feels sensible. I think in C++ it would be, you don't have to (and usually couldn't) specify the types needed to be Mul except by multiplying them.

I don't follow it enough to know if rust will get better at inferring or not, and if it did, if the excessive compile time overhead will be reduced or not.

I have the feeling that I always have when I try to do something generic in a language: "surely there's a way to do this." But usually sooner or later I've plumbed the abilities of the language and there just isn't and everyone is used to doing without.

Date: 2020-12-11 09:48 (UTC)
pndc: (Default)
From: [personal profile] pndc
What makes libraries like this trickier and more tedious to write in Rust (but also more likely to be correct and useful) is that (*handwave*) Rust generics are type checked at declaration time, whereas C++ does it at use time. C++ generics feel rather more like macros than generics at times.

Date: 2020-12-12 11:50 (UTC)
jack: (Default)
From: [personal profile] jack
That makes sense. Specifying the type in a generic class might be analogous to specifying the type of a function argument: if you only use it one or two places (as I mostly did with C++ generics), it's less trouble to accept anything and debug problems as they occur, but as you use it more often, it's increasingly superior to get an error as soon as you use the wrong type, rather than buried in the implementation when it tries to use it.

But that said, "this class can be genericised with any numeric types that support addition and multiplication" seems like a reasonable use case; it might well make sense to have multiple related types and manage the conversions where the different types meet, rather than as soon as they're included at all.

June 2025

S M T W T F S
1234567
8 91011121314
15161718192021
22232425262728
2930     

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated 2025-06-11 19:35
Powered by Dreamwidth Studios