I'm considering writing a type similar to those defined in NamedArrays and Images. Let's say I just want essentially an Array with a piece of metadata, say a user-friendly name that I'll write at the top of a file when I write the array to disk. (This detail is not relevant; I'm just contriving an example.)
So I might do
type MyNamedArray
data::Array
name::ASCIIString
end
function mywrite(f,x::MyNamedArray)
write(f,x.name)
write(f,x.data)
end
or something, and no other behavior needs to be different from the base Array behavior.
In my head, it's "obvious" that I just want every existing function that operates on Arrays to operate on the data
field of this type. In another language e.g. Java I might have just subclassed Array and added name
as an instance field to the subclass, which would automatically preserve compatibility with all the existing Array operations. But in Julia, if I try a solution such as that above, I now need to define a ton more functions, e.g. as @TimHoly and 'davidavdav' have done in the linked packages.
Of course I am aware that being forced to write out some of these functions by hand is useful for realizing things that you haven't thought through. E.g. in the example MyNamedArray
I give above, one could object by pointing out that I haven't defined the name of x::MyNamedArray * y::MyNamedArray
. But what if I just don't care about that, and want code that "just works," without so much boilerplate? (See e.g. looping over symbols to push new method definitions in NamedArrays and manually writing out a hundred lines of definitions in Images. The vast majority of these definitions are boilerplate / the "obvious" definition.)
Specifically to continue the example I cited, for MyNamedArray
, the default could be x*y
is no longer a MyNamedArray
, i.e. since every function just defaults to the "inherited" behavior of applying the same function on the underlying data, we can just forget the metadata on all pre-existing functions.
Note, I find Tomas Lycken's answer here insightful, and so are the question and answers here.
The best synthesis I can come up with is "you just have to suck it up and write out the functions, or write a macro that does that for you." If this is the case, so be it; I'm just wondering if I'm missing a better option, particularly a better way to design the solution to make it more Julian and avoid the boilerplate.