Re: Gee Functional iterators - call for consensus



On Wed, 2011-06-29 at 14:04 +0100, Maciej Piechotka wrote:
> On Wed, 2011-06-29 at 13:11 +0200, Quikee wrote:
> > Hi,
> > 
> > I intended to write this for quite some time - I am sorry that it took so long.
> > 
> 
> No problem.
> 
> > I have looked at the implementation and proposal for "functional
> > iterators" and I have some remarks and things I really don't like.
> > 
> > - Implementation directly on iterator interface: Even if it is legal
> > to do it in GObject I don't like that the interface contains the
> > implementation and then you are forced to override it in your
> > implementation just to do something different. This is for example
> > also the reason for the existence of AbstractCollection and co.
> > because neither I nor Didier did not want to put code into the
> > interface. I hope you will also change this for the iterators.
> > 
> 
> Well - possibly due to different background I like virtual method in
> interfaces (i.e. like classes in Haskell). They allow to change
> interface w/out breaking API (breaking ABI however).
> 
> > - Stream function: Stream function is for me just a implementation
> > detail how the functional iterators are implemented. I don't think it
> > is wise to force it into the interface of iterator. They should be
> > available but only as a special type of iterator or something similar
> > that is just used as the implementation and hidden on the interface. I
> > also don't think there will be a lot of people that will write its own
> > functional operator anyway. I must also say that I don't like that
> > stream operation as it is very hard to read what exactly it does and
> > how it works. The performance might also be an issue as functional
> > programming languages are heavily optimised for (tail) recursion and
> > lambda but vala is not. Still if the stream operation is just regarded
> > as a implementation detail I don't mind.
> > 
> 
> The stream function was written for performance reason. The Vala does
> not optimize the virtual calls at all so they perform slowly as Java or
> C# would do. Vala have no static or dynamic type analysis and therefore
> each call to interface goes through 1-2 jumps by function pointers.
> 
> For exact numbers see:
> 
> https://bugzilla.gnome.org/show_bug.cgi?id=645850#c4
> 
> It is written mostly for implemantators as it:
> 
>  - Allows to reuse of code across functions (like map etc.) therefore
> making life of people implementing new combinators easier (i.e. Jurg,
> Dider, mine, ...). I agree that it is small benefit and therefore it was
> not in original spec.
>  - As a side effect it allows to implement all functional methods to be
> implemented efficiently by just reimplementing forall and stream. As it
> generally have huge impact (virtual calls are heavy in Vala, virtual
> calls to interfaces via abstract classes are even more).
> 
> As shown in the data I've linked it have the  some constant overhead
> (which quickly outperform other methods except .get for array).
> 
> In short - it is implementation detail but important one from
> performance POV (yes, I was surprised by benefits of forall).
> 
> > - Call to iterator() before executing an functional operation is not
> > elegant. Each collection could have functional operations directly
> > accessible as well and just could delegate to the iterator when it is
> > called.
> > 
> 
> Hmm. +1?
> 
> What about something like Stream interface from which both Collection
> and Iterator inherit?
> 
> Edit: it seems you call it Functional. I'm not particulary happy with
> either of names.
> 
> > - In my opinion a functional operation is in itself an special
> > iterator not an additional method on iterator itself. I don't like
> > that I can call iterator() and do next() next() next() and afterwards
> > call a functional operator. What can I expect in such an case?
> 
> Ok. There was take and skip operators in spec which get lost.
> 
> it would be something like:
> 
> iterator().skip(3).map(func)
> 
> 
> > Also
> > there is nothing preventing an Iterator to never end the iteration
> > (not in any implementation in libgee but doable with a custom
> > iterator). What can I expect in such a case from an functional
> > iterator?
> > 
> 
> They produces elements as they go. So say there is iterator returning:
> 
> iter = [1, 2, 3, 4, ....]
> 
> iter.map((x) => {return x + 1;}) returns
> 
> [2, 3, 4, 5, ...]
> 
> iter.scan((x, y) => {return x + y}, 0) returns
> 
> [0, 1, 3, 6, 10, ...]
> 
> > I hope you don't take this negatively this is my personal opinion and
> > I also may be wrong. :) Generally I like the interface.
> > 
> 
> No. It would be... well stupid if I sent RFC/call for consensus
> expecting only positive feedback. Well - ok, I do hope everything is
> fine with my original design ;) but from my experience negative, but
> constructive, feedback is the most valuable one.
> 
> > I have also implemented how I think the functional iterators should be
> > implemented (however I am not totally happy with the code but it
> > should be good enough as an example).
> > The code is available as a clone of your repository in gitorious in:
> > http://gitorious.org/~quikee/libgee/quikees-mpiechotkas-libgee/commits/functional-iterators
> > 
> 
> To be honest I don't like the separation of FunctionalIterator and
> Iterator. Every iterator is, conceptually, functional iterator. There is
> no iterator for which you cannot define meaningfully map function.
> 

Sorry for double-posting. Also - your implementation uses foreach by
default which is a bad idea from performance POV as mentioned before.
(Namely 20x performance degradation for 1023 element array).

> > Regards, Tomaž
> 
> Regards

Regards

Attachment: signature.asc
Description: This is a digitally signed message part



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]