Tim,

The fact that 'next' is called before the loop body rather than after means 
that the 'done' predicate must provide an answer to the question: "if 
'next' is called on the current state, then would the result be the end of 
the data structure?"  The obvious way to answer that question is to 
actually invoke 'next' to see what happens. For a balanced tree, there is 
no simpler way that I know of to answer the question other than calling 
'next'.  It is possible to avoid the performance hit with additional code 
complexity by caching the result of 'next', but still, the question 
remains, why are start/done/next implemented in this way instead of the 
more obvious way (for example, in the C implementation of for(..; .. ; ..) 
the 'next' operation is invoked at the end of the body).

-- Steve



On Wednesday, July 23, 2014 12:29:12 AM UTC+3, vav...@uwaterloo.ca wrote:
>
> Dear Julia users,
>
> As I have mentioned in earlier posts, I am working on a 2-3 tree 
> implementation of a sort-order dict, that is, a dict in which the (key, 
> value) pairs can be retrieved in the sort-order of the keys.  According to 
> section 2.1.7 of the manual, "for i = I; <body> ; end" translates to:
>
>   state = start(I)
>   while !done(I, state)
>       (i,state) = next(I,state)
>       <body> 
>   end
>
> The more obvious way to implement the loop would be to put the body BEFORE 
> the 'next' statement, and at first I thought that maybe the manual has a 
> typo.  But then I checked the file dict.jl, and I found indeed the code:
>
> done(t::ObjectIdDict, i) = is(next(t,i),())
>
> So this means that every loop iteration over an ObjectIdDict requires two 
> calls to 'next', one as part of the call to 'done', and a second one to 
> actually advance the loop.
>
> I also looked at the code for 'done' for Dict in dict.jl, and it appears 
> to be buggy(??).  It does not check whether everything after the current i 
> is deleted(??)
>
> For a 2-3 tree, the 'next' operation is logarithmic time, so requiring it 
> twice per loop iteration is undesirable.
>
> Can anyone shed light on why the Julia loop construction is implemented 
> this way, so that two separate calls to 'next' are necessary?  I suppose 
> that it is possible with additional code complexity to cache the result of 
> the first call to 'next' inside the state, but what exactly is the 
> rationale for the current design?
>
> Thanks,
> Steve Vavasis
>
>

Reply via email to