So, if I understand correctly, the problem you're trying to solve is that
A[end] lowers to getindex(A, endof(A)), but you want to know that the index
is the last one since you can implement a more efficient algorithm in that
case.
Making getindex a macro won't solve this problem, so lets set aside that
discussion. But there may be a solution for you here. You can try using a
special index type that specifically refers to the number of indices from
the end.
immutable BackwardsIndex <: Integer
i::Int
end
Now simply add `getindex(::YourType, ::BackwardsIndex)` method that
traverses the dequeue backwards. `x[BackwardsIndex(1)]` then refers to
your last element with O(1) complexity. That's pretty verbose, but here's
what you can try: make `endof(::YourType) = BackwardsIndex(1)`. Now
`A[end]` is O(1) complexity. This won't work for AbstractArray subtypes,
but I think it should work for other custom indexable types.
You can even add primitive arithmetic to the BackwardsIndex type to support
things like `A[end-1]`, but anything more than that becomes complicated
fast. What's `x[end÷2]`? Or worse: `x[rand(2:end-1)]`? These are the
same challenges that a syntax-level change would rapidly run into.
Matt
On Thursday, May 26, 2016 at 2:45:34 PM UTC-4, Stefan Karpinski wrote:
>
> The difference is that a symbol is a value but `end` is not a value. If
> you can write
>
> v[:foo]
>
>
> then you should also be able to do this:
>
> x = :foo
> v[x]
>
>
> This precludes doing the lookup at compile time – except as an
> optimization. That argument doesn't apply to `end` since the `end` keyword
> is purely syntactic – trying to assign `end` to a variable is just a syntax
> error:
>
> x = end
>
> v[x]
>
>
> Lowering things to macro calls is sometimes effective – we do this for
> non-standard string literals, for example – but it should be done as
> sparingly. In this case, the only thing that you're going to accomplish
> with this approach is to make a feature that's thoroughly broken. For
> example, by having v[:foo] do one thing while `x = :foo; v[x]` does
> something completely different.
>
> On Thu, May 26, 2016 at 2:31 PM, Ford Ox <[email protected] <javascript:>>
> wrote:
>
>>
>>
>> Dne čtvrtek 26. května 2016 18:03:50 UTC+2 Yichao Yu napsal(a):
>>>
>>> > Because it is done at compile time, where you can even decide to call
>>> > completely different function. See
>>> > dequeue = .....
>>> > dequeue[:first] # is replaced with different function than dequeue[1]
>>> > dequeue[:last] # is replaced with different function than dequeue[end]
>>> (
>>> > O(1) vs O(n) )
>>>
>>> I don't see what you mean by compile time. You cannot dispatch on the
>>> symbol at compile time. If you use syntax level rewrite, there's no
>>> point of using symbol either.
>>>
>>
>> What do you mean by syntax level. Why there is no point for using symbol
>> if that's the case?
>>
>>
>>>
>>> >
>>> > Because you can define your own syntax. The :middle was just stupid
>>> example
>>> > to show you, that you can decide on your own symbol based on
>>> collection you
>>> > are working with ( say there is collection which when accessing middle
>>> has
>>> > different complexity than accessing other elements).
>>>
>>> You can easily do this by defining your own token. Misusing the symbol
>>> syntax isn't the right way to go.
>>>
>>
>> Yeah, I also feel that using symbol is not the right approach, but I
>> couldn't think about any other simpler way of doing that.
>> Can you show me what do you mean by token?
>>
>>
>>>
>>> >
>>> > Of course you can do arithmetics with this approach.
>>>
>>> No you can't. Not in a way that you can overload it for different types
>>> anyway.
>>>
>>> >> Which is what make the way you propose unsatisfying.
>>> >>
>>> >
>>> > Are you talking about [ FIRST = :first ]?
>>> > If so, I could argue about this since you can't also do [ LAST = end ]
>>> > The only difference is that [ LAST = end ] throws error at compile
>>> time.
>>>
>>> The difference is that `end` is a keyword. And symbol literal is not.
>>>
>> Which is intended and its fine.
>> The problem is that user won't know, what symbols should he use, unless
>> he checks the docs, which is not nice.
>>
>
>