# How to return an instance of a composite type based on a given field value?

**URL:** <https://discourse.julialang.org/t/how-to-return-an-instance-of-a-composite-type-based-on-a-given-field-value/87374>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [September 16, 2022, 3:47pm UTC](https://discourse.julialang.org/t/how-to-return-an-instance-of-a-composite-type-based-on-a-given-field-value/87374 "2022-09-16T15:47:52Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![phantom](https://avatars.discourse-cdn.com/v4/letter/p/e0b2c6/32.png) [@phantom](https://discourse.julialang.org/u/phantom)\
**Post date:** [September 16, 2022, 3:47pm UTC](https://discourse.julialang.org/t/how-to-return-an-instance-of-a-composite-type-based-on-a-given-field-value/87374/1 "2022-09-16T15:47:52Z")

</div>

Hi I’m going through the Julia manual and learning about abstract and composite types. I wanted to create a method that returns the instance of a composite type based on a given field value. I was wonder if there was a general way to do this. So for example suppose

```julia
 abstract type warrior end 
 struct elf <: warrior
     strength :: Int
     power :: String 
 end 
 struct ninja <: warrior
     strength:: Int
     Power:: String 
 end

Legolas = elf(10, "archery")
snakeeyes = ninja(12, "stealth")

battle(x::warriors, y::warrior) = max(x.strength,y.strength) 

```

This would return the max of the field x.strength. Is there a simple way to have a method return the instance based on a given field value as opposed to the value itself? i.e. in this case the `battle` method would return `snakeeyes` as opposed to `12`? (please excuse the cheesy example, just trying to understand the purpose behind abstract types a little better.)

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [September 16, 2022, 3:55pm UTC](https://discourse.julialang.org/t/how-to-return-an-instance-of-a-composite-type-based-on-a-given-field-value/87374/2 "2022-09-16T15:55:37Z")

</div>

Is this what you are looking for?

```julia
julia> battle(x::warrior, y::warrior) = x.strength > y.strength ? x : y
battle (generic function with 1 method)

julia> battle(Legolas, snakeeyes)
ninja(12, "stealth")

```

---

<div class="post-metadata">

**Author:** ![phantom](https://avatars.discourse-cdn.com/v4/letter/p/e0b2c6/32.png) [@phantom](https://discourse.julialang.org/u/phantom)\
**Post date:** [September 17, 2022, 4:13am UTC](https://discourse.julialang.org/t/how-to-return-an-instance-of-a-composite-type-based-on-a-given-field-value/87374/3 "2022-09-17T04:13:34Z")

</div>

yes thanks so much for pointing this out! although is there a way for it to return the instance of the composite type, i.e. snakeeyes as opposed to just the composite type itself? I suppose I could add another field to the composite type including the name of the instance but I was wondering if there was a more direct way to go about it?

---

<div class="post-metadata">

**Author:** ![jmair](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmair/32/35117_2.png) [@jmair](https://discourse.julialang.org/u/jmair)\
**Post date:** [September 17, 2022, 8:17am UTC](https://discourse.julialang.org/t/how-to-return-an-instance-of-a-composite-type-based-on-a-given-field-value/87374/4 "2022-09-17T08:17:23Z")

</div>

It already returns the instance, it’s just that you would need a field for the name if you want to see that.

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [September 17, 2022, 7:45pm UTC](https://discourse.julialang.org/t/how-to-return-an-instance-of-a-composite-type-based-on-a-given-field-value/87374/5 "2022-09-17T19:45:12Z")

</div>

A way to realize by following the path you were attempting

```julia
julia> import Base.isless

julia> isless(x::warrior, y::warrior) = x.strength < y.strength
isless (generic function with 44 methods)

julia> battle(x::warrior, y::warrior) = max(x,y) 
battle (generic function with 1 method)

julia> battle(Legolas, snakeeyes)
ninja(12, "stealth")

julia> Legolas > snakeeyes
false

julia> Legolas < snakeeyes
true

```

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [September 17, 2022, 8:31pm UTC](https://discourse.julialang.org/t/how-to-return-an-instance-of-a-composite-type-based-on-a-given-field-value/87374/6 "2022-09-17T20:31:52Z")

</div>

Would it be possible to achieve this by adapting the `show()` function for the `warrior` type?

---

<div class="post-metadata">

**Author:** ![phantom](https://avatars.discourse-cdn.com/v4/letter/p/e0b2c6/32.png) [@phantom](https://discourse.julialang.org/u/phantom)\
**Post date:** [September 19, 2022, 7:27am UTC](https://discourse.julialang.org/t/how-to-return-an-instance-of-a-composite-type-based-on-a-given-field-value/87374/7 "2022-09-19T07:27:00Z")

</div>

thanks, as mentioned I was wondering if there was a way to do it without having to add another field to the instance?

---

<div class="post-metadata">

**Author:** ![phantom](https://avatars.discourse-cdn.com/v4/letter/p/e0b2c6/32.png) [@phantom](https://discourse.julialang.org/u/phantom)\
**Post date:** [September 19, 2022, 7:29am UTC](https://discourse.julialang.org/t/how-to-return-an-instance-of-a-composite-type-based-on-a-given-field-value/87374/8 "2022-09-19T07:29:56Z")

</div>

thanks! does this affect a global change to the `<`operator?

---

<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:** [September 19, 2022, 7:40am UTC](https://discourse.julialang.org/t/how-to-return-an-instance-of-a-composite-type-based-on-a-given-field-value/87374/9 "2022-09-19T07:40:41Z")

</div>

> [@phantom](#):
>
> thanks, as mentioned I was wondering if there was a way to do it without having to add another field to the instance?

So you want to print the variable name, together with the value? For that you can use the `@show` macro:

```julia
julia> @show snakeeyes;
snakeeyes = ninja(12, "stealth")

```

This isn’t really a Julia question, though; you would have the same problem in any language. You are using a variable name to indicate the name of the individual `warrior`, which is a bit strange. If you want to associate a “person name” with a `warrior`, you should make a `name` field in the struct. Variable names aren’t really part of the data here, they are just labels that make it easy for you to write your code, but the `@show` macro gives you a sort of workaround for printing the variable name along with the value.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [September 19, 2022, 7:41am UTC](https://discourse.julialang.org/t/how-to-return-an-instance-of-a-composite-type-based-on-a-given-field-value/87374/10 "2022-09-19T07:41:52Z")

</div>

No, because the values of variables are not aware of the variables’ names.

You _could_ do this with metaprogramming, such that

```julia
julia> @battle Legolas Snakeeyes
Snakeeyes wins 12 to 10!

```

but this is not the simplest way to do it. It’s likely to be difficult to read, difficult to write, difficult to debug and less performant than simply keeping track of names.

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [September 19, 2022, 7:50am UTC](https://discourse.julialang.org/t/how-to-return-an-instance-of-a-composite-type-based-on-a-given-field-value/87374/11 "2022-09-19T07:50:30Z")

</div>

A counterexample to show _why_ you can’t expect variable names to follow the variables around:

```julia
julia> snakeeyes = Ninja(12);
julia> winner = snakeeyes

```

Should Julia print `"winner"` or `"snakeeyes"`?  
How about

```julia
julia> function give_promotion!(employee::Warrior) 
employee.strength += 1
return employee
end;
julia> give_promotion(snakeeyes)

```

Should it print `"snakeeyes"` or `"employee"`?

---

<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:** [September 19, 2022, 7:55am UTC](https://discourse.julialang.org/t/how-to-return-an-instance-of-a-composite-type-based-on-a-given-field-value/87374/12 "2022-09-19T07:55:43Z")

</div>

> [@gustaphe](#):
>
> variable names to follow the variables around

“Variables” → “values” for clarity?

---

<div class="post-metadata">

**Author:** ![phantom](https://avatars.discourse-cdn.com/v4/letter/p/e0b2c6/32.png) [@phantom](https://discourse.julialang.org/u/phantom)\
**Post date:** [September 19, 2022, 8:04pm UTC](https://discourse.julialang.org/t/how-to-return-an-instance-of-a-composite-type-based-on-a-given-field-value/87374/13 "2022-09-19T20:04:55Z")

</div>

Thanks so much guys this is very helpful. I was confused because I assumed the name was the instance of the composite type. However I still don’t quite understand how it is that I can enter the name into the method or function without issue, but only the value is returned. Is there somewhere that explains in what point in time they are separated within the method? Also I am still not sure how the @show workaround would work in this case. If I try something like. `battle(x::warrior, y::warrior) = x.strength > y.strength ? @show(x) : @show(y)` I get the following output.

````julia
y = ninja(12, "stealth")
ninja(12, "stealth")```
````

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [September 19, 2022, 8:14pm UTC](https://discourse.julialang.org/t/how-to-return-an-instance-of-a-composite-type-based-on-a-given-field-value/87374/14 "2022-09-19T20:14:16Z")

</div>

Inside functions, the variable gets a local name (`employee` in my second example above). In fact, my first example also shows a reassignment of variable names. Either way, the compiler happily replaces these names with numerical memory addresses (and intermediate names), because they only serve the purpose of communicating to the programmer.

`@show` works because macros (like `@show`) are given access to the entered _expression_. You can think of `@show snakeeyes` as a special version of a function `_show( :snakeeyes )` which first uses the supplied `Symbol` as is, and then `eval`uates it to extract its value.
