It all started with trying to extend the behavior of Vectors to have a into_audio_iter() so that I can include "meta data" that can be accessed when using iterator function continuations
raw_vec.into_audio_iter(sample_rate, bit_rate, channels).chunk(hundred_milliseconds).detect_silence().map(|x|{})
That way an iterator adapter like detect_silence() can access the sample rate to use. I didn't want to pass down the meta data along with the real data in Iterator::Item. I've been trying to do this for one week now!
This isn't a help me do this thing post. I've honestly been sapped of all enthusiasm to accomplish that goal. I have Python and C++ code that accomplishes it. I wanted to use it as a learning experience for Rust and so far its been absolute hell. The more and more I use Rust, the more and more I realize that maybe I'm just not smart enough to use it.
The borrow system is always touted as "the difficult" part of Rust. But for me that has been the easiest part! The rules are clear, the application of rules consistent, so far as my early experience goes. The Trait system is the scariest part. Its not always clear to me what is going on when I use traits. Particularly associated types, default generic type params, external traits and some other features. That when isolated, maybe I could really understand what these features do. But when combined together and used in funny ways that as far as I can see in the Iterator crates, is complete magic to me. Ambiguation, lifetime etc issues abound in my attempts.
If I define a AudioIntoIterExt: IntoIterator trait and define a fn into_audio_iter(self) -> Self::IntoIter its not clear to me why Self::IntoIter is an ambiguous association. In my small brain, the trait is just abstract and its up to the implementation to narrow down the concrete of what Self is and therefor Self::IntoIter. Of course I'm wrong but this is the kind of intuitive assumptions I make that get me into trouble with the language's traits all the time. Its also not clear if only the "static" methods defined in the AudioIntoIterExt trait are shared with IntoIterator or all future methods of impl AudioIntoIterExt as well. If they are shared how does that play with associated types I invent inside my trait? What about the interplay of generics and default generic params with all said above? The complexity quickly blows up.
I always hear disparaging opinions on Inheritance and Java and how it is so inferior. Say what you want, but that model of thinking is natural for people. The data proves it, the history of usage proves it. I even get people telling me that Functional is the way the people naturally think. I'm not a cognitive scientist or anything, but I am pretty sure that people actually tend to think about the world in hierarchies and symmetries of THINGS. The kind of model best fit by OOP and Java style inheritance systems. It is clear where the abstractions begin and end and where the concrete takes over. My biggest pain point with Rust right now is that it is not clear where the lines for abstractions are and how the MANY interconnected rules for traits apply to each other.
I see there are more features rolling out for Traits and I'm honestly sapped. I really really want to love this language because for me Rust contributes to that "programmer happiness" buzzword. I genuinely like it for some inexplicable reason. But since I hear no one else really expressing the abstraction features of the language as a pain point and only the borrow system, a seed of doubt in me is saying this is not for me. I want to be told I'm still a noob and I don't know what I'm talking about and your small OOP brain just needs to relearn concepts. I do, because otherwise if I have to implement one more Iterator and in a week still not understand where that lego piece fits into the hierarchy of other iterators I'm just done.