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. 
>>
>
>

Reply via email to