Hi Lex, thanks for your feedback. I think you must have missed a bit of the discussion, and are lacking some of the context, which needs filling in a little both to remove the sting present it is true in the discussion, but also to allow us to see what the discussion has accomplished and why it was a fruitful one for the scala-dev list.
What brought me here was that I was asked by Reto to verify on the scala-dev
mailing list that
import ez1._
b_("reto") -- FOAF.homepage --> "http://bblfish.net/".uri
import ez2._
b_("hjs") -- FOAF.homepage --> "http://bblfish.net/".uri
was an anti-pattern [1]. We are two to be developing enthusiastically with
Scala in Clerezza, so the problem is that if we have a disagreement of this
kind it is very difficult to resolve it there. It is true that I found it so
evidently to be a problem, that I thought that this was a bit disingenuous to
ask me to come to this list initially.
Anyway, so I came to the list, to ask the question, and the answer was very
clear: I don't think there was any support for the proposed way of doing things
from anyone here.
But was that therefore supporting some supposed way I had of doing things? Was
this an issue of my patch versus his patch?
No, very clearly not. The solution I had developed a while ago [2] was clearly
over-engineered, and I am not suggesting to go back to that. The discussion on
this list helped me look very carefully at Reto's arguments for his solution
above. And you will see me taking those very seriously in quite a few of the
e-mails to this list [3]. In fact what I took out of this was exactly why my
original solution was problematic. But as I will show, that part of the
solution is still present within the code that Reto proposed.
The problem with "my" original code, is to put it as simply as possible is that
you need the context to cover the whole of the DSL. Ie. in my original
solutions one would write
( graph.node a FOAF.Person
-- name --> "Lex"
-- knows --> ( graph.bnode("hjs") -- name --> "Henry Story")
-- knows --> ( reto -- knows -- graph.bnode("hjs"))
)
Notice that following the first -- knows --> arrow one MUST have a reference
back to the original graph object
with the code graph.bnode("hjs") if one wants that to be used again in the last
statement of the DSL above -
the one where it is claimed that Reto knows the same person you do.
It is in order to improve this that Reto rewrote the code I had written and
came up with the solution I have claimed
is an anti-pattern. (It relies much too strongly on implicits.) Reto solved the
above very cleverly by using subclassing
and an import statement [4] it works miracles so long as you have only one
graph. What you do is you import an implicit conversion from bnodes or Uris to
a GraphNode backed by a instance of a Graph. This then allows you to write the
above as
val graph = new EzMGraph()
import graph._
( node a FOAF.Person
-- name --> "Lex"
-- knows --> ( bnode("hjs") -- name --> "Henry Story")
-- knows --> ( reto -- knows -- bnode("hjs"))
)
Which as you will see removes all the references back to the original graph in
the DSL. ( No more graph.xxx )
How this works I explained in detail in the bug report CLEREZZA-603
So I think I explained on this list very clearly why Reto's solution was so
attractive for him, and why to that extent it was an improvement on the code I
had written, and indeed this is why I did not oppose it being introduced into
the Clerezza subversion repository.
But of course the problem is that it makes use of this anti pattern that we are
discussing here, and that is visible when you start using multiple graphs
together, at which point that notation becomes very confusing. (Now it took me
some time to see spot this myself, btw.)
Reto claims that we never need more than one graph - and I fundamentally
disagree. A very large part of the work I need to do in creating distributed
social networks, is going to be writing, comparing and playing with multiple
graphs. In fact if the semantic web brings one thing to us it brings this
ability to work with multiple points of view, without needing to assert anyone
as the only truth [5]. So this is a very important tool that I wish to use, and
I believe it will be more and more important as Clerezza builds apps.
So accepting the anti-pattern - or whatever you wish to call it - and
accepting that Reto's solution contains some interesting insights, you will
notice that I was not banging on my chest - as you say - trying to get my own
old solution back in, but rather I sought out a new solution that could satisfy
both the point that Reto had made without requiring the anti-pattern. This is
the solution I developed in the part of this thread entitled "taking context
seriously", and which I have been developing on the github branch of clerezza I
am working on at https://github.com/bblfish/clerezza/ in the zz-issues branch,
and soon the bblfish branch. How does this end up looking?
Well with the proposed changes [6] one just makes the context clear by writing
new context {(
node a FOAF.Person
-- name --> "Lex"
-- knows --> ( bnode("hjs") -- name --> "Henry Story")
-- knows --> ( reto -- knows -- bnode("hjs"))
)}
Here the DSL is protected as an inner class by the context, so that one never
moves out of one graph into another by mistake, which would have many unclear
consequences. I have been using this on my github branch, and it does work very
nicely on the whole. It also avoids subclassing a graph object, which is
dangerous as that tends to give code more access to the internals of how a
graph works that is relevant to the coder writing such triples.
Henry
[1] Reto wrote on the clerezza mailing list
"I think it's important to identify anti-pattern. Post a link here if you
document the anti-pattern you think you've discovered on the scala mailing
list"
[2] see the older version 1141579 of EzMGraph
[3] My reply dated 21 July 2011 to Reto's 5 questions among others
[4] version 1144633 of EzMGraph and version 1144633 of RichGraphNode
[5] See my mail on blogs.sun.com Beatnik: change your mind
[6] see the new context class I proposed on my branch in github
Social Web Architect
http://bblfish.net/
On 24 Jul 2011, at 06:58, Lex wrote on scala-dev:
> Does this really belong on the scala list?
yes
> So your patch was not accepted, not a big deal. I
This was not about patches being accepted or not.
> f you feel a strong disagreement with the
> author, just fork the project.
I have a branch on github, where I have been developing this.
> If you are unwilling to maintain the fork, then think about how much effort
> it takes to start a project and
> keep it going. Maybe that will make you more respectful and
> professional about the subject.
It is a lot of work, that is why I am trying to make sure that Clerezza does
the right thing.
I would rather the right thing were done without my having to discuss it, as I
have a lot of more
urgent things to do. But we are breaking new ground here, and we are
discovering the power of
Scala - which one has to be careful not to abuse.
> Banging on the chest and pointing to your way of doing things as
> superior, while calling the original "anti-pattern" wont get you
> anywhere.
I don't think I pointed to my way of doing things as being better anywhere on
this thread.
I just asked whether or not the solution was an anti-pattern. It is important
to agree on that,
because otherwise there is no reason to find a better solution.
This discussion helped us find a solution, so I think it is all to the good.
smime.p7s
Description: S/MIME cryptographic signature
