# Change construction type parameters for a type in a vector?

**URL:** <https://discourse.julialang.org/t/change-construction-type-parameters-for-a-type-in-a-vector/84441>\
**Category:** General Usage\
**Tags:** question, array, dispatch, vector, parameters\
**Created:** [July 19, 2022, 4:38am UTC](https://discourse.julialang.org/t/change-construction-type-parameters-for-a-type-in-a-vector/84441 "2022-07-19T04:38:54Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![emmettgb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/emmettgb/32/20393_2.png) [@emmettgb](https://discourse.julialang.org/u/emmettgb)\
**Post date:** [July 19, 2022, 4:38am UTC](https://discourse.julialang.org/t/change-construction-type-parameters-for-a-type-in-a-vector/84441/1 "2022-07-19T04:38:54Z")

</div>

I have an abstract type:

```julia
abstract type Pickle end

```

I have a sub-type

```julia
mutable struct Dill <: Pickle
    rating::Integer
end

```

If I construct a `Vector{Dill}`:

```julia
[Dill(5), Dill(6,)]

```

The type of this is `Vector{Dill}`. What I would like for this to do instead is return a `Vector{Pickle}`. Instead of the sub-type, I want my supertype in the parameters.  
I do not want my users to have to call a method that groups the pickles, like `pickles(pickles::Pickle ...)` or something, instead i’d rather them do

```julia
# vv insert method with this argument here.
[pickles ...] = 

```

Does anybody have more info on this?  
thanks friends 🙂

---

<div class="post-metadata">

**Author:** ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)\
**Post date:** [July 19, 2022, 4:52am UTC](https://discourse.julialang.org/t/change-construction-type-parameters-for-a-type-in-a-vector/84441/2 "2022-07-19T04:52:09Z")

</div>

You need to specialize `Base.vect`

```julia
julia> Base.vect(X::Pickle...) = Pickle[X[i] for i in eachindex(X)]

julia> [Dill(3), Dill(4)]
2-element Vector{Pickle}:
 Dill(3)
 Dill(4)

```

---

<div class="post-metadata">

**Author:** ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)\
**Post date:** [July 19, 2022, 4:54am UTC](https://discourse.julialang.org/t/change-construction-type-parameters-for-a-type-in-a-vector/84441/3 "2022-07-19T04:54:11Z")

</div>

Hi!  
All it takes is to do `a = Pickle[Dill(5), Dill(6)]`, or to create `a = Vector{Pickle}(undef, 2)` and fill it afterwards. However, I’m not sure I understood why you want to do that, since it will probably result in a performance loss.  
As a side note, you probably want to give the `rating` field a concrete type such as `Int` instead of the abstract type `Integer`, so that the compiler knows its memory layout and can perform better optimizations. If you don’t need mutability, you may also ditch the `mutable` keyword to further speed things up.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [July 19, 2022, 7:57am UTC](https://discourse.julialang.org/t/change-construction-type-parameters-for-a-type-in-a-vector/84441/4 "2022-07-19T07:57:30Z")

</div>

> [@jishnub](#):
>
> `julia> Base.vect(X::Pickle...) = Pickle[X[i] for i in eachindex(X)]`

Even though this isn’t technically type piracy, it does profoundly change a pretty fundamental behavior in Julia: one expects `[]` to always return the narrowest typed vector. Changing this behavior risks confusing your users badly, @emmettgb.

Being explicit here by doing

> [@gdalle](#):
>
> `Pickle[Dill(5), Dill(6)]`

seems much preferable.

The part below is a bit confusing. What does it mean?

> [@emmettgb](#):
>
> I do not want my users to have to call a method that groups the pickles, like `pickles(pickles::Pickle ...)` or something

---

<div class="post-metadata">

**Author:** ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)\
**Post date:** [July 19, 2022, 8:42am UTC](https://discourse.julialang.org/t/change-construction-type-parameters-for-a-type-in-a-vector/84441/5 "2022-07-19T08:42:26Z")

</div>

> [@DNF](#):
>
> Even though this isn’t technically type piracy, it does profoundly change a pretty fundamental behavior in Julia: one expects `[]` to always return the narrowest typed vector. Changing this behavior risks confusing your users badly

What are the adverse consequences of this, other than possibly hitting suboptimal fallback methods? Can this break anything?

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [July 19, 2022, 9:41am UTC](https://discourse.julialang.org/t/change-construction-type-parameters-for-a-type-in-a-vector/84441/6 "2022-07-19T09:41:54Z")

</div>

No, as I said, it’s not type piracy, so I’m not sure if there are bad consequences. But, psychologically, I think it would be very confusing. I could very well imagine myself spending an hour in total disbelief, trying to figure out why `[]` stopped working.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [July 19, 2022, 10:02am UTC](https://discourse.julialang.org/t/change-construction-type-parameters-for-a-type-in-a-vector/84441/7 "2022-07-19T10:02:08Z")

</div>

I think perhaps it violates the description in the documentation of `vect`:

> Create a `Vector` with element type computed from the `promote_typeof` of the argument, containing the argument list.

---

<div class="post-metadata">

**Author:** ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)\
**Post date:** [July 19, 2022, 10:18am UTC](https://discourse.julialang.org/t/change-construction-type-parameters-for-a-type-in-a-vector/84441/8 "2022-07-19T10:18:42Z")

</div>

Ok, in that case, extending `Base.vect` in this way is unwarranted. Perhaps the docstring needs to be refined though, as `promote_typeof` is not a part of the API (it’s not documented, and doesn’t have a docstring either), so defining the element type of `vect` in terms of this seems a bit iffy.

---

<div class="post-metadata">

**Author:** ![emmettgb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/emmettgb/32/20393_2.png) [@emmettgb](https://discourse.julialang.org/u/emmettgb)\
**Post date:** [July 19, 2022, 4:14pm UTC](https://discourse.julialang.org/t/change-construction-type-parameters-for-a-type-in-a-vector/84441/9 "2022-07-19T16:14:16Z")

</div>

That was a concern, of course yes, but sometimes you might want to dispatch a collection of abstract types, like a `Vector{Number}` which contains `Int64'`s and `Float64`’s instead of being a `Vector{Any}`.  
Doubtful it would detract from anything else in Base, or suddenly break Vectors, but I definitely see your point on how it might confuse people. However, all of my methods which work with collections in my package use them from the top of the heirarchy. In other words, a `Vector{Dill}` has no methods, but a `Vector{Pickle}` has a surplus.  
Still, I agree this is somewhat **implicit** , especially when it comes to Julia, however I think this will be what I go with. Also the `pickles(p ...)` thing that I was referring to is something like:

```julia
pickles(p::Pickle ...) = Vector{Pickle}(p)

```

Thanks for your reply!

---

<div class="post-metadata">

**Author:** ![emmettgb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/emmettgb/32/20393_2.png) [@emmettgb](https://discourse.julialang.org/u/emmettgb)\
**Post date:** [July 19, 2022, 4:15pm UTC](https://discourse.julialang.org/t/change-construction-type-parameters-for-a-type-in-a-vector/84441/10 "2022-07-19T16:15:59Z")

</div>

Thanks, but I do not think this will work for what I want to do, as I want all collections of any `Pickle` subtype to become a `Dill`.

---

<div class="post-metadata">

**Author:** ![emmettgb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/emmettgb/32/20393_2.png) [@emmettgb](https://discourse.julialang.org/u/emmettgb)\
**Post date:** [July 19, 2022, 4:17pm UTC](https://discourse.julialang.org/t/change-construction-type-parameters-for-a-type-in-a-vector/84441/11 "2022-07-19T16:17:07Z")

</div>

Thank you, master kenobi, these were the Base methods I was looking for

---

<div class="post-metadata">

**Author:** ![emmettgb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/emmettgb/32/20393_2.png) [@emmettgb](https://discourse.julialang.org/u/emmettgb)\
**Post date:** [July 19, 2022, 4:18pm UTC](https://discourse.julialang.org/t/change-construction-type-parameters-for-a-type-in-a-vector/84441/12 "2022-07-19T16:18:40Z")

</div>

Also – don’t worry the real code I am applying this to has nothing to do with this little example and nothing to do with Pickles. I figured this would be a lot more interpretable than placing all of this type information into the post!

---

<div class="post-metadata">

**Author:** ![emmettgb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/emmettgb/32/20393_2.png) [@emmettgb](https://discourse.julialang.org/u/emmettgb)\
**Post date:** [July 19, 2022, 4:24pm UTC](https://discourse.julialang.org/t/change-construction-type-parameters-for-a-type-in-a-vector/84441/13 "2022-07-19T16:24:50Z")

</div>

> [@jishnub](#):
>
> `mote_typeof`

`promote_typeof` and promotion in general is what I was trying before, I could not get it to work for this application – and as you touched on, the documentation in that portion of Base was not my favorite, but I kind of figured there had to be a method that does this, which I now know to be `Base.vect`, and I think this option will be what I go with – at least for now, thanks!

---

<div class="post-metadata">

**Author:** ![yha](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yha/32/3502_2.png) [@yha](https://discourse.julialang.org/u/yha)\
**Post date:** [July 19, 2022, 4:34pm UTC](https://discourse.julialang.org/t/change-construction-type-parameters-for-a-type-in-a-vector/84441/14 "2022-07-19T16:34:28Z")

</div>

> [@emmettgb](#):
>
> In other words, a `Vector{Dill}` has no methods, but a `Vector{Pickle}` has a surplus.

So you have methods taking `Vector{Pickle}`, and therefore want your users to create vectors of this type? It’s probably better to change the argument type to `Vector{<:Pickle}`, or better yet `AbstractVector{<:Pickle}`, so you can pass in `Vector{Dill}` as well.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [July 19, 2022, 5:52pm UTC](https://discourse.julialang.org/t/change-construction-type-parameters-for-a-type-in-a-vector/84441/15 "2022-07-19T17:52:17Z")

</div>

> [@emmettgb](#):
>
> a `Vector{Dill}` has no methods, but a `Vector{Pickle}` has a surplus.

What will you do if someone creates a `Vector{Dill}`, and start `push!`ing to it?

I fear this will make things both really hard and very confusing for your users. Why not try to stick with consistency and predictability, values that are very central to the language?
