Ramifications of *not* constraining the URL in conformance resources to a fixed value (fixedUri or system)? - hl7-fhir

It seems that some conformance resources are written to prescribe fixed URLs (with or without version suffix), for example by constraining meta.profile to a fixedCanonical.
{
"id": "Invoice.meta.profile",
"path": "Invoice.meta.profile",
"fixedCanonical": "http://zrbj.eu/StructureDefinition/foo|1.2.3"
}
This means that users always MUST specify the URL exactly as specified, i.e. with or without version, and the builtin flexibility of the FHIR mechanisms goes down the drain.
If I leave off the constraint then it is the user's choice whether to specify a version or not. Given a profile http://zrbj.eu/StructureDefinition/foo with version 1.2.3 the following four canonicals all work as expected in meta.profile of resource instances:
http://zrbj.eu/StructureDefinition/foo
http://zrbj.eu/StructureDefinition/foo|1.2
http://zrbj.eu/StructureDefinition/foo|1.2.2
http://zrbj.eu/StructureDefinition/foo|1.2.3
http://zrbj.eu/StructureDefinition/foo|1.2.4
The fifth example (resource with higher patch level than the profile) may be slightly counter-intuitive but that is how semantic versioning (SemVer) is supposed to function here: if major and minor version correspond then a resource with lower patch level must be accepted by a profile version with higher patch level and vice versa (i.e. compatibility goes both ways).
The following canonicals do not match major.minor of the profile and are rejected, as expected:
http://zrbj.eu/StructureDefinition/foo|1
http://zrbj.eu/StructureDefinition/foo|1.1
http://zrbj.eu/StructureDefinition/foo|1.3
Our usage scenario calls for the second accepted case: resources must 'commit' to one of the structural versions (major.minor) defined as permissible on the day of their creation, and they must document this by specifying the chosen version in the URL suffix. This still leaves the profile author free to fix minor things and increment the patch level, as long as two-way compatibility is preserved. It also offers a way of fixing certain classes of bugs with the least amount of collateral damage.
Is there anything that speaks against leaving off the URL-fixing constraint, given a usage scenario as the one I described?
UPDATE
Lloyd McKenzie has pointed out that extension URLs cannot be versioned. Hence I have rewritten the examples to use meta.profile instead.

Extension.url is defined as having a type of "uri", not "canonical". That means that version-specific references are not permitted. The version of the extension "in play" is driven by the version of the core specification in play and/or the versions of the IGs declared in the CapabilityStatement of the server. If neither of these define the extension, then the version of the extension may be ambiguous. For this reason, its important to not significantly change the semantics of an extension over time - instead, if needed, define a new extension.
There is currently no conformant mechanism of declaring the 'version' of an extension in an instance. If this is an essential requirement for you, submit a change request using the "propose a change" link at the bottom of any page in the spec and the community can discuss alternatives. (Given that Extension is now normative, it is extremely unlikely that changing to allow the 'canonical' syntax will be the agreed solution, as that would be a breaking change.)

Related

What does the Maven well known qualifier of sp stand for?

I have read several good articles on the Maven versioning with well known qualifiers. However, I found it interesting that after the so called 'final' release which is an empty qualifier, ga, or final I can't find any article that describes how the sp qualifier might be used. Evidently it compares greater than the final qualifier, but I've no idea of the letters stand for something in particular or if there is some popular software release convention that uses that qualifier. rc would typically mean release candidate, so I would think that sp would have some kind of meaning and that the letters were chosen in accordance with some kind of pattern.
Here is one of the articles I've already read, and I see no info that would give me a hint as to what sp means or how it might be used.
https://cwiki.apache.org/confluence/display/MAVENOLD/Versioning
AFAIK this stands for "service pack" and therefore describes corrections/additions after the final release.

FHIR and null flavors

I am trying to understand how FHIR handles null flavors in comparison to CDA. Here, FHIR says that "FHIR approaches the problem differently. Null flavors are only introduced in the core specification in those circumstances where it is expected that most systems will need them. Where needed, the flavors are constrained to those relevant to that element."
What does this mean? Does this mean that FHIR allows null flavors only in some circumstances, i.e., in some resources where it is expected that most systems will need them? But in my reading of FHIR so far where I came across several resource I found none with null flavor.
Or is it the case that FHIR does not at all allow null flavors and if one needs it, extensions should be used?
It's indeed the case that if one needs nullFlavours, extensions may be used.
When we wrote "Null flavors are only introduced in the core specification in those circumstances where it is expected that most systems will need them" we expected our resources to have "real" elements in places where nullflavours are common (but then with a more useful name, e.g. "tooSmallToMeasure" in an Observation). This did happen to the v3 "negation" indicator, which was for example turned into an element Procedure.notPerformed.
As it turned out sometimes nullFlavors are explicitly allowed or required, but this is not done in the general specification but only in profiles and Implementation Guides, where their use is detailed and the circumstances in which they may appear is explicitly documented.

Best practice for Cocoa category naming conventions

I am tidying up my ancient Cocoa code to use modern naming conventions. There has been lots of discussion on best practices, but I'm unsure of one thing.
I'm thinking about adding a prefix to category method names, to ensure uniqueness. It seem generally agreed that this is a good idea, though most people probably don't bother.
My question is: what about a NSDictionary category method like -copyDeep that does a deep copy? The method used to be named -deepCopy, but I reversed the words as the analyzer looks for a prefix of "copy". Therefore I presumably couldn't add a prefix. And having the "prefix" in the middle or end of the method name seems messy and inconsistent.
I'd also be interested in thoughts on the style of prefix -- I currently use DS (for Dejal Systems) for class prefixes. But I know that Apple now wants to reserve all two-character prefixes for themselves, so am thinking about using Dejal, e.g. my class DSManagedObject would be renamed as DejalManagedObject. And getting back to categories, their methods would be renamed to add a dejal prefix, e.g. from -substringFromString: to -dejalSubstringFromString:. But -dejalCopyDeep would confuse the analyzer, so maybe I'd have to be inconsistent for such methods, and use -copyDeepDejal or -copyDeep_dejal?
I will be re-releasing my categories and various classes as open source once I've cleaned them up, so following the latest conventions will be beneficial.
I emailed the Apple Application Frameworks Evangelist about this, and got a reply that recommended not prefixing category method names. Which conflicts with the advice in the aforelinked WWDC10 session, but I assume reflects Apple's current thinking.
He recommended just looking at the beta seed API diffs to spot conflicts, which is what I've always been doing.
I agree with Kevin Ballard, you should prefix your category method names, particularly if you are going to distribute them to others. But you do have a valid concern the analyzer will be confused by DScopy. The ARC compiler will similarly be confused if the definition/implementation of DScopy is done without ARC and is used by another class using ARC (or vice versa).
My preferred solution is to use "ownership transfer annotations", such as:
NS_RETURNS_NOT_RETAINED
NS_RETURNS_RETAINED
They would be used to override the compilers default behavior of reading method names and acting on them. You might declare DScopy like so: (This declaration must be in a header file that is imported by all the classes that use this method mentioned due to link)
-(DSManagedObject *)DScopy; NS_RETURNS_RETAINED;
Source for NS_RETURNS... WWDC 2011 Session 322 - Objective-C Advancements in Depth. The meat of this issue begins at about time 9:10.
A note about "But I know that Apple now wants to reserve all two-character prefixes for themselves". As a personal preference I like to use the _ character to separate the prefix from the name, it works well for me. You might try something like:
-(DSManagedObject *)ds_copy; NS_RETURNS_RETAINED;
This would give you three characters, and arguably make the method name more readable.
Edit In response to link posted in comment.
However as Justin's answer to your original question says that can be broken.
With regards to attributes; I did not suggest using __attribute__((objc_method_family(copy))) I suggested using NS_RETURNS_RETAINED, which translates to :__attribute__((ns_returns_retained)). While the first example there won't even compile (as he says) using - (NSString *)string __attribute__((objc_method_family(copy))); it compiles with - (NSString *)string; NS_RETURNS_RETAINED; just fine.
Obviously also if the NS_RETURNS_.. are "hidden" from the compiler in separate the .ms or indirected in some other way and the compiler can't see the directives then it won't work. Because of this I would suggest putting the declaration for any methods that may cause the analyzer/compiler confusion in your main .h file (the one that imports all the others) to limit the chances that there will be an issue.

Cross version line matching

I'm considering how to do automatic bug tracking and as part of that I'm wondering what is available to match source code line numbers (or more accurate numbers mapped from instruction pointers via something like addr2line) in one version of a program to the same line in another. (Assume everything is in some kind of source control and is available to my code)
The simplest approach would be to use a diff tool/lib on the files and do some math on the line number spans, however this has some limitations:
It doesn't handle cross file motion.
It might not play well with lines that get changed
It doesn't look at the information available in the intermediate versions.
It provides no way to manually patch up lines when the diff tool gets things wrong.
It's kinda clunky
Before I start diving into developing something better:
What already exists to do this?
What features do similar system have that I've not thought of?
Why do you need to do this? If you use decent source version control, you should have access to old versions of the code, you can simply provide a link to that so people can see the bug in its original place. In fact the main problem I see with this system is that the bug may have already been fixed, but your automatic line tracking code will point to a line and say there's a bug there. Seems this system would be a pain to build, and not provide a whole lot of help in practice.
My suggestion is: instead of trying to track line numbers, which as you observed can quickly get out of sync as software changes, you should decorate each assertion (or other line of interest) with a unique identifier.
Assuming you're using C, in the case of assertions, this could be as simple as changing something like assert(x == 42); to assert(("check_x", x == 42)); -- this is functionally identical, due to the semantics of the comma operator in C and the fact that a string literal will always evaluate to true.
Of course this means that you need to identify a priori those items that you wish to track. But given that there's no generally reliable way to match up source line numbers across versions (by which I mean that for any mechanism you could propose, I believe I could propose a situation in which that mechanism does the wrong thing) I would argue that this is the best you can do.
Another idea: If you're using C++, you can make use of RAII to track dynamic scopes very elegantly. Basically, you have a Track class whose constructor takes a string describing the scope and adds this to a global stack of currently active scopes. The Track destructor pops the top element off the stack. The final ingredient is a static function Track::getState(), which simply returns a list of all currently active scopes -- this can be called from an exception handler or other error-handling mechanism.

Configuration Management - History in Code Comments

Let me pose a bit of background information before asking my question:
I recently joined a new software development group that uses Rational tools for configuration management, including a source control and change management system.
In addition to these tools, the team has a standard practice of noting any code changes as a comment in the code, such as:
///<history>
[mt] 3/15/2009 Made abc changes to fix xyz
///</history>
Their official purpose for the commenting standard is that "the comments provide traceability from requirement to code modification".
I am preparing to pose an argument that this practice is unnecessary and redundant; that the team should get rid of this standard immediately.
To wit - the change management system is the place to build traceability from requirement to code modification, and source control can provide detailed history of changes by performing a Diff between versions. When source code is checked in, the corresponding change management ticket is noted. When a CM ticket is resolved, we note which source code files were modified. I believe this provides a sufficient cross-reference for the desired traceability.
I would like to know if anyone disagrees with my argument. Am I missing some benefit of commented source code history that change management and source control systems cannot provide?
For myself, I have always found such comments to be more trouble than they're worth: they can cause merge conflicts, can appear as 'false positives' when you're trying to isolate the diffs between two versions, and may reference code changes that have since been obsoleted by later changes.
It's often (not always, but often) possible to change version-control systems without losing metadata. If you were to move your code to a system that doesn't support this, it would not be hard to write a script to convert the change history into comments before the cutover.
A comment allows you to find all the changes and their reasons in the code right where they are relevant without having to dig into diffs and version control system intricacies. Furthermore, should you decide to change of version control system, the comments will stay.
I worked on a large project with similar practice that had changed of source control system twice. There wasn't a day when I wasn't glad to have these comments.
Is it redundant? Yes.
Is it unnecessary? No.
I've always thought that code should be, of course, under version control, and that the current source code (the one that you can open and read today) should be valid only in present tense.
It doesn't matter if a report could have up to 3 axis in the past and last month you updated it to support up to 6 axis. It doesn't matter if you expanded some function or fixed some bug, as long as the current version can be easily understood. When you fix a bug, just leave the fixed code.
There's an exception, though. If (and only if) the fixed code looks less intuitive to you than the previous, incorrect one; if you feel that someone might come tomorrow and, just by reading the code, be tempted to change it back to what "seems more correct", then it's good to add a comment: "This is done this way to avoid... blah blah blah." Also, if the problem behind is an infamous war story inside the team's culture, or if for some reason the bug report database contains very interesting information about this part of the code, I wouldn't find it incorrect to add "(see Bug Id 10005)" to the explaining comment.
The one that jumps to mind to me is vendor lockin. If you ever moved away from Rational, you'd need to make sure that the full change history was maintained during the migration - not just the version of the artifacts.
When you're in the code you need to know why it's structured like that, hence in code commenting. Tools that sit outside the code, good though they may be, require far too much of a context shift in your brain to be useful. As well as that, trying to reverse engineer the code intent from documentation and a diff is pretty damn hard, I'd much rather read a line of comment any day.
There was a phase in the code I work on, back in the 1994-96 time frame, where there was a tendency to insert change history comments at the top of the file. Those comments are now meaningless and useless, and one of the many standard cleanups I perform when editing files containing such comments is to remove them.
In contrast, there are also some comments with a bug number at the location where the change is made, typically explaining why the ridiculous code is as it is. These can be very helpful. The bug number gives you somewhere else to look for information, and fingers the culprit (or victim - it varies).
On the other hand, items like this one - genuine; cleaned up last week - make me grit my teeth.
if (ctab->tarray && ctab->tarray[i])
#ifndef NT
prt_theargs(*(ctab->tarray[i]));
#else
/* Correct the parameter type mismatch in the line above */
prt_theargs(ctab->tarray[i]);
#endif /* NT */
The NT team got the call correct; why they thought it was a platform-specific fix is beyond me. Of course, if the code had used prototypes instead of just parameterless declarations before now, then the Unix team would have had to fix the code too. The comment was a help - assuring me that the bug was genuine - but exasperating.

Resources