Support issue relations and dependencies (9)
Issue relations may involve blocking issues, duplicate issues, dependent issues, etc. Users should be able to model issue dependencies and preferably receive necessary support for managing dependencies in the UI.
The preferred way of modeling dependencies is by tags. We could introduce #-tags for referring issues (e.g. #24). However, to model the type of relation, we would need more complex tags, such as: #depends24, depends#24, or >#24. None of which is ideal. The best tagging approach remains unclear. Any suggestions or comments are welcome.Submitted by Sander Vermolen on 16 February 2010 at 08:21
Formally, I understand tags as predicates. Every time you tag an issue, you add a fact about that tag to the data base. For instance, using Prolog syntax:
A relation between
nissues can then be modeled as a
n-ary predicate. For instance, the binary
Using a Prolog backend, you can also easily express derived facts, as, for example, transitivity of dependencies or a blocking tag:
depends(A, C) :- depends(A,B), depends(B,C). blocks(A,B) :- depends(B,A).
Following such an encoding, I think the main challenge is to provide a lightweight user interface that fits YellowGrass.
From a user perspective, I agree. From a system perspective, different projects can use different predicates and assign different semantics to these predicates. To avoid the infinite number of predicates problem, there is a meta-predicate tag:
tag : Issue x String
Or its a collection of Issue, String pairs if you like. Now there are three main difficulties in implementing dependencies. The first is how to (nicely) expand the tag predicate to incorporate references to other issues, or issue relations in a more general sense (which could also involve n issues). The second is how to support this in the UI and the third is how to implement the 'business logic' for special tags like depends.
Currently, the implementations of @ and ! tags are rather ad hoc. I would like to diverge from this and make a tagging library of some sort.
I very much like the tag-centric approach and I think tags should be thoroughly used all the way. Hence, how about the following encoding:
Tag = String Untagged = Issue | Tag Tagged = Tag x List(Untagged) | <your primitive tags here>
- Tags are simple strings.
- Issues are untagged values.
- Tags themselves are untagged values, and can thus be tagged.
- Tagged values are a tag and a list of untagged values the tag applies to.
- Primitive tags such as !seba can be added to the
Name x List(Untagged)for the follow-tag (allows me to follow tags and/or issues).
In this encoding, your
tagpredicate corresponds to
tag : Tag x List(Untagged) -> Tagged, which supports issue relations. For instance:
depends(A,B) = tag("depends", [A, B])
I don't think it's a good idea to add more primitive/special tags, except maybe when side-effects are desired. Instead, consider having depends as a normal user-defined tag. Its business-logic, i.e. transitivity, could be simply implemented by users. After all, your users are programmers and the rules I gave in my previous post are pretty much declarative (and standard Prolog syntax).
In the UI, I would show the tag only for the first issue in the list. Hence, for
depends(A, B), issue
Awould be tagged with "depends(B)", whereas this tag is not visible on issue
B. However, since you can derive the tag
blocks(B, A)as shown in my earlier comment,
Bwould be visibly tagged with "blocks(A)". When adding a tag to an issue, you could provide a box for giving the tag's arity, and then provide issue and tag selection boxes/screens/... .
Also, what's the actual technical difference of the "@" and "!" tags (except for the symbol)? Doesn't it generalize to email notifications? Is there any other side-effect currently supported?
Indeed, I agree. Except perhaps that there are no primitive tags. Not modeled anyway. Tags like !... and @... and version are just regular tags that receive special functionality. They are stored the same as any other tag.
From a higher perspective, we apparently want to model function applications at a meta-level. Functions have a name (tag) and some parameters (list of untagged). They could even have types, distinguishing subsets of Untagged. I think that is a nice perspective.
As for implementation, one problem is the list of untagged, which triggers an extra table in the database and will make things rather inefficient, I am afraid. But perhaps, I can implement function logic in a bunch of HQL queries and solve this problem. Another problem is implementing functionality for predicates in the UI, which might be painful. Perhaps solvable through some nice abstractions though.
As for the technical differences between ! and @: ! makes a user follow an issue and @ assigns an issue to a user. They are equivalent wrt notification emails, but different when it comes to UI. Votes are counted, which allows for vote-based issue ordering (e.g. on the project page). Also I have just added an explicit vote count to mark important issues. @-tagged issues are shown on a user's home page and the tags themselves are automatically auto-completed for project members. The differences are not too prominent yet, but this is slowly changing.
Interesting stuff. I like the idea of higher-order free-form tagging. I don't really like the idea of having special meanings for tags like "@foo". In my opinion, the names of tags should be atomic. Instead, I propose to model users as yet another "untagged value". That is, I would extend Sebastian's proposal to:
Tag = String Untagged = Issue | Tag | User Tagged = Tag x List(Untagged)
Now something like "@foo" could be expressed as "assigned(foo)".
Yes, users should be untagged as well. But I am still hesitant to implement this. The reason is in the:
Tagged = Tag x List(Untagged)
There are two practical difficulties: If I want to store tagged issues, I would need 3 tables in the database (Issues, Tagged, Tagged_UntaggedList) as opposed to the 2 tables I need now (Issues, Tags). Consequently, any logic on tags would need to join three (relatively large) tables. As tags are used pretty much anywhere, this would have a significant impact on performance. The second difficulty is in the UI: how would a user enter a Tagged? And would it still be understandable?
I see. I'm not a datalog expert, but I think a real datalog implementation would use a separate table per tag. So "assigned(issue13, rendel)" would be stored in a table "assigned" with two columns. This would support "to whom is this ticket assigned?" well, but not "show me all tags for this issue".
If you implement the whole datalog factbase generically in a couple of tables, you are essentially implementing datalog in SQL, and that's probably not a good idea due to the interpretative overhead.
Indeed. But perhaps I'll give the three tables a try and see if it scales to a 'yellowgrass-size' database. It might work if I write efficient queries and do try to compute anything overly complex.
This has been a popular, much debated issue for a long time without to much result so far. I'm contemplating a more mundane approach and supporting a separate issue relation to model binary relations on issues:
Relation: name x issue x issue
where name can be free-form but includes some predefined ones such as blocks, depends
I kinda like the mundane approach of GitHub too. You refer to some issue, say YellowGrass/1, and you automagically get a backlink in the issue you referred to ("Lennart Kats referenced this issue in YellowGrass/38"). It's really simple, doesn't carry semantic information, but it solves the problem of manually having to maintain backlinks.
But a semantic relation can be maintained in two ways automatically.
But a semantic relation can be maintained in two ways automatically.
Log in to post comments