Is it possible to define a method/function/macro/etc so that I can use ⟦⟧ to index a custom vector/struct? I’m looking for some kind of trick that would allow me to do something like the following:
struct MyVec
data
block_size
end
v = MyVec([1 2 3 4 5 6 7 8 9 10], 2)
...what I need...
i = 1
v⟦i⟧ = [5 5] # == v[(i-1)*v.block_size+1:i*v.block_size] = [5 5]
v.data == [5 5 3 4 5 6 7 8 9 10]
>> true
Are you asking because you also need regular indexing to work alongside this? If not, you can simply overload Base.getindex and Base.setindex! to define whatever indexing behavior you want for your struct.
Using custom symbols as brackets isn’t possible though, and it turns out that those particular symbols can’t be used at all…
julia> ⟧ = 1
ERROR: syntax: invalid character "⟧" near column 1
Yeah, this can be done with a macro if you really want:
using MacroTools: postwalk, @capture
macro foo(expr)
(esc ∘ postwalk)(expr) do ex
if @capture(ex, v_{i_})
ex = :($v.data[($i-1)*$v.block_size+1:$i*$v.block_size])
end
ex
end
end
struct MyVec
data
block_size
end
v = MyVec([1 2 3 4 5 6 7 8 9 10], 2)
i = 1
No, {} is not a valid indexing delimiter in julia, but it parses like one specifically so they can be used in macros. We can lessen the amount of logic that’s in the macro though and offload the work to a special mygetindex function:
using MacroTools: prewalk, @capture
macro foo(expr)
(esc ∘ prewalk)(expr) do ex
if @capture(ex, (v_{i__} = x_))
:($mysetindex!($v, $x, $(i...)))
else
ex
end
end
end
mysetindex!(v::MyVec, x, i) = v.data[(i-1)*v.block_size+1:i*v.block_size] = x
julia> @foo begin
v = MyVec([1 2 3 4 5 6 7 8 9 10], 2)
i = 1
v{i} = [5 5]
v.data
end
1×10 Array{Int64,2}:
5 5 3 4 5 6 7 8 9 10