I guess I would have just added a clear() method to the expansion. But of course I understand that using mutable expansions requires that the user actually understand the implications, which goes against the simplicity of the DSL.
On Thu, Jun 24, 2010 at 12:23 AM, Tobias Ivarsson < tobias.ivars...@neotechnology.com> wrote: > 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 > _______________________________________________ Neo4j mailing list User@lists.neo4j.org https://lists.neo4j.org/mailman/listinfo/user