Make the rank metaslot inherited - #264
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the LinkML metamodel schema to treat the rank metaslot as inherited, so that rank values propagate through slot-to-slot inheritance and downstream tooling can preserve intended ordering.
Changes:
- Mark the
rankslot (metaslot) asinherited: truein the metamodel schema.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
This feature makes sense to me, and it seems safe for the schemas I maintain. I checked MIxS, nmdc-schema, and the NMDC submission-schema. In none of them would any slot start inheriting a rank, so nothing changes downstream for us. MIxS sets rank only inside One note on timing rather than on the change itself. Inheritance is not read from Separately, be aware that a rank of 0 will not inherit. The code that copies inherited values treats 0 the same as a value that was never set. That is not this pull request's fault and it already affects more important metaslots. Filed as For rank the only consequence is display order, so I would not hold this up for it. |
|
Hey @turbomam, thanks for the review :) neither of these issues apply to LinkML-Scala, so we are 100% fine with this. |
|
@cmungall do you have any thoughts about this? Several questions came up in the LinkML developer's meeting yesterday
|
|
@Ostrzyciel can you say whether you intend for your Scala implementation of LinkML to be a subset, superset or parity matching with the Python reference implementation? |
We are currently focusing on the features that are needed for the use cases that we have at hand. Long-term, I think a sensible approach would be for LinkML-Scala to implement most of the LinkML specification, but this really depends on what people will want from it. Note that we are not trying to reimplement linkml/linkml, so we do have some things that work differently than in Python. For us the only source of truth is the spec. |
|
@turbomam we also made a community post explaining why we made LinkML-Scala :) https://github.com/orgs/linkml/discussions/3787 |
| - order | ||
| - precedence | ||
| - display order | ||
| inherited: true |
There was a problem hiding this comment.
@turbomam flagged that rank: 0 won't inherit, correctly attributed it to the truthiness bug in #3845, and said not to hold the PR for it. What about this though?:
slots:
ranked_parent: {abstract: true, rank: 5}
child: {is_a: ranked_parent, rank: 0}will the child end up with rank 5 because 0 is falsey?
There was a problem hiding this comment.
This does seem to be the behavior for int-valued slots in LinkML. LinkML-Scala generates 0. I don't think the spec says anything about this case, but I can't think of a reason why would rank 5 be the desired behavior.
There was a problem hiding this comment.
@niegrzybkowski the problem is not on the spec/model side - the problem is here that the spec change reveals a potential problem in the linkml runtime which needs to be fixed before we can merge / ship this!
From you as pure consumers of the model this is of course annoying, but thats why we have this problem of not being able to cleanly split the model from the runtime: we cant just approve a change to the model (whether or not it is a semantically meaningful change to the spec) if we cant convince ourselves that the runtime can handle it correctly.
All that said, we have a separate internal discussion on this PR going on where we try to resolve this. I will keep you posted.
There was a problem hiding this comment.
the problem is not on the spec/model side - the problem is here that the spec change reveals a potential problem in the linkml runtime which needs to be fixed before we can merge / ship this!
I... I don't understand, sorry. The case you provided is a theoretical situation that nobody has reported as a real issue. Therefore, making rank inherited does not introduce a regression, so it can be merged.
If I understand correctly (and I'm very confused, to be honest), the argument is that this might become a problem in the future for some rare use cases due to an unrelated issue elsewhere in the spec or the runtime. Using the same logic, one could veto any change in the LinkML spec, because of course there are plentiful bugs in the current implementations.
we have this problem of not being able to cleanly split the model from the runtime
There must be a constructive process to introducing changes in the spec and the metamodel, otherwise it will be extremely hard to make the spec and the implementations better. Typically, a spec change is first made, expectations / conformance tests written, and then implementations simply go on to comply with the change. This can be done in the next release.
You can always report partial spec compliance and work towards it iteratively, this is literally what everyone in the software world does, e.g., with W3C Recommendations. No implementation is ever fully spec-compliant and cases like linkml/linkml#3912 demonstrate that. Nobody stops RDF 1.2 from being released because rdflib or RDF4J are not keeping up with all the features, or may implement it in a buggy manner.
There was a problem hiding this comment.
I would also like to point out that this is a non-breaking change with a single line diff. If it warrants so much discussion and checks, then I see no path of making any meaningful changes to the spec. I do not wish to bash on you as the maintainers here, I just want to demonstrate that this approach to spec changes will be extremely hard (or even impossible) to manage in the future.
There was a problem hiding this comment.
...if you would like, I could offer some help with setting up a reasonable spec management process. I'm not an expert myself, but I did write the Jelly spec (5 implementations), and I'm leading a Task Force at W3C RSP CG where we wrote this. I would be happy to help.
| - precedence | ||
| - display order | ||
| inherited: true | ||
| description: the relative order in which the element occurs, lower values are given precedence |
There was a problem hiding this comment.
What's the rule when a rank arrives from both is_a and a mixin? The spec's CombineSlotsMetaslots table has no row matching two different non-null integers, so it's undefined — and the two engines already disagree: for is_a: (rank 1) + mixins: [(rank 3)], SchemaView gives 3 and SchemaLoader gives 1. Since 07codegen.md makes rank order a MUST, can the missing row go in this PR? min(v1,v2) would be my suggestion, since it's order-independent.
There was a problem hiding this comment.
Good point, I did not notice this. The table does have an answer: the fallback v1 wins, the problem then would be that the spec does not define is_a/mixin order for slot inheritance, only for classes.
To me, it's also a separate issue, as it also affects the exact_cardinality, minimum_cardinality and maximum_cardinality metaslots in the exact same way.
There was a problem hiding this comment.
I don't think int merging with min(v1, v2) would be a good solution - the minimum_cardinality metaslot would then expand with inheritance rather than narrow down
Resolves linkml/linkml#3808