messing around with “automagic” (macros) is not neccesary for beginners or even most advanced users. Consider you are free to write the mundane and powerful thing
reader(vec,symb) = (getfield(p,symb) for p in vec)
then you can do things like
total_ages = sum(reader(ps,:age))
but using a bit more characters to write sum(p.age for p in ps) is probably preferred to readability.
If you are attached to the fuzzy feeling of vectorized code (note there’s really no need, the for loops in julia are fast, but I get it!) there are some cool packages like Transducers.jl that are especially powerful.
… and yet, having a (automagically created) function named like the field would, IMHO (and not only mine), make life easier. There are non-Julia precedents.
I guess I will live with the x -> x.field functions.
There’s no good reason to do that when the dot syntax and the underlying getfield and getproperty already exist, and there’s a good reason to avoid doing that: although Julia lacks formal access modifiers, something similar is done by getter/setter methods being public API while the fields remain internal details that can change in minor revisions. Typically the getters and some of the types’ fields will diverge in names and structure. That’s not done for every type; fields or derived properties may be exposed as public API and idiomatically accessed by dot syntax.
But what’s wrong with getfield.(persons, :age)? It seems to what you are looking for, except better, because it doesn’t pollute the namespace with a function.
Field names are supposed to be internal and ‘hidden’, producing functions that ‘steal’ those names seems really bad to me.
Is it idiomatic in any language to automatically generate getter and setter methods for all fields like you’re suggesting? From what I’ve seen, getters and setters are manually implemented to do more than just expose fields ie validation or derivation, and automatically exposing all fields goes against encapsulation principles. Dot syntax is used for simple access of fields, and only the public fields in languages with access modifiers.
But what if you really don’t want such a function to be automagically generated. Then it would be a bad idea, don’t you agree? I want internal names to be hidden. Isn’t it more reasonable that you opt in to this behavior when you need it, by defining a function?
Oh yes. It is idiomatic in at least another language. The one with even better macros than Julia (look ma, no ‘@’), many implementations and some very good compilers.
Have only seen that in Haskell, but some other functional languages might also do that. Clojure has a clever compromise in that symbols are callable and look themselves up in a struct, i.e., (:fieldname obj) instead of obj.fieldname or fieldname(obj).
I won’t make claims about which language has better macros, but I can let you know that the @ naming convention was deliberately chosen to visually distinguish macros. They’re not a necessary evil, but a design choice. So presumably, the devs thought this was, actually, better.
(Amusingly, and incidentally, biking without your hands is actually a bad idea.)
Well, I had a “I am missing something with Julia macros” moment a couple of weeks ago, but maybe I just need to grok them better.
As per the devs, I have horror stories (well, maybe just comedy ones) about devs being quite wrong. Again, the ‘@’ is also no biggie: another thing I can live with it. I wouldn’t be here otherwise.