# Modify Parameters of Type

**URL:** https://discourse.julialang.org/t/modify-parameters-of-type/5431
**Category:** General Usage
**Created:** [August 17, 2017, 6:48pm UTC](https://discourse.julialang.org/t/modify-parameters-of-type/5431 "2017-08-17T18:48:51Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![ckfinite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ckfinite/32/8341_2.png) [@ckfinite](https://discourse.julialang.org/u/ckfinite)
#### Post date: [August 17, 2017, 6:48pm UTC](https://discourse.julialang.org/t/modify-parameters-of-type/5431/1 "2017-08-17T18:48:51Z")

</div>

I’m working on a very reflective program, and need to take a type with specified type parameters (e.g. Array{Int64, 1}) and turn it back into a UnionAll (e.g. Array{T, N} where T where N), without mutating the source DataType, ideally without having to eval a synthetic expression. This seems like something that should be possible, but the trivial ideas don’t seem to work:

- There doesn’t appear to be a built in function to do this, though I could just be missing it.
- There’s no DataType constructor that lets one modify the new type’s properties.
- DataType.parameters is (for most types) an svec, which can’t be mutated from Julia.
- clone isn’t defined for types, and Base.deepcopy returns the same vector, so replacing the parameters field with a fresh svec won’t work.

Is there a nice way to do this?

---

<div class="post-metadata">

### Author: ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)
#### Post date: [August 17, 2017, 6:53pm UTC](https://discourse.julialang.org/t/modify-parameters-of-type/5431/2 "2017-08-17T18:53:14Z")

</div>

I’m pretty sure you can’t do that. Doing so would be equivalent to mutating the type of an existing object, which should not be possible.

Are you _sure_ you actually want to mutate the type? Would just returning the appropriate UnionAll not suffice?

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [August 17, 2017, 7:01pm UTC](https://discourse.julialang.org/t/modify-parameters-of-type/5431/3 "2017-08-17T19:01:28Z")

</div>

Getting `Array{T,N} where T where N` from `Array{Int64,1}` is easy.

```julia
julia> T = Array{Int,1}
Array{Int64,1}

julia> typeof(T.name.wrapper)
UnionAll

julia> T.name.wrapper
Array

```

However, doing that for arbitrary type is basically never what you want to do.

---

<div class="post-metadata">

### Author: ![ckfinite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ckfinite/32/8341_2.png) [@ckfinite](https://discourse.julialang.org/u/ckfinite)
#### Post date: [August 17, 2017, 7:06pm UTC](https://discourse.julialang.org/t/modify-parameters-of-type/5431/4 "2017-08-17T19:06:39Z")

</div>

That’s exactly what I needed, thanks.

@rdeits In my use case, I’m interested in getting a new type that doesn’t have the parameters of the old one, not modifying the type that already exists. @yuyichao’s answer is ideal.

---

<div class="post-metadata">

### Author: ![jameson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jameson/32/23_2.png) [@jameson](https://discourse.julialang.org/u/jameson)
#### Post date: [August 18, 2017, 6:55pm UTC](https://discourse.julialang.org/t/modify-parameters-of-type/5431/5 "2017-08-18T18:55:02Z")

</div>

> However, doing that for arbitrary type is basically never what you want to do.

An explanation of why this is not something you should usually do will eventually make its way into the manual. For now, there’s a PR: [Update of Jameson's "common parametric method patterns" by mauro3 · Pull Request #23245 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/23245/files#diff-619ea7b9ee7c2fa87a3720c1361ba46cR564)

---

<div class="post-metadata">

### Author: ![ckfinite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ckfinite/32/8341_2.png) [@ckfinite](https://discourse.julialang.org/u/ckfinite)
#### Post date: [August 18, 2017, 8:43pm UTC](https://discourse.julialang.org/t/modify-parameters-of-type/5431/6 "2017-08-18T20:43:37Z")

</div>

In this particular case, I needed this in order to check to see if there was an extant method implementation for a specific argument type in a typechecker, in a kind of ghetto re-implementation of `ml_matches` with nonzero `lim`, as a result of wanting to precisely identify methods potentially invoked by a call (`methods` conservatively over-approximates the set, in the case where all subtypes of a type have implementations) and check to make sure that implementations exist for every subtype. Since I’d rather implement as much of my algorithm in Julia as possible, I would at this point rather avoid calling `ml_matches`.

The problem that required this arises when filtering the list of potentially invoked methods by type. My algorithm works by subsetting the list of methods to those in a typing relation to the current “objective” type, then recursing on the subtypes of the objective until it either runs out of methods (a failure, in which case a more general implementation must exist/be used), or run out of subtypes (a success). This runs into trouble, however, in the case of something like trying to find an implementation of `size` on an `AbstractSparseArray{Int64,Ti,1} where Ti`, whose sole subtype (in a fresh 0.6.0 REPL) is `SparseVector{Int64,Ti} where Ti<:Integer`. However, only one implementation of `size` is available, taking a `SparseVector{T,V} where T where V`, which is not a subtype or supertype of `AbstractSparseArray{Int64,Ti,1}`, which is removed. Then, the next step of the algorithm tries to find a method for `SparseVector{Int64, Ti} where Ti <: Integer`. However, since the implementation for `SparseVector{T,V} where T where V` was filtered out at the previous iteration, this fails.

The fix is that instead of filtering on subtypes of `AbstractSparseArray{Int64,Ti,1}`, the list of functions is filtered based on subtypes of `AbstractSparseArray{T,U,V} where T where U where V`, of which `SparseArray{T,U} where T where U` is a subtype. This works perfectly for my limited use case. At some point I’ll rip this out and replace it with a C call to `ml_matches` with the appropriate limited mode turned on and some patches to require exhaustiveness, but I wanted to see if I could write it all in Julia.

---

<div class="post-metadata">

### Author: ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)
#### Post date: [August 18, 2017, 9:08pm UTC](https://discourse.julialang.org/t/modify-parameters-of-type/5431/7 "2017-08-18T21:08:26Z")

</div>

If I understand correctly, it sounds like this [https://github.com/JuliaLang/julia/pull/23117](https://github.com/JuliaLang/julia/pull/23117) might make your life easier.
