Hi Simo, As for the modularization, I went ahead and did this in the trunk. On the overall I think Bruno's work is proceeding in a good direction, so I agree that it should be merged back to trunk when ready. I have some more refactorings i am interested to try out on this, or another, branch. These are all, of course, my opinion:
- LoopingGenerator's wrapping constructor should only accept other looping generators; otherwise, the objects will do things users probably don't expect. - LoopingGenerator should be renamed to something that relates to its "stoppable" quality. StoppableGenerator? InterruptibleGenerator? - Several of the generator implementations, e.g. UntilGenerate, don't seem to behave consistently with their description. - I still feel Range should be decoupled from Generator. I think it would be better to join a Range<T> with a UnaryFunction<T, T> to create the step needed to go from Range to Generator. This would be more flexible than a simple addition-based step anyway. Does anyone object to any of these changes? Matt On Mon, Jan 28, 2013 at 2:46 AM, Simone Tripodi <simonetrip...@apache.org>wrote: > Hi Matt, > > I had a quick look at your branch and I honestly think it is a very > good work, maybe we could insert even more modules granularization, > but IMHO it worths to merge it in the main branch. > Do you see any blocker? > > Best and thanks! > -Simo > > http://people.apache.org/~simonetripodi/ > http://simonetripodi.livejournal.com/ > http://twitter.com/simonetripodi > http://www.99soft.org/ > > > On Sun, Jan 27, 2013 at 6:39 PM, Matt Benson <gudnabr...@gmail.com> wrote: > > All: I have merged Bruno's work to > > > https://svn.apache.org/repos/asf/commons/proper/functor/branches/FUNCTOR-14-mmbased > > on functor's multi-module reorg. > > > > Matt > > > > > > On Wed, Sep 19, 2012 at 2:12 AM, Simone Tripodi < > simonetrip...@apache.org>wrote: > > > >> Olá Bruno, > >> > >> excellent work, congrats!! I will have a look tonight (my local TZ) > >> I'll try to let you know ASAP! > >> > >> thanks, all the best! > >> -Simo > >> > >> http://people.apache.org/~simonetripodi/ > >> http://simonetripodi.livejournal.com/ > >> http://twitter.com/simonetripodi > >> http://www.99soft.org/ > >> > >> > >> On Wed, Sep 19, 2012 at 4:12 AM, Bruno P. Kinoshita > >> <brunodepau...@yahoo.com.br> wrote: > >> > Hi all, > >> > > >> > me again bringing a new implementation idea for the Generators API > >> > > >> > in [functor], and looking forward to some thoughts on this :-) > >> > > >> > There is a separate branch for this issue [1], and here's what has > been > >> done. > >> > > >> > - Split Generator interface into Generator interface and LoopGenerator > >> > (abstract class). IMO, this will help in modularization (see this > >> discussion [2]) > >> > in the Generators API, as the stop() method and the wrapped > generators, > >> > for instance, had been added because of the generators created for > >> handling > >> > execution flow control (e.g.: GenerateWhile, UntilGenerate, etc). > >> > > >> > - Moved LoopGenerator and its implementations under the newly created > >> > org.apache.commons.functor.generator.loop package. > >> > > >> > - Moved IntegerRange and LongRange from > >> org.apache.commons.functor.generator.util to > >> > the newly created org.apache.commons.functor.generator.range package. > >> > > >> > - Created a Range API, with a Range interface, a Ranges helper > interface > >> and > >> > some implementations (including existing IntegerRange and LongRange, > and > >> new > >> > ones like DoubleRange, FloatRange and CharacterRange). > >> > > >> > - Added steps different than 1 to Ranges (not the generator interface, > >> as this > >> > is related only to ranges). > >> > > >> > - The Ranges implemented are all Generators too, what is very > >> convenient, as you > >> > can use Ranges to both define intervals and/or execute a procedure for > >> each of its > >> > elements. > >> > > >> > I've wrote a sample code using the existing Generators API [3] and > wrote > >> the > >> > same code for the new Generators API [4]. The API is compatible, but > as > >> some > >> > packages changed, you have to update existing code (but as [functor] > >> hasn't been > >> > released yet, it shouldn't be a problem I believe :-). Both codes > >> produce the > >> > same output too (0 1 2 3 4 5 6 7 8 9 ). > >> > > >> > And here's an example [5] of creating Ranges and using them as > >> Generators. More > >> > examples can be found in the tests for the Generator and the Range > API's. > >> > > >> > I've updated the examples page and added tests. I've also updated the > >> parent > >> > pom to 26, but as this is not related to the FUNCTOR-14 issue, we can > >> drop this > >> > > >> > part when merging the code. > >> > > >> > I'll merge the changes to trunk if everybody thinks this new > >> implementation is > >> > better than the current one. > >> > > >> > A side note: PHP recently got generators too [6], and an interesting > >> thing that I noticed in > >> > their Wiki was the discussion about callback functions. After reading > the > >> > discussion, for me it looks like [functor] generators API is more > >> similar to > >> > callback handler. Differently than the Python and PHP implementations > >> with the > >> > yield statement. > >> > > >> > Thank you in advance! > >> > > >> > [1] > >> > https://svn.apache.org/repos/asf/commons/proper/functor/branches/generators-FUNCTOR-14 > >> > [2] http://markmail.org/message/nymsk7l64aj4csxi > >> > [3] https://gist.github.com/3747204 > >> > [4] https://gist.github.com/3747207 > >> > [5] https://gist.github.com/3747224 > >> > [5] https://wiki.php.net/rfc/generators > >> > > >> > Bruno P. Kinoshita > >> > http://kinoshita.eti.br > >> > http://tupilabs.com > >> > > >> >>________________________________ > >> >> From: Matt Benson <gudnabr...@gmail.com> > >> >>To: Bruno P. Kinoshita <brunodepau...@yahoo.com.br> > >> >>Cc: Commons Developers List <dev@commons.apache.org> > >> >>Sent: Wednesday, 6 June 2012 9:56 AM > >> >>Subject: Re: [functor] Patch for FUNCTOR-14, new Generators and Ranges > >> >> > >> >>On Tue, Jun 5, 2012 at 11:48 PM, Bruno P. Kinoshita > >> >><brunodepau...@yahoo.com.br> wrote: > >> >>> Hi Matt, > >> >>> > >> >>> > >> >>>> Would there be a type of Range that could not be turned into a > >> >>>> Generator given a compatible Step parameter? If not, we could > define: > >> >>>> > >> >>>> interface Range<T, S> { > >> >>>> ... > >> >>>> Generator<T> toGenerator(S step); > >> >>>> } > >> >>>> > >> >>>> This way, Range itself does not contain a step, but still maintains > >> >>>> control over how a step is used to create a generator. > >> >>> > >> >>> I can't think of any type that could not be turned into a generator > >> given > >> >>> the step parameter. But if a range has no step, I think we would > have > >> to > >> >>> remove the isEmpty(), contains(), containsAll() methods from range > >> >>> implementations, as using steps higher than 1, we need to use the > step > >> value > >> >>> to check if a range is empty or contains a certain element (e.g.: > >> integer > >> >>> range (1, 2], step 3, check if contains(2) or isEmpty()). > >> >>> > >> >> > >> >>My thought was that by decoupling a Range from a step, you use only > >> >>the bound types/values to determine inclusion of a given value. If a > >> >>Generator is created from (1, 2] with step 3, then that Generator will > >> >>only return 1, but that doesn't reflect on the Range, IMO. > >> >> > >> >>Matt > >> >> > >> >>> > >> >>>> Either way, I like the notion that a Range is its own type that > just > >> >>>> *happens* to either provide access to, or an implementation of, > >> >>>> Generator. > >> >>> > >> >>> +1, let it provide access or be an implementation of Generator. In > >> case we > >> >>> do the latter case, I believe isEmpty(), contains() and other > methods > >> using > >> >>> the step value would be doable. > >> >>> > >> >>> Regards, > >> >>> > >> >>> > >> >>> Bruno P. Kinoshita > >> >>> http://www.kinoshita.eti.br > >> >>> http://www.tupilabs.com > >> >>> > >> >>> On 06/05/2012 11:52 PM, Matt Benson wrote: > >> >>>> > >> >>>> Hi, Bruno. Likewise, answers inline: > >> >>>> > >> >>>> On Tue, Jun 5, 2012 at 9:32 PM, Bruno P. Kinoshita > >> >>>> <brunodepau...@yahoo.com.br> wrote: > >> >>>>> > >> >>>>> Hi Matt! > >> >>>>> > >> >>>>> Thanks for your response! Answers added inline. > >> >>>>> > >> >>>>> > >> >>>>>> 1. Why are a Range's type and step-type potentially different > >> >>>>>> (different type variables, etc.)? > >> >>>>> > >> >>>>> > >> >>>>> When I started writing this patch, the range's type and step-type > >> were > >> >>>>> the > >> >>>>> same (i.e. the interface had only one generics type,<T>), but > then I > >> >>>>> created the CharacterRange and it didn't work because its range > type > >> is > >> >>>>> Character and its step-type is Integer (same would happen for a > >> >>>>> DateRange). > >> >>>> > >> >>>> > >> >>>> I see; good point. > >> >>>> > >> >>>>> > >> >>>>> What do you think? Maybe with some generics magic or with a > different > >> >>>>> approach we could remove the step-type? (I would be +1 for this) > >> >>>>> > >> >>>>> > >> >>>>>> 2. Why, if it is a Generator's responsibility to generate items > >> >>>>>> subsequent to the lower endpoint, is the step part of the range > at > >> >>>>>> all? Based on [1], which definition of "range" are we attempting > to > >> >>>>>> represent? > >> >>>>> > >> >>>>> > >> >>>>> In google guava and java-yield a range is a generator, as it was > in > >> >>>>> [functor] too (this patch removes the old IntegerRange, a > generator > >> of > >> >>>>> Integers). > >> >>>>> > >> >>>>> [functor] has generators that don't require steps (GenerateWhile, > >> >>>>> WhileGenerate, UntilGenerate, etc). I think random generators > >> wouldn't > >> >>>>> use > >> >>>>> steps too (e.g.: RandomIntegerGenerator, USPhoneNumberGenerator, > >> >>>>> UUIDGenerator, PrimeNumberGenerator). > >> >>>>> > >> >>>>> The initial idea of the Range interface, was to have similar > >> behavior as > >> >>>>> commons-lang's Range [1], plus being able to define steps and have > >> the > >> >>>>> actual process (the yield) being executed by an external agent, a > >> >>>>> generator. > >> >>>>> In the end, I think the of the Range in my patch would be more > like > >> an > >> >>>>> Interval [2]?. > >> >>>>> > >> >>>>> > >> >>>>>> The current code seems to implement definition 2 and > >> >>>>>> *part* of definition 3, deferring the rest to a corresponding > >> >>>>>> Generator. > >> >>>>> > >> >>>>> > >> >>>>> I couldn't have said it better :-) > >> >>>>> > >> >>>>> > >> >>>>>> Settling the question of whether [functor]'s Range is a > >> >>>>>> "2-range" or also a "3-range" would seem to dictate our action: > do > >> we > >> >>>>>> move the step to the generator, or do we make Range calculate > each > >> >>>>>> item (in which case would it be simpler for Range to implement > >> >>>>>> Generator)? > >> >>>>> > >> >>>>> > >> >>>>> After reading your considerations, I now think that it would be > >> better to > >> >>>>> maintain the current approach (Range implements a Generator) and > try > >> to > >> >>>>> implement generators for double, float and character using the > actual > >> >>>>> interfaces and try to use steps. What do you think? > >> >>>> > >> >>>> > >> >>>> Would there be a type of Range that could not be turned into a > >> >>>> Generator given a compatible Step parameter? If not, we could > define: > >> >>>> > >> >>>> interface Range<T, S> { > >> >>>> ... > >> >>>> Generator<T> toGenerator(S step); > >> >>>> } > >> >>>> > >> >>>> This way, Range itself does not contain a step, but still maintains > >> >>>> control over how a step is used to create a generator. > >> >>>> > >> >>>>> > >> >>>>> Do you think we should keep the naming standard > >> IntegerRange/LongRange, > >> >>>>> or > >> >>>>> change them to IntegerGenerator/LongGenerator? > >> >>>> > >> >>>> > >> >>>> Either way, I like the notion that a Range is its own type that > just > >> >>>> *happens* to either provide access to, or an implementation of, > >> >>>> Generator. > >> >>>> > >> >>>> br, > >> >>>> Matt > >> >>>> > >> >>>>> > >> >>>>> Thank you for reviewing my patch and for the interesting > questions! > >> I'm > >> >>>>> no > >> >>>>> FP expert either, feel free to suggest different ideas, no hard > >> feelings > >> >>>>> :) > >> >>>>> > >> >>>>> [1] > >> >>>>> > >> >>>>> > >> > http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/Range.java?view=markup > >> >>>>> [2] http://en.wikipedia.org/wiki/Interval_(mathematics) > >> >>>>> > >> >>>>> Bruno P. Kinoshita > >> >>>>> http://www.kinoshita.eti.br > >> >>>>> http://www.tupilabs.com > >> >>>>> > >> >>>>> > >> >>>>> On 06/05/2012 12:08 PM, Matt Benson wrote: > >> >>>>>> > >> >>>>>> > >> >>>>>> Hi, Bruno! > >> >>>>>> > >> >>>>>> I have some questions: > >> >>>>>> > >> >>>>>> 1. Why are a Range's type and step-type potentially different > >> >>>>>> (different type variables, etc.)? > >> >>>>>> 2. Why, if it is a Generator's responsibility to generate items > >> >>>>>> subsequent to the lower endpoint, is the step part of the range > at > >> >>>>>> all? Based on [1], which definition of "range" are we > attempting to > >> >>>>>> represent? The current code seems to implement definition 2 and > >> >>>>>> *part* of definition 3, deferring the rest to a corresponding > >> >>>>>> Generator. Settling the question of whether [functor]'s Range > is a > >> >>>>>> "2-range" or also a "3-range" would seem to dictate our action: > do > >> we > >> >>>>>> move the step to the generator, or do we make Range calculate > each > >> >>>>>> item (in which case would it be simpler for Range to implement > >> >>>>>> Generator)? > >> >>>>>> > >> >>>>>> I am by no means an FP or any other type of expert, so feel free > to > >> >>>>>> show me why I'm wrong on a given point! > >> >>>>>> > >> >>>>>> br, > >> >>>>>> Matt > >> >>>>>> > >> >>>>>> [1] http://en.wikipedia.org/wiki/Range_(computer_science) > >> >>>>>> > >> >>>>>> On Mon, Jun 4, 2012 at 11:59 PM, Bruno P. Kinoshita > >> >>>>>> <brunodepau...@yahoo.com.br> wrote: > >> >>>>>>> > >> >>>>>>> > >> >>>>>>> Hi all, > >> >>>>>>> > >> >>>>>>> I've finished a patch for FUNCTOR-14, regarding the Generators > API > >> in > >> >>>>>>> [functor]. I'd like to hear what others think about what was > done > >> >>>>>>> before > >> >>>>>>> attaching the patch to JIRA: > >> >>>>>>> > >> >>>>>>> - Didn't change the Generator interface. Although I commented in > >> the > >> >>>>>>> issue about removing the stop() and isStopped() methods and > moving > >> to a > >> >>>>>>> different interface, it would require a major refactoring, as > many > >> >>>>>>> other > >> >>>>>>> generators are built upon this idea. > >> >>>>>>> > >> >>>>>>> - Created IntegerGenerator, LongGenerator, FloatGenerator, > >> >>>>>>> DoubleGenerator and CharacterGenerator. Didn't implement a > >> >>>>>>> DateGenerator as > >> >>>>>>> it would require more time and a discussion on how to use days, > >> months, > >> >>>>>>> years, days of week, etc. > >> >>>>>>> > >> >>>>>>> - Introduced Ranges, with the following initial ranges: > >> IntegerRange, > >> >>>>>>> LongRange, FloatRange, DoubleRange and CharacterRange. This API > is > >> >>>>>>> quite > >> >>>>>>> similar to other existing APIs, with the difference that you can > >> >>>>>>> specify the > >> >>>>>>> step (like ranges in Matlab) > >> >>>>>>> > >> >>>>>>> - The generators that use numbers (there are many other > generators, > >> >>>>>>> like > >> >>>>>>> GenerateWhile, GenerateUntil, etc) use ranges to create the > >> series. The > >> >>>>>>> objects are created only when the generator is executed, > calling a > >> >>>>>>> procedure. Like in python, but instead of retrieving the value > >> with a > >> >>>>>>> 'yield' statement, we give a procedure to be executed using the > >> value > >> >>>>>>> created. > >> >>>>>>> > >> >>>>>>> - Included tests to cover the changes. > >> >>>>>>> > >> >>>>>>> - Updated web site examples. > >> >>>>>>> > >> >>>>>>> All the tests passed, no checkstyle/pmd/findbugs errors. The > >> character > >> >>>>>>> range/generator is a very simple, and there are some operations > >> with > >> >>>>>>> double/float in the ranges and generators. I keep my code > mirrored > >> in > >> >>>>>>> github > >> >>>>>>> too, in case someone prefers reading it there > >> >>>>>>> https://github.com/kinow/functor. > >> >>>>>>> > >> >>>>>>> Let me know what you think about it :-) > >> >>>>>>> > >> >>>>>>> Thank you in advance! > >> >>>>>>> > >> >>>>>>> Bruno P. Kinoshita > >> >>>>>>> http://kinoshita.eti.br > >> >>>>>>> http://tupilabs.com > >> >>>>>>> > >> >>>>>>> > >> >>>>>>> > >> --------------------------------------------------------------------- > >> >>>>>>> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org > >> >>>>>>> For additional commands, e-mail: dev-h...@commons.apache.org > >> >>>>>> > >> >>>>>> > >> >>>>>> > >> >>>>>> > >> --------------------------------------------------------------------- > >> >>>>>> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org > >> >>>>>> For additional commands, e-mail: dev-h...@commons.apache.org > >> >>>>>> > >> >>>>> > >> >>>> > >> >>>> > --------------------------------------------------------------------- > >> >>>> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org > >> >>>> For additional commands, e-mail: dev-h...@commons.apache.org > >> >>>> > >> >>> > >> >> > >> >>--------------------------------------------------------------------- > >> >>To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org > >> >>For additional commands, e-mail: dev-h...@commons.apache.org > >> >> > >> >> > >> >> > >> >> > >> > > >> > --------------------------------------------------------------------- > >> > To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org > >> > For additional commands, e-mail: dev-h...@commons.apache.org > >> > > >> > >> --------------------------------------------------------------------- > >> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org > >> For additional commands, e-mail: dev-h...@commons.apache.org > >> > >> >