I’m building a function that receives an object as input, and depending on whether the type of this object is standard or user-defined (=composite type defined by the user through a struct) it must do one thing or another. Something like
if typeof(x) == user_defined
such that if I define
mutable struct conch
x :: Int
y :: Float64
conch() = new()
As Tamas says, the concept of a user-defined type doesn’t really exist in Julia. However, there do exist primitive types (e.g., integers, floats, other chunks of raw memory), though primitive types might well not include all the types you are interested in. (And users are free to define their own new primitive types!)
It might help to get at which meaning of this you want by asking: what should happen on the future if Julia introduces a new predefined type? Would your code break if that was included or if it wasn’t?
so inspecting whether the list is empty or not I know if I must recursively call the function.
The problem I don’t know how to sort out is that, when passed R to a function, fieldnames() does not provide the complete names of the variable passed to it
but in that case, what I get is Symbols, and their length is always 0.
Can on easily get filenames)=, acting on z in function dale(z), to give the whole name of the original argument passed to it (R in dale®), so that I can check the length of the fields?
Please accurately define what do you meman by “user-defined struct”. Is a type defined in Base module one? What about one defined in a stdlib package? What about a third party package? Does it only belong to a few packages you are interested in? Does it have to be from a script (i.e. from Main)? Does it have to be a type you defines? Or maybe it could be a type that others could define that satisfy some properties? If so, what are those properties, can you just test those instead?
Is being a struct the only important feature? (i.e. you want to test if it’s a primitive type).
Also related is do you care about the field type or the field value. That determines if you need to handle abstract type.
You see, every single questions I raise above should have a well defined and relatively simple answer that you can easily code out. From your krok, reptil example, however, it’s unclear what about those types are so special that you need to recurse into them. In general, if what makes them special is some general concept of the type, then you just test that after figuring out what it is (see above). Otherwise, you are interested in some property that’s only interesting for you (which is the most common and most useful case BTW) and you need to encode that info yourself, say by either inherit them from the same abstract type, or (possibly combined with abstract type) specializing your “function” (for printing??) on these types.
P.S. are you sure you are not just looking for show?
Too many questions
I guess, at least for a start, that the data types I will be using are those created by me and only me in my codes, a type defined by me. No packages, no nothing else. So it is the ‘some property that’s only interesting for you (which is the most common and most useful case BTW)’, in your own words…
I highly doubt if this is actually the property you are interested in, by which I mean, you (the programmer) might be interested in it but in general code (written by you) shouldn’t really care about it’s author. Having your friend fixing a typo in your code will change the (co)author of the code but shouldn’t change the code’s behavior in a way that’s different if you made the change yourself. There’s just no way this can happen with current computer technology.
I should clarify this as “objective property” or “code property”. Anything that your code can react to, rather than anything that is intersting to you for other reason…
I give you a long list since it’s AFAICT the simplest way to guide yourself to the definition of your “user-defined struct”. It’s also to help you to formulate your question in a way that others can actually help. Otherwise there are only guesses and that’s what I’m going to do below too.
The closest interpretation of what you said I can come up with is that you want to treat types in your script differently than anything else. You are not using any packages. In that case, it’s included in my list of questions above and, well, just test if the type is from Main should work for you, i.e. T.name.module === Main. Note that this will break if you move the code. Change Main to @__MODULE__ will work if you put it in a module. It’s still a property that makes no sense to query other than for some low level purposes. In particular, it’s orthogonal to whether the type has field to be iterated, which is what you want to do, so making the decision this way is almost certainly wrong.
If you don’t care too much about the maintainability of the code, you can just hard code the list of special types for you, which is actually a much better method in many ways. OTOH, if you want an answer with a more maintainable approach that makes more sense, you really need a definition of “user-defined struct” that is actually based on some programatically distinguishable properties. Again, the list I have above should be a good place to start.
Thanks for the info but… honestly, you’re making a mess out of the question. The situation I want to solve now is not a general case, it is as simple as the kook() and reptile() case above, defined by me and used by me. Nothing fancy, nothing that should care too many people…
OK, in that case and if you don’t want to read any one of my potential implementations above, for which I have at least 3, just define your function to treat kook and reptile type differently. That’s as simple as it gets.
Edit: Then update your title please. Your title is very generic. It doesn’t mention kook or reptile specifically. If the example you gave are not examples of a more general question but actually the question itself, please clarify.
Yes there’s a simple fix, by looking at which module the type is defined in. (Again, the answer has already been posted above.) Replace the two inspect methods with:
function inspect(r, padding = 0)
parentmodule(typeof(r)) ≡ Main || return print(r) # not user-defined
# user-defined type
for f in fieldnames(typeof(r))
print("\n" * " "^(padding+2) * "$f = ")
inspect(getfield(r, f), padding + 2)
Note: This is just a proof-of-concept. You’ll need to replace Main above with whatever module your types are defined in, and if you have hierarchical modules you’ll need to add support for that.