- From: Sean Mehan <sean@smo.uhi.ac.uk>
- Date: Wed, 13 Aug 2003 11:05:06 +0100
- To: Bob MacGregor <macgregor@ISI.EDU>, Garret Wilson <garret@globalmentor.com>, www-rdf-interest@w3.org
+2 on RDF:List semantics being driven by a logic paradigm, which has dealt with associated concepts and problems for longer than I have been alive, as opposed to being driven by JAVA, which has been around considerably less. regards, sean On Wednesday 13 August 2003 01:39, Bob MacGregor wrote: > Garret, > > It would seem that you were never a Common Lisp > programmer, or the constraints on RDF lists would seem > natural. You apparently are taking it for granted that > operations on lists other than the empty list should be > "destructive". That decision probably deserves some > discussion. > > I wasn't a party to the discussions that lead to inventing > RDF:List semantics, but its likely that the motivation > was based on ability to manipulate lists via logic, rather > than via Java or some other procedural > language. RDF:List semantics is closely aligned with > both Prolog-style and KIF-style lists. As such, its > semantics is probably not open to debate. > > A key question is whether or not an API > for manipulating lists should make it easy to support > both destructive and non-destructive operations. In the > Common Lisp world, list operations frequently occur in > pairs. For example, "append" is non-destructive concatenation > of lists, and "nconc" is its destructive analog. "reverse" is > a non-destructive reversal, and "nreverse" is destructive > reversal. I would prefer seeing the same thing for an RDF API, > unless someone can present a good argument against it. > > Cheers, Bob > > At 05:09 PM 8/12/2003 -0700, Garret Wilson wrote: > >Everyone, > > > >I'm just getting around to implementing support for > >rdf:parseType="Collection", even though I've been using it for a while in > >specifications I've written. > > > >The design of rdf:List looks good in theory, but there are a few details > >that make it a pain to implement---particularly, the way rdf#nil is used: > > > >1. Empty lists cannot be modified. > > > >In the RDF world, it's natural to think that one can always add things to > >a resource. I can specify another dc:creator to a book. I can later add an > >rdfs:label to a resource. Yes, I know that RDF is designed to only be > >aware of one set of static relationships, but in the real world we need to > >modify resources at some time or another. We can modify rdf:Alt, rdf:Bag, > >and rdf:Seq, even if they are empty---we just add one or more resources to > >the collection. > > > >rdf:List is designed so that one cannot add anything to an empty rdf:List, > >because there is only one empty rdf:List, the one named rdf#nil. There are > >an infinite number of non-empty lists, with an infinite number of (usually > >anonymous/blank node) reference URIs, but *none* of those lists can be > >empty, because the empty list has its own static universal reference URI. > >Conversely, the empty list can never be added to without changing its > >reference URI. Put differently, an empty rdf:List cannot be filled---it > >can only be replaced with a filled list. (Compare this to an rdf:List with > >one element---programmatically, one can add more elements by changing the > >rdf:rest property, allowing the list remains the same entity, identified > >by the same reference URI. This is impossible with an empty list.) > > > >2. It is a pain to populate an rdf:List. > > > >Even if we accept the theoretical notion of RDF as a static snapshot of > >relationships, in the real world one has to populate that directed graph > >programmatically---when parsing an RDF+XML document, for instance. With > >the old containers, that was easy: we start with an empty rdf:Alt, > >rdf:Bag, or rdf:Seq and then add elements if and only if they are present. > > > >With rdf:List, this procedure remains the same *only* after we know we > >have one element in a list. Until we have one element in the list, we > >don't know whether to create an anonymous rdf:List and populate it with > >items, or (if there are no items) to create an rdf#nil list (with its > >unique reference URI). This results in very inelegant algorithms: > > > >while(there are child elements) > >{ > > create a new rdf:List > > if(we've already created an rdf:List) > > { > > add the new rdf:List to the old one > > } > > else > > { > > specify that the new list is the "root" list > > save this new list for next time > > } > >} > >if(we have record of finding a "root" list) > > use the "root" list as the property value > > > >In contrast, the old containers allowed very elegant implementations, > >because they didn't distinguish conceptually between empty and filled > >containers: > > > >create new container > >while(there are child elements) > >{ > > add the element to the container > >} > >use the new container as the property value > > > >3. It is impossible to independently insert an element at the beginning of > >an rdf:List. > > > >In object-oriented programming, I'd like to have an object represent an > >rdf:List. In Java, something implementing java.util.List would be great. > >Given any MyList, it's a simple matter to insert something at index i+1 > >with i>0: I just create a new rdf:List with rdf:first representing the > >inserted resource, change rdf:List(i).rdf:rest to point to the new > >rdf:List, and change rdf:List(i+1).rdf:rest to the old value of > >rdf:List(i).rdf:rest. > > > >That's all fine except when i=0. To insert at the front of the list, I > >have to know for which resource property the rdf:List is the property > >value. This is made worse by the fact that several properties (of several > >resources) might have the rdf:List as a property value. This leads to the > >following inconsistency: if resources example.com#book1, > >example.com#book2, and example.com#book3 all have a property of > >listOfComments, I can always add another comment to the end of the list > >without modifying the property value for any of the books, but if I want > >to *insert* a comment at the first of the list, I have to modify the > >property value for each of the books. > > > >In very practical terms, that means if I have the function... > > > >add(RDFList list, RDFResource resourceElement, int index) > > > >...it will work for all values of index except index==0, unless I have > >access to the entire RDF data model, walk the graph, and find all > >resources which have properties for which the list is a property value. > > > >Similarly, going back to problem #1 (above), the function... > > > >add(RDFList list, RDFResource resourceElement, int index) > > > >...cannot work with empty lists! > > > >I understand that the old collection framework had shortcomings (those > >silly indexes, for one thing) and that the new rdf:List framework looks > >nice in a pretty static graph on paper. The specific way that rdf#nil is > >used as an empty list, however, creates very inelegant impelementation > >restrictions. Surely rdf:List could me modified to be better than the old > >collections, yet also usable in real life. > > > >Garret > > ===================================== > Robert MacGregor > Senior Project Leader > macgregor@isi.edu > Phone: 310/448-8423, Fax: 310/822-6592 > Mobile: 310/251-8488 > > USC Information Sciences Institute > 4676 Admiralty Way, Marina del Rey, CA 90292 > =====================================
Received on Thursday, 14 August 2003 03:14:25 UTC