Sorry, I can’t understand these type of changes. On 0.7 we now get
Warning: `fieldnames(v)` is deprecated, use `fieldnames(typeof(v))` instead.
And when the deprecation stage is over one will get only a, +/- comprehensible, error message.
The old behavior was much more user friendly. Why making life of users more difficult?
Because the old one is very dangerous. The function had to guess if you want to know something about the type or the type of the type. Try fieldnames(Vector) and fieldnames(Array) on 0.6.
Agree with the general statement. But in this case I think it’s easier for a user. I remember playing around with typeof s, supertype s and fieldnames and was wondering why fieldnames(v) would work. Shouldn’t it be an instance of a type which has the fieldnames? With this change I think it’s clearer b/c there is no confusion between value and type.
Sorry, I must be missing something (did not understand the fieldnames(Vector) example). When would the fildnames of a type and of an instance of that type be different?
And so that would be the case when one would have to use fieldnames(typeof(type)), which you’ll agree is a much rarer case than the Joe normal user wanting to know the fields of a certain struct
No, absolutely not. There is no risk at all of giving the wrong answer silently.
Sorry, meant to say 0.5. not 0.6.
And doing something at all for those cases is terrible. So basically if the function is to do both things, it would have to raise an error for the ambiguous case, which means that for those ambiguous case which are actually useful, the function cannot possibly do anything. As a more concrete example, if you want to know what’s the field of a Vector type, you need to figure out a way to get from it to Array (And not the thing that binds to the Array name, but the Array datatype).
So you think it is better to implement a function that send you a message on the forum whenever it encounters an ambiguous case?
The issue here is also that we have different views on the importance of simplicity. If the two user situations are so important, create a new function parentfieldnames(...)
I’m not sure what do you mean by two user situations and what is parentfieldnames supposed to do but if you want to have a function that treat everything as value instead of types, you can have your own function to do that. You can even implement your own heuristic to guess what you want to check in the repl. The reverse cannot be done.
But isn’t the simplicity here only the fact, that one has to enter fewer character in the keyboard?
In x = Dict("hi"=>"world") the variablex doesn’t have fieldnames AFAIU. Only its type, typeof(x) has. And fieldnames(typeof(x)) shows the fields which can be found in the ‘mutable struct’ definition in base/dict.jl. To know the type of the Dict, a DataType, and the fieldnames thereof, it’s fieldnames(typeof(typeof(x))) and the definition can be found in base/boot.jl. This seems easy and consistent.
But fieldname(x) is confusing for me. If this gives the fieldnames of the Dict type, why doesn’t fieldname(typeof(x)) give the fieldnames of the DataType type? Why should a DataType be treated differently than a (e.g.) Dict type?
In my view of simplicity, if the variable has no fields, it would say so in output. Like it does in
julia> fieldnames(0)
0-element Array{Symbol,1}
otherwise if it has then list them. I’m just imagining the number of surprised users in future when they will get an error when doing fieldnames(some_var_type) and will have to go dig the manual why so.
On the plus side, the error could stay informative: if passed something that is not a type fieldnames could explain in the error what is now explained in the warning.
A variable never has any field. A variable has a value. As I said, if you want to have a function that tell you what fields a value has, go ahead and do that yourself, just make sure that it is not the same function that tells you what field a type has.
It’s not about me. Honestly it’s my presumption (hopefuly wrong) that in name of such purist principles Julia will be sending away many users with unfriendly behaviors like this.
It’s trivial to define: fieldnames_t(v) = fieldnames(typeof(v)), which avoids the problems that Yu Yichao and others have brought up, while keeping what you want relatively short and sweet.