Need heterogeneous list that's not statically typed

I was just scanning the thread to see if someone already posted this article. It made me realize that I am making a mistake by trying to force functional patterns on rust as well.

We (I) want to use Rust, and we (I) want to do functional programming as well. It may not be ideal, but I'll take what I can get. :see_no_evil:

3 Likes

Still raking my brain over this, and I'm not sure how to proceed... :see_no_evil:

What is your goal with trying to accept these?

The problem is that Into is so general that it has a type parameter. The compiler isn't gonna know, given some type T, what of many possibilities you want to turn it into.

I'm not sure if this will work for you , but you could define a trait IntoSource which has an associated type, rather than a type parameter, so that there's only one possible conversion:

pub trait IntoArcSource {
    type Output;
    fn into_arc_source(self) -> Arc<Source<Self::Output>>;
}

and then in your macro you'd have:

impl<$($T: 'static, [<S $T>]: 'static),+> Combine for ($([<S $T>],)+)
where
    $(
        $T: Clone + Send + Sync,
         [<S $T>]: IntoArcSource<Output = $T>,
    )+
{

I'm still not sure your motivation, but if you want to accept any Source<T> or Arc<Source<T>>, then you could impl:

impl<T> IntoArcSource for Arc<Source<T>> {
    type Output = T;
    fn into_arc_source(self) -> Arc<Source<Self::Output>> { self }
}

impl<T> IntoArcSource for Source<T> {
    type Output = T;
    fn into_arc_source(self) -> Arc<Source<Self::Output>> { Arc::new(self) }
}
1 Like

I actually want to accept anything that implements Into<Arc<Source<T>>>. Is there no way to achieve that? The custom trait isn't going to cut it, since I have no way to tell what the users might have, e.g. Box<Source<T>>

Could using an intermediate function / macro help? As in, only accepting Arc<Source<T>> in the Combine implementation, but have another layer which converts from Into<Arc<Source<T>>> to Arc<Source<T>> (How? Is it even possible?)

Well, the Source struct is in your crate, so because of Rust's trait coherence rules, only your crate can write Into impls for arbitrary Source<T> anyway, the exception being that if a crate itself defines the type T then it can write an impl for Source<T>. But the same rules go for your custom IntoArcSource trait anyway.

The other thing I should mention is that accepting such a broad scope of types can really render type inference quite ineffective, sometimes giving cryptic non-local error messages, which can actually be quite irritating as a user. I've seen many libraries narrow the scope of their inputs, in favor of having users perform the necessary conversions themselves.

I still think it might help (for me at least) to write down example use cases for combine, in order to either come up with a solution that works for all those use cases, or identify the tradeoffs that need to be made and which use cases are more important than the others.

std has examples of this same "specialized into" pattern, like IntoIterator.

2 Likes

Right... That's really helpful!

This thought has crossed my mind multiple times:

An operator (or rather, the resulting transformed source) actually does not "own" its source(s), so why is it taking owned source(s)?

It feels wrong to me, but I'm not sure how it should be handled... An Arc represents shared ownership, so it does feel less wrong...

I mean, I would think of an Arc<T> more as a shared reference to T that happens to be atomically reference-counted. Other types of shared references include &T, Rc<T>, Weak<T>, and even Gc<T> with the help of a third-party crate.

But I could think of Arc<T> as where this T "lives", and it's being kept alive by the (strong) references to this Arc. Seems to me like shared ownership in the true sense.

What do you consider "not owning" then, especially in Javascript?

Now that I think about it, shared ownership of sources does kinda make sense (at least, the sources need to live as long as the resulting transformed source?)... So perhaps the current type signatures I have are okay-ish.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.