# Accessing an object's unparameterized type

**URL:** https://discourse.julialang.org/t/accessing-an-objects-unparameterized-type/89128
**Category:** New to Julia
**Tags:** question
**Created:** [October 23, 2022, 5:37am UTC](https://discourse.julialang.org/t/accessing-an-objects-unparameterized-type/89128 "2022-10-23T05:37:06Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)
#### Post date: [October 23, 2022, 5:37am UTC](https://discourse.julialang.org/t/accessing-an-objects-unparameterized-type/89128/1 "2022-10-23T05:37:06Z")

</div>

I have a function that receives an object with parameters attached to it, and I’d like it to call the object’s constructor with those parameters removed.

For example, consider:

```julia
struct Test{A, B} end

obj = Test{1,2}()

```

Suppose I write a function that receives `obj`; I’d like to call its constructor while discarding its parameters, in order to call it with different parameters, e.g. `Test{3,4}()`.

I can access a representation of `Test` as a `Core.TypeName`:

```julia
typeof(obj).name == Base.typename(Test)

```

but I don’t know how to retrieve a callable `Test` constructor from it.

```julia
julia> Type((Test{1,2}).name)
ERROR: MethodError: no method matching Type(::Core.TypeName)

```

Knowing that types and their parameters can be teased out in the function definition, I’ve also given this a shot, but it just results in errors:

```julia
julia> (T where {T}){1,2}
ERROR: TypeError: in Type{...} expression, expected UnionAll, got Type{Any}

julia> T{1,2} where {T}
ERROR: TypeError: in Type{...} expression, expected UnionAll, got a value of type TypeVar

```

Any ideas on how to access the unparameterized constructor?

Thanks~

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [October 23, 2022, 11:03am UTC](https://discourse.julialang.org/t/accessing-an-objects-unparameterized-type/89128/2 "2022-10-23T11:03:25Z")

</div>

Maybe define the input of the function as

```julia
f(T{A,B}) where {T,A,B} = ...

```

then you can use `T`?

---

<div class="post-metadata">

### Author: ![thautwarm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thautwarm/32/37760_2.png) [@thautwarm](https://discourse.julialang.org/u/thautwarm)
#### Post date: [October 23, 2022, 11:18am UTC](https://discourse.julialang.org/t/accessing-an-objects-unparameterized-type/89128/3 "2022-10-23T11:18:44Z")

</div>

Julia does not support higher-kinded type parameters.

---

<div class="post-metadata">

### Author: ![thautwarm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thautwarm/32/37760_2.png) [@thautwarm](https://discourse.julialang.org/u/thautwarm)
#### Post date: [October 23, 2022, 11:19am UTC](https://discourse.julialang.org/t/accessing-an-objects-unparameterized-type/89128/4 "2022-10-23T11:19:28Z")

</div>

Given `t::DataType`, you might need `getfield(t.name.module, t.name.name)`.

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [October 23, 2022, 11:20am UTC](https://discourse.julialang.org/t/accessing-an-objects-unparameterized-type/89128/5 "2022-10-23T11:20:20Z")

</div>

This has been discussed numerous times - search for [“strip type parameters”](https://discourse.julialang.org/search?q=strip%20type%20parameters).

This is the most relevant result:

> [@Stripping parameter from parametric types](https://discourse.julialang.org/t/stripping-parameter-from-parametric-types/8293):
>
> I have writing code that maniuplates containers of arrays of custom types with several parameters, e.g. SomeArrayType{T, G1, G2, N} \<: AbstractArray{T, N}, where the last parameter in SomeArrayType is always the array rank N. The arrays that can be in the container can differ in rank N but otherwise should be the same type, for example Vector{SomeArray{T, G1, G2}} which can also be written Vector{SomeArray{T, G1, G2, N} where N}. I’d like to create a function arraytype that strips the last (ra…

> [@uniment](#):
>
> I’d like to call its constructor while discarding its parameters, in order to call it with different parameters, e.g. `Test{3,4}()`.

There may not be such a constructor. This is not safe to do in general. Reflection can only work in limited cases here. The “canonical” solution is to have `similar` implemented on your type.

---

<div class="post-metadata">

### Author: ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)
#### Post date: [October 23, 2022, 12:32pm UTC](https://discourse.julialang.org/t/accessing-an-objects-unparameterized-type/89128/6 "2022-10-23T12:32:55Z")

</div>

Thanks, that was it! I had failed to explore the `TypeName` object’s properties.

Short answer:

```julia
struct Test{A,B} end
obj = Test{1,2}()

typeof(obj).name.wrapper{3,4}() # == Test{3,4}()

```

Or in a method definition,

```julia
funcname(obj::T) where T = begin
    T.name.wrapper{3,4}()
end
funcname(obj)

```

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [October 23, 2022, 12:37pm UTC](https://discourse.julialang.org/t/accessing-an-objects-unparameterized-type/89128/7 "2022-10-23T12:37:58Z")

</div>

Be aware that this is not safe to do - `TypeName` is an internal object and may vanish at any point, or its fields may change name or vanish. This is not stable & supported API.

What are you ultimately trying to achieve with this? There’s probably a better/more stable way to do this.

---

<div class="post-metadata">

### Author: ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)
#### Post date: [October 23, 2022, 5:15pm UTC](https://discourse.julialang.org/t/accessing-an-objects-unparameterized-type/89128/8 "2022-10-23T17:15:05Z")

</div>

There is a way to do this without touching the internals:

> <https://github.com/JuliaObjects/ConstructionBase.jl/blob/master/src/ConstructionBase.jl#L29-L31>

Specifically:

```julia
getfield(parentmodule(T), nameof(T))

```

But notice its in a generated function for performance in ConstructionBase.jl, so also not a great option. `name.wrapper` has been working fine for quite some years now too.

---

<div class="post-metadata">

### Author: ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)
#### Post date: [October 24, 2022, 8:47am UTC](https://discourse.julialang.org/t/accessing-an-objects-unparameterized-type/89128/9 "2022-10-24T08:47:02Z")

</div>

Wow, this library is a treasure trove of clever magic! Thanks!

I’m also currently accessing the type parameters with

```julia
T.parameters[1]
T.parameters[2]

```

In the same spirit, I presume this is not considered official API…

> [@Sukera](#):
>
> What are you ultimately trying to achieve with this? There’s probably a better/more stable way to do this.

As a Julian you will not like this, but I’ve put together a package for easy and informal prototype-based programming à la JavaScript’s `Object` model. It’s a toy project for now, just to tinker around and see what’s possible and what makes sense, but it really got me into the weeds of Julia’s type system.

I started typing out an essay about what I’m doing here, but it might be easier to point to the code. The code in question is on lines 110 and 117 of `src/object.jl`, where I find the prototype “parent” object’s type, strip off the parameters (which encode the object’s contained types), and call its constructor (which can be one of three types: `Dynamic`, `Static`, or `Mutable`) to create an inheritor “child” object which has similar characteristics.

[Objects.jl: Dynamic, Static, and Mutable Objects with Composition, Prototype Inheritance, Method Membership, and Type Tagging for Julia](https://github.com/uniment/Objects.jl)

With your help and Raf’s help, I’m pretty happy with it so far. 🙏

---

<div class="post-metadata">

### Author: ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)
#### Post date: [October 24, 2022, 10:02am UTC](https://discourse.julialang.org/t/accessing-an-objects-unparameterized-type/89128/10 "2022-10-24T10:02:11Z")

</div>

I would rely on ConstructionBase.jl for these things wherever possible, a good fraction of the ecosystem supports it now. For parameters, instead of `x.parameters[2]` just use regular function dispatch with type parameters? `getparam(::MyType{<:Any,B}) where B = B` (or define it for type type if you need that). Write it for an abstract type with consistent params.

And don’t worry, as “Julians” many of us have gone through phases like the one you are in. I wrote Mixers.jl in my first few months out of frustration with lack of field inheritance. Now I never use, and actively recommend against it.

Mostly we are guessing you will follow a similar arc with your need for Javascript-like objects 😉

---

<div class="post-metadata">

### Author: ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)
#### Post date: [October 24, 2022, 11:29am UTC](https://discourse.julialang.org/t/accessing-an-objects-unparameterized-type/89128/11 "2022-10-24T11:29:45Z")

</div>

> [@Raf](#):
>
> For parameters, instead of `x.parameters[2]` just use regular function dispatch with type parameters?

Ah right, I wrote this part of the code before I figured out how to do that, a few days ago. Hah, how time flies. 😅

> [@Raf](#):
>
> And don’t worry, as “Julians” many of us have gone through phases like the one you are in. I wrote Mixers.jl in my first few months out of frustration with lack of field inheritance. Now I never use, and actively recommend against it.

Hah that’s a relief! I actually looked at that package not so long ago and was wondering if I should be structuring my code with it. 😅

> [@Raf](#):
>
> Mostly we are guessing you will follow a similar arc with your need for Javascript-like objects 😉

We shall see 😉

> [@uniment](#):
>
> The code in question is on lines 110 and 117 of `src/object.jl`

Now lines 85 and 92
