Skip to content

Default trait for ArrayBase? #204

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

Closed
SuperFluffy opened this issue Jul 16, 2016 · 5 comments
Closed

Default trait for ArrayBase? #204

SuperFluffy opened this issue Jul 16, 2016 · 5 comments

Comments

@SuperFluffy
Copy link
Contributor

SuperFluffy commented Jul 16, 2016

What is the opinion on implementing std::default::Default for ArrayBase? When skipping deserialization of a field with serde, it wants to insert the Default::default() value in there, so this would be one case where this would be very useful.

We already have a default function for ArrayBase, which however expects some kind of shape/dimension:

    pub fn default<Sh>(shape: Sh) -> ArrayBase<S, D>
        where A: Default,
              Sh: Into<Shape<D>>,
    {
        let shape = shape.into();
        let v = (0..shape.dim.size()).map(|_| A::default()).collect();
        unsafe { Self::from_shape_vec_unchecked(shape, v) }
    }

A default in the spirit of std::default::Default would look like:

    pub fn default() -> ArrayBase<S, D>
        where A: Default,
              D: Default + Default,
              Sh: Into<Shape<D>>,
    {
        let shape = <D as Default>::default().into();
        let v = (0..shape.dim.size()).map(|_| A::default()).collect(); // == Vec::new()
        unsafe { Self::from_shape_vec_unchecked(shape, v) }
    }

And Default impls for the various dimension-like types would be akin to:

impl Default for Ix {
    fn default() -> Self {
        0 as Ix
    }
}

impl Default for (Ix,Ix) {
    fn default() -> Self {
        (0,0) as (Ix,Ix)
    }
}

Is this desirable?

EDIT: I just realize that this might not be as straightforward as I thought, since e.g. Ix acts as just a type alias, preventing an easy implementation of Default for it. :-/

@bluss
Copy link
Member

bluss commented Jul 17, 2016

Default seems useless since it doesn't tell us what size the array should be. One could make the choice to make it a 0-element array or a 1-element array, but since arrays are not growable it doesn't seem useful at all.

@SuperFluffy
Copy link
Contributor Author

The reason is quality-of-life. Take the following example:

fn default_1d<T>() -> Array<T,Ix>
    where T: Default
{
    Array::default(0)
}

fn default_2d<T>() -> Array<T,(Ix,Ix)>
    where T: Default
{
    Array::default((0,0))
}

#[derive(Clone,Debug,Deserialize,Serialize)]
pub struct MyStruct {
    alpha: Array<f64, Ix>,

    #[serde(skip_deserializing,skip_serializing,default="default_1d")] 
    inverse_alpha: Array<f64, Ix>,

    #[serde(skip_deserializing,skip_serializing,default="default_2d")] 
    temp_quantities: Array<f64, (Ix, Ix)>,
}

I am skipping serialization and deserialization of some quantities. After deserialization, MyStruct is still not complete as I need to fill inverse_alpha (calculated from alpha) and have temp_quantities initialized. The size of the latter also depends on a field, which is not shown here.

Since I can't leave these fields empty, I need to fill something in, which I can accomplish through the default="$PATH" attribute serde provides (the default_{1,2}d functions above). If ArrayBase<A,S> had Default this boiler plate could be skipped.

@bluss
Copy link
Member

bluss commented Jul 17, 2016

It makes sense. Not fill, but replace the array. You'd need separate default implementations depending on the storage type (type parameter S), maybe we could implement an zero-dimensional default for all of Array, RcArray, ArrayView, ArrayViewMut

@SuperFluffy
Copy link
Contributor Author

Not sure I understand. A zero-dimensional default would not work in the case above, since I don't generalize over Array<f64, D>, but have Ix and (Ix,Ix). So the defaults would need to be n-dimensional, but with length 0 in each direction.

@bluss
Copy link
Member

bluss commented Jul 17, 2016

Ah I mean zero-size.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants