[Neo] First external committer?

Viktor Klang viktor.klang at gmail.com
Tue Nov 20 23:40:42 CET 2007


On Nov 20, 2007 11:29 PM, Björn Granvik <bjorn.granvik at jayway.se> wrote:

> > writing TraverseSpecification.by(Order.BREADTH_FIRST).by(
> Order.BREADTH_FIRST)
> > gives me a compiler warning saying that static methods should be
> accessed in a
> > static way.
>
> I understood that when I read it was static (I had to reread to:-)
> This means you have a two-level approach - a static "by" with a mix of
> "add/set" methods?


Yes, that's the current take on it. :)


>
> This might be nice but maybe not very "fluent".


Hmmm, I guess there's always some room to improve... something like this
could work better lexically...

for(Node node : root.traverse(byBreadth.include(MyRelTypes.DADDY,
Orientation.INCOMING
).returnAll(myReturnEval).randomizeWith(myRandEval).until(END_OF_NETWORK))
 foo(node);


Looks kind of sexy, really.



>
>
> To me your strongest point is the separation.


Yeah, the separation is the selling point. To be able to reuse, to name and
to pass the specifications as arguments gives:

1) a clear separation of concerns
2) clear code ( traverse(allStudents) is more clear than traverse(
Order.BREADTH_FIRST..........))
3) encourages code reuse
4) makes it easier to refactor


Cheerio!

-Viktor


>
>
> /Björn
>
>
>
> Viktor Klang wrote:
> > On Nov 20, 2007 11:12 PM, Björn Granvik <bjorn.granvik at jayway.se> wrote:
> >
> >
> >> Hi Viktor,
> >>
> >> Ok, now I understand better what you're getting at.
> >> I like the division of labor between traverse and specification. It
> >> makes for some sort of declarative class for the traversal.
> >> And the verbose version is   ...verbose :-)
> >>
> >
> >
> > Ah, I re-read your previous e-mail (my eyes are tired :( ),
> > writing TraverseSpecification.by(Order.BREADTH_FIRST).by(
> Order.BREADTH_FIRST)
> > gives
> > me a compiler warning saying that static methods should be accessed in a
> > static way.
> >
> > Regarding ReturnableEvaluator the current version of
> TraverseSpecification
> > behaves just as if you'd set it to *null
> > *when calling the "manual"-version of traverse(), but if people'd want
> it I
> > guess it'd be a matter of 2 minutes to
> > actually have a default which returns *true* for all nodes.
> >
> >
> >
> >> Btw, ISA and ISE means?
> >>
> >>
> >
> > Ah, sorry, too tired to type in long exception-names. :/
> > IAE = IllegalArgumentException
> > ISE = IllegalStateException
> >
> > Cheers!
> >
> > -Viktor
> >
> >
> >
> >> Cheers,
> >> Björn
> >>
> >>
> >> Viktor Klang wrote:
> >>
> >>> On Nov 20, 2007 10:27 PM, Björn Granvik <bjorn.granvik at jayway.se>
> wrote:
> >>>
> >>>
> >>>
> >>>> Hi Viktor,
> >>>>
> >>>> Fluent interfaces are nice and makes for easy reading. But I have a
> >>>> question or two.
> >>>>
> >>>> What would the following mean?
> >>>>        Traverser t = *root.traverse(by(Order.BREADTH_FIRST)
> >>>>                .add(MyRelTypes.DADDY, Direction.OUTGOING)
> >>>>                .add(MyRelTypes.MOMMY,Direction.INCOMING)*;
> >>>>
> >>>>
> >>> Actually, "by" is just a static method of the class
> >>>
> >> TraverseSpecification
> >>
> >>> (imported statically).
> >>>
> >>> If you want to be extra verbose, the following code is also possible
> to
> >>>
> >> use:
> >>
> >>> TraverseSpecification spec = TraverseSpecification.by(
> >>>
> >> Order.BREADTH_FIRST)
> >>
> >>>                    .setStopEvaluator(StopEvaluator.END_OF_NETWORK)
> >>>                    .setReturnEvaluator(MyReturnEvaluator)
> >>>                    .add(MyRelTypes.DADDY) //equals .add(
> MyRelTypes.DADDY
> >>> ,null)
> >>>                    .add(MyRelTypes.MOMMY,Direction.BOTH)
> >>>                    .setRandomEvaluator(myRandEval);
> >>>
> >>> In TraverseSpecification, there's 3 shorthand set-methods for
> >>>
> >> StopEvaluator,
> >>
> >>> ReturnableEvaluator and RandomEvaluator
> >>>
> >>> for(Node node : root.traverse(spec))
> >>>       foo(node);
> >>>
> >>> TraverseSpecification.by(null) yields an IAE
> >>> Trying to traverse a TraverseSpecification without having added any
> >>> relationships(/Directions) yields an ISE
> >>>
> >>> The good part of it is the no-bullshit/clear syntax + you can re-use
> and
> >>> pass the TraverseSpecifications around as you like.
> >>> (this means you can name them and give your code more clarity and ease
> >>>
> >> to
> >>
> >>> refactor).
> >>>
> >>> Does this answer your questions?
> >>> Do not hesitate to ask for further info!
> >>>
> >>> Cheers
> >>> -Viktor
> >>>
> >>>
> >>>
> >>>
> >>>> Here we have no returnEval. Would that mean a new Exception when
> >>>> traversing or would we default to some kind of standard evaluator?
> >>>> If the latter, does this mean I have to remember more conventions?
> >>>>
> >>>> Or:
> >>>>
> >>>>        Traverser t = *root.traverse(by(Order.BREADTH_FIRST)
> >>>>                .add(MyRelTypes.MOMMY,Direction.INCOMING)
> >>>>                .set(StopEvaluator.END_OF_NETWORK)
> >>>>                .add(MyRelTypes.DADDY, Direction.OUTGOING)
> >>>>                .set(returnEval)
> >>>>                .by(Order.DEPTH_FIRST))*;
> >>>>
> >>>> Notice the double use of "by" and the sort of odd "add-set-add-set".
> >>>> In some cases where fluent interfaces are used (or the "reversed sql"
> >>>> resemblence in Linq) I'm uncertain whether or not there is a
> mechanism
> >>>> to express things in the correct order.
> >>>> For instance; Is there some kind of state that will help me do
> >>>> "code-completion" (for instance the by-method only returns an object
> >>>> that has add or set methods).
> >>>> Is there some kind of state that will recognize the double use of
> "by"
> >>>> in the code above?
> >>>>
> >>>> I didn't mean to sound pessimistic about your idea, it's just that
> I've
> >>>> had these questions running around my head for some of the fluent
> >>>> interface implementations that I've seen.
> >>>>
> >>>> Regards,
> >>>> Björn
> >>>>
> >>>> Ps. I like having patches served, but I'm just a user of Neo so
> someone
> >>>> else would have to give you a proper answer :-)
> >>>>
> >>>>
> >>>>
> >>>> Viktor Klang wrote:
> >>>>
> >>>>
> >>>>> Greetings people!
> >>>>>
> >>>>> How'd you like to be able to write stuff like this?
> >>>>>
> >>>>> ReturnableEvaluator returnEval = new ReturnableEvaluator(){
> >>>>>             @Override
> >>>>>             public boolean isReturnableNode(TraversalPosition
> >>>>>
> >>>>>
> >>>> currentPos) {
> >>>>
> >>>>
> >>>>>                 return (currentPos.currentNode
> ().hasProperty("name"));
> >>>>>             }
> >>>>>         };
> >>>>>
> >>>>>         Traverser t = *root.traverse(by(Order.BREADTH_FIRST)
> >>>>>                 .add(MyRelTypes.DADDY, Direction.OUTGOING)
> >>>>>                 .add(MyRelTypes.MOMMY,Direction.INCOMING)
> >>>>>                 .set(StopEvaluator.END_OF_NETWORK)
> >>>>>                 .set(returnEval))*;
> >>>>>
> >>>>>         for(Node node : t)
> >>>>>            doFunStuffWith(node);
> >>>>>
> >>>>> Or even:
> >>>>>
> >>>>> TraverseSpecification spec = *by(Order.BREADTH_FIRST)
> >>>>>                 .add(MyRelTypes.DADDY, Direction.OUTGOING)
> >>>>>                 .add(MyRelTypes.MOMMY,Direction.INCOMING)
> >>>>>                 .set(StopEvaluator.END_OF_NETWORK)
> >>>>>                 .set(returnEval);
> >>>>>
> >>>>> *for(Node node : *someNode.traverse(spec)*)
> >>>>>       doFunStuffWith(node);*
> >>>>> *
> >>>>> for(Node node : *someOtherNode.traverse(spec)*)
> >>>>>       doFunStuffWith(node);*
> >>>>>
> >>>>> *Interested?
> >>>>> Code is already written and I've played with it a bit.
> >>>>> How do you like your patches served? :)
> >>>>>
> >>>>> Best regards
> >>>>> -Viktor*
> >>>>>
> >>>>> **
> >>>>>
> >>>>> *
> >>>>> _______________________________________________
> >>>>> Neo mailing list
> >>>>> User at lists.neo4j.org
> >>>>> http://lists.neo4j.org/mailman/listinfo/user
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>> _______________________________________________
> >>>> Neo mailing list
> >>>> User at lists.neo4j.org
> >>>> http://lists.neo4j.org/mailman/listinfo/user
> >>>>
> >>>>
> >>>>
> >>> _______________________________________________
> >>> Neo mailing list
> >>> User at lists.neo4j.org
> >>> http://lists.neo4j.org/mailman/listinfo/user
> >>>
> >>>
> >>>
> >> _______________________________________________
> >> Neo mailing list
> >> User at lists.neo4j.org
> >> http://lists.neo4j.org/mailman/listinfo/user
> >>
> >>
> > _______________________________________________
> > Neo mailing list
> > User at lists.neo4j.org
> > http://lists.neo4j.org/mailman/listinfo/user
> >
> >
> _______________________________________________
> Neo mailing list
> User at lists.neo4j.org
> http://lists.neo4j.org/mailman/listinfo/user
>


More information about the User mailing list