Re: [julia-users] iterator construct seems incorrect?

2014-07-23 Thread Mauro
Hi Steve

 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.

Presumably for ObjectIdDict calling next is cheap, so there is no reason
to avoid one extra call.  In particular as ObjectIdDict is coded in C,
this avoids having to write more C code.

 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 `Dict` `done` does not call `next` again.  Maybe you can model your
iterator after that?  Also, I think there is no bug in it, as `skip_deleted`
will return the index of the last `d.vals` if there are no more filled
slots, which in turn makes `done` true.


[julia-users] iterator construct seems incorrect?

2014-07-22 Thread vavasis
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



Re: [julia-users] iterator construct seems incorrect?

2014-07-22 Thread Tim Holy
You seem to be attributing a general principle where I don't think there is 
one. For example, see the iterators in base/range.jl; there are not two calls 
to next.

--Tim

On Tuesday, July 22, 2014 02:29:12 PM vava...@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