Yeah I agree with you, we can use multiple dispatch with completely same 
result and it will actually work.
Even the user will know, what types of parameters he should paste in.

Problems begin when I import it.
Lets say I have defined it like this:

type Dequeue ... end
type Last end
type First end
getindex(d::Dequeue, ::Last) = last(d)
getindex(d::Dequeue, ::First) = first(d)
pop!(d::Dequeue, ::Last) = pop!(d) # removes and returns last element
pop!(d::Dequeue, ::First) = shift!(d) # removes and returns first element
pop!(d::Dequeue, index::Int) = splice!(d) # removes and returns element at 
index x

But types Last and First can still class with my own types!
I would also like to call it like this:
dequeue[Last]
#instead of this
dequeue[Last()]

Is there any way to workaround these problems?

Dne čtvrtek 26. května 2016 21:23:32 UTC+2 Matt Bauman napsal(a):
>
> 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]> 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