I have been implementing a new type of array which is just a normal array except the content is fetched in the background and everything about it is the same as a normal array including access etc.
I call this Array the Ghost Array. For example I have been defining functions like
So I am overloading the getindex method which is fine. But I want GhostArray to work with hundreds of methods and the pattern for doing so is the same which is.
So I want for all fn, do the above. But there is no way to know all possible fn. And people can always define more fns. Also there are fns where GhostArray is not the first argument. I want to “overtake” them too.
Solutuon
One way I thought would be to have some Trojan horse types that can take over the any function and replace itself with materialize(a).
I call these types the Trojan horse types, because they go in and try to take over.
I don’t think this can be done in Julia yet. I know of Cassette.jl but I think that would require the code to be run in a context so can’t deal with all possible functions (my understanding might be off here).
I would highly appreciate if anyone can point to programming language research that already has this idea discussed and researched this and if there are languages already implementing this.
Would be nice if something like this is possible in Julia though. Or maybe it is already! Please enlighten me!
Can you make some pseudocode of what you want it to do? Maybe a few dumby examples. I think I know what you want, but don’t want to completely miss the point with my answer.
i don’t know if i have the same problem, but is at least similar.
I have a function $property(model,volume,temperature,mol_fraction) where mol_fraction is an array. i have a subtype of AbstractArray called AbstractMaterialVector (takes care of conversions between mol and mass quantities) and i need to do something like
Interfaces, proper use of Abstract type trees and promotion should get you quite far. Once this is no longer the case, loops with @eval is as far as I know the goto solution. If there is a better way I would certainly like to know, as I make extensive use of this strategy
I think that’s a good practical solution. I think I am getting is that it’s not possible in Julia to this in general.
You can do this for all functions that exists already. Possibly using a macro, but there is no way to do this for all functions. Unless you put it inside context and use Cassette.jl
Which is fine. Just confirming that it’s not possible is good enough for me
Could you overload splat, with a ternary operator? Caveat, all fn args would need to be supplied as tuples. Maybe splat is one of those protected thingy madoodles.
If I understand it right, you want a different behavior for a base type at the value level?
If there are n definitions like fn(a::GhostArray, kwargs...) = fn(materialize(a), kwargs...) for m functions like fn, GhostFunction-based approach requires O(n) + O(m) lines; you need O(nm) lines in a naive approach.
You can use map over args and materialize it if the argument isa GhostArray. Julia is clever enough to compile it away.
This question comes up very frequently. I think that the right solution to this problem is to define and document an interface that a particular thing has to comply with, and keep it small.
If you just want to implement an <:AbstractArray, I am not sure where those “hundreds ot methods” are coming from. Ideally, if they work for an <: AbstractArray, and you implement the API for the latter, they should work for your type, too.