Sometimes I’d like to be able to write
r = 1:End()-1
x[r] .= y[r]
Is this a good idea and how to achieve this?
Sometimes I’d like to be able to write
r = 1:End()-1
x[r] .= y[r]
Is this a good idea and how to achieve this?
Are you concerned by the cost of building the 1:end - 1
range in:
x[1:end - 1] .= y[1:end - 1]
?
No, not at all, just for readability in expressions like
sk=10; plot([first.(y[1:sk:end]) for y in ys[1:sk:end]],[last.(y[1:sk:end,end]) for y in ys[1:sk:end]])
vs
r=1:10:End()
plot([first.(y[r, end]) for y in ys[r]], [last.(y[r,end]) for y in ys[r]])
You could define
End
type, eg describing end + a
,Base.colon
method, that emits another custom type which can contains ranges with this kind of endpoints,Base.getindex
and Base.setindex
method for this custom type.I don’t think it is worth it though. If in the above example you don’t want End
to resolve differently for x
and y
and they have the same indexes, you could use something like
r = indices(x, 1)[1:(end-1)]
x[r] .= y[r]
Otherwise, I think that x[1:(end-1)] .= y[1:(end-1)]
is just more readable.
I once (in Julia 0.2 or 0.3) made such an End
type: Bitbucket
But I’m sure there are better ways to go about it. But it’s not trivial, that is why Julia opted for a syntax approach to the problem.
I could also image to define something along the lines
struct Formula{T} f::T end
farg(args, symb) = last(args[findlast(x->first(x)==symb, args)])
import Base.getindex
(f::Formula)(;args...) = f.f(;args...)
getindex(a::AbstractArray, f::Formula) = a[f(END=length(a))]
so that for
r = Formula((;args...)->1:farg(args, :END)-1)
julia> rand(10)[r]
9-element Array{Float64,1}:
0.355413
0.26395
0.260973
0.0454235
0.860611
0.958574
0.912541
0.812007
0.500342
and then define a macro @formula
giving syntactic sugar to r = Formula((;args...)->1:farg(args, :END)-1)