But to GET the UUID of a link, we either need to inspect the link manually, or we need a way of describing the link by its characteristics.
Agreed we need to get the UUID somehow… UUIDs alone would not give enough power to be worth the effort. There is a third option to the ones you describe, namely combining it with the index access you described in your first example syntax (using []). I tried to suggest that in the third paragraph of my earlier, longer response. Unless I’m missing something, index access would allow us to iterate over the links on a note, find the one we want by inspecting its attributes, then access its UUID–all programmatically.
So I see two use cases at least:
- Changing specific links in a note using a stamp that iterates over the links, modifying those that match a condition. This need not require UUIDs, but would require access operators.
- Making changes on an ongoing basis through agents, rules, etc. These might be made more efficient if the specific links of interest can be stored somewhere for re-use. One could also produce chained logic where an agent populates a list of links, and some other agent, etc. works on the list. These seem to need both UUIDs and access operators in many cases.
@PaulWalters: I’m not sure that link comments are the best example here.
But let’s suppose that you have a link from there word “Frost” in the note Poetry, and you’d like it to link to the most recently posted Frost poem on your weblog. That’s not currently possible, but it could be.
Links usually have short descriptive titles reflecting the intent or purpose of the link e.g. answers the question “What is the connection ?”. Typical examples provided in the default TB notebook are agree, clarify, disagree, example, response etc…
I may have missed something but I believe there is no direct way of answering the question of why and associate it with each link. As an example I could have a set of notes about People say Person1, Person2 and Person3 with details on contacts, their background etc… I can also have a set of notes about new ideas for a satellite e.g Idea1, Idea2 and Idea3. Now Person1 agrees with Idea1 and Idea2. Person2 agrees with Idea1 but disagrees with Idea2. Links to the rescue. I use agree and disagree to connect their responses to each of my ideas. So far so good.
However this does not tell me why they agree or disagree. I can of course create an intermediate note so that
Person1 -> Intermediate Note on why he agrees -> Idea1
Person2 -> Intermediate Note on why she disagrees -> Idea2
and so on. Visually this might be ok in a Map view however the direct link between Person and Idea is now lost and I have to go back two levels of links to find the Person. There may be other approached.
I would prefer to store this information in the link itself as a comment so that it can be consulted in the context of the link.
A feature that exists now.
That’s why we recently added link comments. The issue at hand is, can the action language be extended so that it can access and modify link comments? This turns out to be more interesting than I’d expected.
If many properties of the link are accessible then it might be possible to expose other attributes of the link, even those that are read-only. E.g. the source text span for a text-based link could then be used for output through a template.
I know comments are available. Access to the link comment through action language would help filter links with a certain keyword within the comments or compile a summary of all comments for links of a certain type etc…
OK: I’ve got a preliminary design that might be livable.
theLink (predicate).facet
theLink (target,predicate).facet
Predicate is any boolean expression. When evaluated, the current link is bound to the link being tested. For example:
theLink(destination==“/data/example”).comment
Returns the link comment for the link from this note to /data/example. If no such link exists, the expression returns the empty string. If several links exist, the expression returns the result for one of those links.
Facet is one of: id, source, destination, linkType, comment, color, and so forth. The facet “id” is the number of the link in the list of outbound links of its source.
Reading properties of links in this way should be moderately straightforward.
$MyString=theLink(source==this).comment
Writing properties of links in this way will be a moderately-sized bear, but can be done.
Either way, performance in large documents might be a problem since we might need to examine every link. For example:
Agent Name: Notes With Links Needing Further Contemplation
Query: theLink(comment.contains(“Fix Me”)).source==$Path
That agent needs to scan every link in the document and every note in the document, and it performs a regular expression match on each link comment and a string match for each note. My sense is that this will be fine for most documents but it might not be great in documents with many thousands of notes and numerous links. And those might be the very documents for which the feature might be useful.
Better ideas welcome!
I read ‘predicate’ as meaning—form an ordinary user perspective—a query. I think this is pertinent as the more complex the query, the more work the app has to do and this can scale badly…
My immediate reaction. I’d urge great caution testing this at anything other than scale or it simply opens a desire for app performance that may prove very difficult to deliver on. Not least, as many like to “let the computer do the work” the queries (see above) will likely be regex like .contains()
. The load this creates may not be clear to the user as it’s the app’s problem to ‘just’ resolve.
I’d wager that won’t be what users will want or expect, but a list. That said, a list of values too is of little use if not ties to some further contextualising info. this implies an array, something that (look-up lists notwithstanding) isn’t really a central part of action code right now.
I do wonder if we are solving the right problem here. I do see the attraction of the notion of link facets, but I think it helps to unpick the problem, which seems to have too related parts:
- How link ad hoc notes might be used
- How link ad hoc notes might be accessed
I feel we are rushing ahead with the latter without properly diagnosing the former. I sense we have a disconnect between “data I want to note down because a link type assignment is too inflexible” and how free-from that text can really be whilst being as ‘accessible’ is it may seem in minds eye. I feel there is a danger of needing a feature to “show that link or vaguely recall making a few days ago”. Are we users self-disciplined enough in our annotation to write link annotations that can be queried in a usable fashion (i.e. not overly complex or code-heavy).
I’m also unclear on the real use-case. I’d like to see some specimen link annotations and attendant description of how that might expect to be found and used. Having located the right annotation, where is it then seen. Such an annotation is likely to be too big (long) to be read in full in Get Info or Displayed Attributes. They can be read in Browse links or Roadmap (latter only in stand-alone form). So, might one of these UIs be the place to query this? Or, do we need a link-centric report like the old Paths window. All the clever code will be of little help if we can’t make practical use of the output without generating yet another feature request - IOW: measure twice, cut once.
A related fact is to what real extent this is personal style vs a real limitation in link types. this is why seeing some real world annotations would useful (I ask, in no small part as I don’t use them other than for testing). Knowing how many annotation facets are being captured entirely within the ad hoc text annotation is important. For instance, it might be more useful to make explicit inputs for those facets we are likely to want to query. Or, we may find we are recording information which may as easily be recorded as attribute data in one or both of the source and destination note of the link.
I also wonder if people have really given link types a real test. Is everyone away that the built-in ones are a specimen set. Users can add their own (and delete built-in ones if desired). Again, some specimen free text annotations would help more useful consideration.
I’m not against the idea hear, I’m just pragmatic about the danger of addressing the wrong problem
Another proposal: link rules.
A link rule is an action that runs periodically. Link rules may access the facets of the link just as note rules access attributes of the note; link facets use % where attributes use $. Link rules may also access note attributes. For example:
$MyString(%source) = %comment
or
%comment = "Linking "+$Name(%source)
This would be another way to move data from links to notes, and from notes to links.
Thank you Mark for sharing a possible design. It looks pretty good from what I can see.
One concern I have is whether the id facet is not volatile and therefore less useful for retaining a persistent reference to the link. If id is a cardinal index into the links on a note, i.e. the first link is id=1, the second id=2, then any time a link is removed the indices will change the links to which each refers. So if I record (programmatically) that a value is in the fourth link, and the third link is deleted, my use of the 4th index will subsequently give me the wrong link or a nil link. That seems to me a significant limitation.
There is a workaround, viz. I can store any unique identifier in a comment and then find the link using it. The effect of that is to increase the kind of regex searching on comments about which you were concerned.
I suppose a workaround to this worry would be to add an integer (or string?) facet to links, call it “reference”, and allow people to put the value of their choice in it. (The sense of it is the way invoices often come with “our reference” or “your reference” fields, in which typically one of these fields is useless to one of the parties.)
About your rules proposal, that also seems good. Though I’m always wary of introducing new syntax (’%’) rather than just more functions.
Thank you Mark for your detailed expressions of caution and concern. They all seem to me prudent.
You ask whether we understand “How link ad hoc notes might be used”?
The first answer I would give is the one you give to most people who ask how to use Tinderbox. It depends on what you want to do and you may not always realise what you want to do until you are some way into the thick of doing it.
What makes me think it would be useful generally is that links are an aspect of the semantic information stored in a collection of inter-linked TB notes. Right now, the range of that semantic information that can be programmatically accessed is restricted to: that two notes are linked, the directionality of a link, to which category (viz. link type) the link belongs. This, I believe, implies that other attributes of the link that the author takes as meaningful are not programmatically accessible, for example the rationale for the link; fine points of detail about the link; or any attributes that might sub-categorise or alternatively categorise the link. These attributes can be stored in the comment field.
I was not sure what you were trying to express by your use of ‘ad hoc’ in your question. I have taken it you mean unstructured by contrast with the kind of structure that “proper” attributes get you. If so, that is true, but it does not make it unusable. If comments were programmatically manipulated, then it might be possible to enforce a uniformity that made programmatic access less costly. Another option, if a persistent reference to the link can be made, would be to use a “shadow” note’s attributes for the link, i.e. a note that shadows the link and lends its attributes as a structured augmentation of the link’s content.
You ask for a general use case. Suppose links can have by the expedients above de facto two link-types. It would then be possible to enquire as to the significance of notes being linked by the four sub-types this pair of types imply (namely, for types A & B, we have subtypes AB, BA, A¬B,B¬A, maybe exotic variants too such as ¬A¬B and ¬(AB).). So for some link indicating that Note1 “moves” Note2, we can imagine sub-types “reflex” and “action”. Now we can describe about reflex actions, actions that are not reflexes, reflexes that are not actions (e.g. gagging), and movements that are neither. Now we have more semantic information in our TB document. Who knows what we might do with that information in relation to other information we’ve already got, the limits are only the limits of logic and programmatic access.
You might say that it is possible to encode that information now using multiple links or attributes stored on the originating or destination sides. That’s true, but multiple links will not scale, I think, just consider the combinatorial increase with three or four link sub-types. More generally, it seems best to attach information to the entity in which it most closely inheres. So if I use a link of type “is an aspect of” to describe the relation between two notes each of which describes an entity, I may want to expand on the nature of the relation, why I think it is so, and so on. The same thing is true, more prosaically, with saying that there is a dependence relation between this workflow and such and such resource.
I have tried to describe the general need a few times in posts. I can give more if you are still unclear or remain sceptical. In maps I have seen posted by Beck Tench and Dominique Renaud, I have had the sense that they are using Tinderbox to capture relations between notes in ways similar to what I have described, within the limits of Tinderbox.
My guess, not having been around Tinderbox as long as many others, is that the link-type of links (valued especially for the ability for this to be a visible label in maps) is not quite fit for purpose. I believe it was originally added to facilitate link-types in HTML export, but you will know better than I do. People are overloading it to store content/information/significance unrelated to HTML export. The comment feature of links seems a further scratching of this itch.
I gave a user case above in terms of links connecting persons and ideas and comments providing more details on the agree/disagree context (eg. additional details on the link). @entropydave puts it more eloquently - you can use comments to add flexible subcategories or additional keywords to the link which become useful when these can be accessed programmatically.
An example might be to express the strength of the agreement e.g. strongly agree or partially disagree, stored in the comment without the need to create a new link category for each. If all you are interested is the binary question which person agrees with with idea the link itself is sufficient. If on the other hand you want to delve deeper into the details of a strong or weaker agreement/disagreement the comments and access to them would become very useful.
I’m not an expert in implementatio so cannot comment much. I like the fact that % allows for a visible distinction between attributes (notes) and facets (from graph theory I would call them vertices).
I’ll open by noting that my questions are not opposition [sic] but rather, clarification. Causing the app’s developer to expend effort solving the wrong problem affects all users. This is what drives my questions: what problem are the really solving.
You are right to note that I often suggest “It’s depends”. However, I’m not sure that’s the case here. I was seeking a non-conceptual use case for the idea raised. I too think that links—or the rationale for links—is useful. I have also learned that asking our computer to guess for us can be at best confusing and at worst uninformative.
It seems useful to clarify that types of links in Tinderbox (there are only three: basic, text† and web)
†. Due to exposure to other apps, there is a misunderstanding for some that ‘zip links’ are a type of link. This is simply not true. All zip links are text links, they are just text links created via the keyboard-centric ziplink method. I can’t overstate that differentiation as it’s caused some confusion.
Types of Tinderbox ;links are different from Tinderbox link link types. This is an important distinction as your posts appear to misunderstand this.
Tinderbox uses the richer, pre-Web, concept of links whereby they are stored in linkbase discrete from the notes (whereas early Web tech limitations, resulted in links being embedded in notes).
A Tinderbox note can link to another Tinderbox note once or multiple times. Each discrete link can have zero or 1 links types (actually notes with no link type have the link type “*untitled”). Though Tinderbox documents instantiate with a selection of pre-added link types, their use is not a requirement. Not only can you delete built-in link types, but you can add your own.
This means that to apply multiple link types [sic] to the relationship between two note means either adding one ling per link type or storing the relationship in attributes in one/both notes_.
What lay behind my question is is the use case doing inferential work across the graph or a case of “what was that piece of paper I had in my mind yesterday”, or—lest that seem (unintentionally) binary, something else?
I get that this is conceptually useful, but I go back to a use case. What issue (with example data supplied) does this solve that can’t be done currently. That last isn’t meant confrontationally, but rather by way of additional explanation of what my previous post was asking for.
I was unable to see how the misunderstandings you impute are germane to the points I was making. While it is helpful to have further clarifications, I did not see the application of the clarifications to the points I was making. If you think that a clarification you’ve made calls into question the ideas I was trying to set out, please say.
To be clear, anything I have described can be done currently with multiple links, multiple link types (by which I mean the user-adjustable types where at most one can be assigned to links), and perhaps some amount of manual intervention. What is in question is whether this might be done more easily or with more automation.
I’ll only try once more to convince you that there are such use cases. I do not have data [sic] I’m willing to share. It will not be down to the two of us to decide the matter in any case.
We can take Malcolm Davidson’s example above. Suppose a link represents a connection that is a scalar value quantised into five values (agree+, agree, neither, disagree, disagree+). This can be represented with five link types, each having the name of the value. If one has many species of such connection to represent, the link types multiply quickly. One might wish to do with the information retained in the links what one does with the information in any set of notes, e.g. create queries that collect notes (or links); identify using some heuristic and automatically alter notes (or links); create new information by aggregating or deriving information from the existing information including that in links. It is not easy to do this now.
Much of my work in Tinderbox involves making conceptual maps. The notes store extracts of texts or references to texts. Notes typically represent concepts or entities. The relationships are many and subtle. The visible “labels” on links (which mirror link type) are a helpful affordance for visualising relations, but I often feel torn between setting a link type that is most informative and a label that is best suited to visualisation. That is one problem that I might be able to ameliorate by deriving other representations of relations programmatically (e.g. for all links, disregarding labels, collect all those whose relation is strongly supervenient and non-concrete, putting sources in one list and destinations in another). It is very important that I also note detailed comments on the link itself. I would like to find, sometimes, say, all the links in which Heidegger is mentioned in the comments.
In fact, I often try to represent the same concepts using different relationships, sometimes because I am trying to work out the extent of the difference between two totalising conceptions. You may recall in a post a couple of years back my interest in so-called “replicant” notes, which was to do this. While I bodged something together with populations of aliases that were automatically refreshed from a master source population, it proved too brittle to be effective. “Overloading relationships” through richer links is another route toward this kind of work.
Thank you for your questions. By training and temperament, I respond to questions with answers and arguments in favour of the answers. My arguments are not meant as opposition.
May I suggest this thread is running its course? I believe @mdavidson and @entropydave have explained their needs. There may be more than one way to achieve the needs, but I believe there is a request on the table that Eastgate make it possible to, in my words:
(a) set a “label” for an edge on a map, and
(b) make it possible to set and retrieve “label” and the “comment” assigned to that edge through action code.
Eastgate made solution suggestions here and here
Theories aside, is this the problem statement?