The problem with the code below is that once you've used the Person.getFriends(minAge)-method once, the friends-expansion will have that filter added to it forever (if it's mutable), and that means that you will never be able to get the younger friends of that person.
However, reusing an expansion might be so uncommon that it's not even worth bothering with. But if so, it will almost always be used "fluent-style", and the use case for being able to mutate it disappears. Ergo, let's keep it immutable, since it enables more use cases. -t On Wed, Jun 23, 2010 at 8:47 PM, Craig Taverner <cr...@amanzi.com> wrote: > Mutable objects have their issues, and yet this is a common and popular > paradigm in DSL design. I guess however the point with a DSL is that it is > so simple and limited that it compensates for the potential risks. Similar > to the dynamic versus static language argument. > > Now there are ways to reduce the risk. If I remember correctly, one pattern > commonly used in the DSL book was to remain strict with model objects, but > slack on model builder objects. In this case the Node and Person objects > are > model objects, and we would put the fancy DSL stuff into a separate class, > not as a static method of the Person class. This can help conceptually > separate the solid and reliable model from the convenient DSL. > > On a separate note, perhaps I'm just being slow, but I don't see the > aspects > of the code below that would be disabled by a mutable builder? Is it the > final on 'friends'? That keyword should not stop modifying the contents of > friends. ANd you code below does not expose the friends instance to outside > influences, so no-one can modify it anyway. What am I missing. > > On Wed, Jun 23, 2010 at 8:15 PM, Tobias Ivarsson < > tobias.ivars...@neotechnology.com> wrote: > > > Because mutable objects are evil. It would for example make it impossible > > to > > write classes like this: > > > > class Person { > > private final Expansion<Node> friends; > > Person(Node node) { > > this.friends = node.expand( FRIEND ).nodes(); > > } > > Iterable<Person> getFriends() { > > return persons( friends ); > > } > > Iterable<Person> getFriends( final int minimumAge ) { > > return persons( friends.filterNodes( new Predicate<Node>() { > > public boolean accept(Node friend) { > > return minimumAge >= (Integer)friend.getProperty("age"); > > } > > }) ); > > } > > static Iterable<Person> persons( Iterable<Node> persons ) { > > return IterableWrapper<Person, Node>( persons ) { > > protected Person underlyingObjectToObject( Node person ) { > > return new Person( person ); > > } > > } > > } > > } > > > > This might be an acceptable loss though. This could be a case where it is > > ok > > to reuse the same object and mutate the internal state. It's something to > > think about... > > > > -tobias > > > > On Wed, Jun 23, 2010 at 7:10 PM, Craig Taverner <cr...@amanzi.com> > wrote: > > > > > Why not have includes() return the same instance with internal state > > > changed, then the various call options are equivalent. > > > > > > On Jun 23, 2010 6:41 PM, "Tobias Ivarsson" < > > > tobias.ivars...@neotechnology.com> wrote: > > > > > > On Wed, Jun 23, 2010 at 6:10 PM, Craig Taverner <cr...@amanzi.com> > > wrote: > > > > > > > > (I also noticed that r... > > > I get that feeling as well. Another feeling I get with includes() is > that > > > it > > > might be possible to do the following: > > > > > > > > > Expansion<Relationship> expansion = startNode.expand( KNOWS ); > > > expansion.includes( LIKES ); > > > expansion.includes( LOVES ); > > > for (Node node : expansion.nodes()) { > > > ... > > > } > > > > > > With includes() one gets the feeling that the above would expand LOVES, > > > LIKES and KNOWS relationships, but it will in fact only expand KNOWS > > > relationships. With and() I don't think that mistake would be as > common. > > > > > > Cheers, > > > -- > > > > > > Tobias Ivarsson <tobias.ivars...@neotechnology.com> > > > Hacker, Neo Technology > > > www.neotechnology.com > > > Cel... > > > _______________________________________________ > > > Neo4j mailing list > > > User@lists.neo4j.org > > > https://lists.neo4j.org/mailman/listinfo/user > > > > > > > > > > > -- > > Tobias Ivarsson <tobias.ivars...@neotechnology.com> > > Hacker, Neo Technology > > www.neotechnology.com > > Cellphone: +46 706 534857 > > _______________________________________________ > > Neo4j mailing list > > User@lists.neo4j.org > > https://lists.neo4j.org/mailman/listinfo/user > > > _______________________________________________ > Neo4j mailing list > User@lists.neo4j.org > https://lists.neo4j.org/mailman/listinfo/user > -- Tobias Ivarsson <tobias.ivars...@neotechnology.com> Hacker, Neo Technology www.neotechnology.com Cellphone: +46 706 534857 _______________________________________________ Neo4j mailing list User@lists.neo4j.org https://lists.neo4j.org/mailman/listinfo/user