-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Independent feedback while working on the same problem #60
Comments
Hi @james-darkfox, thanks for sharing your thoughts with us!
That's an interesting idea, getting rid of unsafe is definitely desirable. However, I'm unsure how that differs from just having normal crossbeam channels with that union type as the type argument? @wenkokke has an alternative approach in their library that you might want to take a look at as well: https://github.com/wenkokke/rusty-variation. In short, she's sending a new transmitter/receiver every time she does something. I believe she also avoids using
That's cool, and something we haven't considered at all. I wonder what it would take to make our library work in a
Interesting thought! Perhaps we could do something similar with specialized trait implementations.
This is something that we spent a long time thinking about. When we were originally implementing this library, I believe that was one of the things we tried out, but we couldn't quite reach a good compromise between safety and usability. Lots have changed in Rust in the meantime though, so perhaps it's time to revisit such an approach. I remember some of the difficulties were: sending channels over channels, intermixing channels, and just general user inconvenience. @laumann perhaps your memory is better than mine on this point? |
Per (2) using the union with crossbeam's channels is an option. The important detail there is that we can use an enum without questioning safety and that Rust's enum representations are ripe for reducing its costs; and that we don't need to use boxes. Here is a dump of my current code. The I wouldn't use the union variant in real code as even with a large protocol the number of unique types won't be too great and the enum will likely be padded anyway. I'm not yet sending the choices as numbers, but they are prepared at the type level in the form Before implementing the union-set I had actually used the left/right routing to index the types directly. This yields less code but its non-unique set is not optimal in the enum form. No specialization needed; although the unique-set does require If you're dealing with multiple channels, you'll probably want to use MPSTs instead of BSTs. After playing with the trait approach for a couple of days, I've decided to leave that code as-is and try another approach. Using procedural macros to both specify MPSTs and to implement actors. I'll keep you posted. :-) |
Heh. After adding the reference to the rust issue for enum representations. I see someone else has done similar work (and probably know the names of these types better). If you go this route, consider frunk's Coproducts. AFAICT there isn't a tree -> unique cons conversion there but that'd be easy to add (at the cost of the unstable feature optin_builtin_traits .. or possibly without but with noisier implementations) |
Feedback ext.
|
Hello. I am currently experimenting with BSTs in Rust and hopefully soon MPSTs. I'll be publishing the code soon. The following thread covers different design decisions relating to the internal implementation without changing the interface for consumers. When I move on to MPST, I'll experiment with a DSL using macros.
Note: For safety, the union will can trivially be replaced with an enum. Currently rust's enum representations aren't quite as nice as they could be, but this should improve in the future - further reducing the cost of tagging each variant. Importantly we do not need unsafe to implement session types. The space inefficient enum tag won't be much more than the optimized choice-based tag, and it is already significantly cheaper than boxing all messages.
Backend agnostic. I.e. A
#[no_std]
context can use acore::cell::Cell<Option<UnionOfMessages>>
as the underlying channel without worrying about allocations.Choices can send a single message, and if followed with a send; the two messages may be bundled. Vs. Sending each boolean choice over the channel.
Although Rust doesn't have linear types, it does have private constructors - which I conject in combination with affine types is sufficient to force the protocol to progress through at least one valid path. Replacing the unit in the
E
type parameter of aChan
with a public contextual type, with a private constructor instantiating it, the relevant function can be forced to return the closed channel to its caller.Do we need anything stronger than requiring the program progress through at least one valid path?
Proof of concept:
The text was updated successfully, but these errors were encountered: