Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> we did not have Vec because we were no-std + stable so we literally had to use arrays

It's true that Vec isn't available in a no-std context, but I don't think it follows that arrays are the only other option - see heapless for one example: https://github.com/japaric/heapless

I also agree with some of the ancestors: the post seems to say that the Rust language couldn't handle arrays with more than 32 elements, and (as someone who's written a fair bit of no-std Rust, before const generic) that doesn't seem right. At first, it did seem awkward to me as well that some macros weren't defined for >32 element arrays, but in practice I haven't found it to be a significant limitation.

Was there a particular scenario where it wasn't feasible to wrap a >32 element array in your own type and implement Default on it?



We tried heapless, but ran into some problems with it. I forget the issue, but it had to do something with a bunch of unsafe code in heapless and the way we did stack frame alignments causing subtle bugs with tuples that had u8's in them. That problem may be resolved now that we're a couple years on.

If I'm not mistaken you can't implement traits on types that aren't in your crates, so, there's that limitation. But generally it's just another layer of friction that feels like it shouldn't be there, and it manifests itself as a form of technical debt. For example inside the microkernel itself there is an array that tracks the connection IDs in and out of a process. It's limited to 32 elements. Back when it was created, that seemed like a lot. Now maybe it'd be nice to bump it up just a little bit...but it would require opening up a can of worms since it never had all the traits implemented around it, so it's just sitting there until it becomes really worth the effort to upgrade that limit. There's a few spots like this.


Ah interesting. I've never dug in to the heapless implementation, but can imagine that getting it working right on a new platform might require a few changes.

It sounds the "orphan rules" that you're referring to; my understanding is that `impl SomeTrait for SomeStruct` needs to be in the same module as either `SomeTrait` or `SomeStruct`.

I bumped in to a similar situation with a project that involved a special buffer for handling digital audio. Initially, I made that buffer generic, and put it in its own module. The thing that used that buffer was in another module, and then everything was brought together in the main application. I wanted the ability to adjust parameters of the buffer from the project's top-level configuration, and can't remember the exact details, but basically with that structure main couldn't be the place that configured both the buffer and the module that dealt with the digital audio peripheral. The solution was pretty simple though: realise that the data structure is only ever used in conjunction with the peripheral, so instead of main including the buffer and peripheral (a dependency graph with edges main-buffer and main-peripheral), put the buffer in the module with the peripheral (edges main-(peripheral&buffer), or main-peripheral and peripheral-buffer, I can't remember which).

If you revisit that problem, it might be worth considering a declaration of a type for the connection IDs and with whatever impls are needed, in the module that wanted the >32 element array.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: