News for hackers. Stuff that matters.
Re:Rewriting Libimagequant in Rust for Portability by roblabla on Tuesday January 04, 2022 @09:55AM (#29795407)
> Trying to make the library more object-oriented exposed a "drum-stick" design issue: does play(drum, stick) translate to drum.play(stick) or stick.hit(drum)?

In cases where OO doesn't make sense, the solution is to simply provide a functional API instead. Rust stdlib has plenty of such APIs, it's fine to have free-standing functions!

Re:Rewriting Libimagequant in Rust for Portability by ape4 on Tuesday January 04, 2022 @10:17AM (#29795635)
Agree, there's no rule that everything has to be a class in C++.

I suppose drum.play() could default to using a stick.

Re:Rewriting Libimagequant in Rust for Portability by mikepurvis on Tuesday January 04, 2022 @11:34AM (#29796674)
I think the GP's idea is to just do play(drum, stick) as its own function and not tie it to either class or have it be a passthru into internal methods for either.
Re:Rewriting Libimagequant in Rust for Portability by nine_k on Tuesday January 04, 2022 @10:49AM (#29796044)
You can even make everything a class, and still provide a functional-ish interface, by using the class as a namespace with a common immutable context.
Re:Rewriting Libimagequant in Rust for Portability by lostcolony on Tuesday January 04, 2022 @11:51AM (#29796869)
But...that was exactly the question the article had. Should drum be the enclosing class, or should stick be? What he cares about is the verb play, but he has to encapsulate it in a noun, and none of the ones actually involved dominate so clearly as to moot having to make a choice.
Re:Rewriting Libimagequant in Rust for Portability by nine_k on Tuesday January 04, 2022 @12:19PM (#29797208)

  musicPart.play(drum, sticks);
Basicslly you can replace the module namespace with a class namespace if desired. What module could that be?
Re:Rewriting Libimagequant in Rust for Portability by lostcolony on Tuesday January 04, 2022 @02:57PM (#29799433)
Right. But that's just it. "musicPart" is an object. A noun. What the hell is a "Music Part"? It's a completely synthetic object you've had to create solely to namespace functions. It's like how so many large Java projects have static "Utils" classes.

What you've done is not OO; in fact, it's an anti-pattern in OO. You've created, as you correctly note, a namespace or module around static functions; there is no meaningful encapsulation of data.

My point isn't that it can't be done, it's that trying to follow best OO practices, you run into this sort of problem (which has had a lot of digital ink spilled on it). The fact there is a pragmatic solution isn't in any doubt; it's that such a solution intentionally eschews the data encapsulation that OO demands (but not imperative or functional approaches, which instead say it's the right approach to do that).

Re:Rewriting Libimagequant in Rust for Portability by nine_k on Tuesday January 04, 2022 @06:34PM (#29802559)
If you ever played music, you know it consists of parts. Say, a percussion part, a bass part, a rhythm guitar part, a lead guitar part, a vocal part, etc.
Re:Rewriting Libimagequant in Rust for Portability by lostcolony on Tuesday January 04, 2022 @08:37PM (#29803800)
Why would 'play' hang off of the (presumably static) "MusicPart" then, rather than, "Player", "Musician", "Composition", etc?

Also, you realize that this whole discussion is proving the point, right?

Re:Rewriting Libimagequant in Rust for Portability by ReleaseCandidat on Tuesday January 04, 2022 @12:34PM (#29797395)
But now the traits aren't connected with drums (or sticks) but MusicParts. Or you end up having some `drum.foo` too.
Re:Rewriting Libimagequant in Rust for Portability by enriquto on Tuesday January 04, 2022 @11:54AM (#29796896)
> using the class as a namespace with a common immutable context

This is why we can't have nice things.

Re:Rewriting Libimagequant in Rust for Portability by nine_k on Tuesday January 04, 2022 @12:24PM (#29797275)
Pray elaborate.
Re:Rewriting Libimagequant in Rust for Portability by ReleaseCandidat on Tuesday January 04, 2022 @11:51AM (#29796873)
I guess he is talking about traits. How do you 'functionize' them?
Re:Rewriting Libimagequant in Rust for Portability by pornel on Tuesday January 04, 2022 @01:07PM (#29797845)
I wasn't thinking about traits when I wrote that, but you make a great point — that's a whole another way to design things. Maybe it could have been something fancy like:

    impl<T> Sound for T where T: Percussion<Accessory=Stick>
Re:Rewriting Libimagequant in Rust for Portability by hedgehog on Tuesday January 04, 2022 @01:58PM (#29798550)
There's also the pattern used in from+into where one implementation is wrapped to provide its counterpart on the other type. Nice to read but feels a little extra magical for someone without a lot of Rust background.
Re:Rewriting Libimagequant in Rust for Portability by tialaramex on Tuesday January 04, 2022 @03:16PM (#29799752)
Blanket implementation is a very common idea in Rust. The standard library "owns" its own Traits and so it gets to provide blanket implementations for those, but you can do the same for your own.

Here's (really, this is literally the code) how std provides a blanket implementation of Into given From:

  impl<T, U> Into<U> for T
  where
      U: From<T>,
  {
      fn into(self) -> U {
          U::from(self)
      }
  }
There's actually a chain, From implies Into, Into implies TryFrom, then TryFrom implies TryInto.