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
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.)
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?
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.
No, because the values of variables are not aware of the variables’ names.
You could do this with metaprogramming, such that
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.
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.
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 evaluates it to extract its value.