LabVIEW Idea Exchange

cancel
Showing results for 
Search instead for 
Did you mean: 
Daklu

Make namespacing and library membership independent

Status: New

When building reusable components I create a set of classes that work together to accomplish some larger goal and put them all in a lvlib.  Sometimes some of those classes are optional--they are not required by the library for it to work but they can make it easier for users to use the library for certain tasks.  These optional classes belong in the same namespace as the library.  One behavior of libraries is that they load all inner libraries.  When the inner library is a class all the class member vis are loaded, which wastes time and consumes resources when the classes aren't needed.

 

My current options are:

- Don't include the classes in the library.  Consequence:  I run a higher risk of name collisions and there's no continuity.

- Put each optional class in its own independent library.  Consequence:  Namespace pollution and a reliance on an arbitrary convention to figure out what libraries should be used together.

- Put the optional classes in the library.  Consequence:  Resources are used needlessly.

 

Usually I do the last option as it provides a more cohesive user experience.  I wish I didn't have to.  An lvlib is a functional grouping of code.  A namespace is a logical grouping of code.

 

To be explicit, I would like to be able to define namespaces for each library such that:

- I can have a single namespace that crosses multiple lvlibs.

- I can have multiple namespaces within an lvlib.

- I can add libraries to a namespace without rebuilding all the libraries in the namespace.

- Loading a component with a specific namespace doesn't automatically load all sub-namespaces.

 

Futher,

- I'm not requesting the ability to separate a single class into multiple namespaces, nor do I think that's a good idea.

- I don't mind the class name being part of the fully qualified namespace.

 

5 Comments
F._Schubert
Active Participant

Just to fuel the design discussion, in uml this is done via ElementImport and PackageImport. My own short notes can be found here. What I think goes further than the request above is to import other elements as public or private.

 

Felix

tst
Knight of NI Knight of NI
Knight of NI

Can you provide a specific example of how this would be used?

What would be the syntax and how does the namespace/library combo affect the fully qualified name?

Is this namespace attached to each specific VI (presumably yes, since you say you want multiple ones inside a library)?

How does this help in not needing to load the members? Would this only work for dynamically loaded code?


___________________
Try to take over the world!
Daklu
Active Participant

"Can you provide a specific example of how this would be used?"

 

If you mean the mechanics of defining and using namespaces, nope.  This request reaches deep enough into Labview's internals that any suggestion I come up with will almost certainly overlook some reason it doesn't work very well.  I'm just asking for dinner; I'll let them prepare the plate.  🙂

 

If you mean examples of when it would be useful, then yes.  AQ's Actor Framework uses the optional class Reply Message.  The framework does not depend on it as part of its core functionality so it is not included in the library.  It just sits out there in namespace purgatory with all the other lonely classes that aren't library members.

 

Another place it would be useful is in setting up hierarchical namespaces.  Hierarchical namespaces help users understand the relationships between classes.  I can and sometimes do use nested lvlibs, but the auto-loading inner libraries often makes that impossible.

 

 

"What would be the syntax and how does the namespace/library combo affect the fully qualified name?"

 

My preference is that the library name is completely independent of the fully qualified name.  A vi's fully qualified name consists of the namespace to which it belongs + the vi name.  That said, using the library's name as a default namespace of its members is a good idea.  I just want to be able to customize it when appropriate.

  

 

"Is this namespace attached to each specific VI (presumably yes, since you say you want multiple ones inside a library)?"

 

Ultimately yes, though I don't want to have to go through each vi's property dialog to review or set namespaces.  (Truthfully the ability to have a single namespace span multiple libraries is more important than the ability to split a library into multiple namespaces.  If vis are linked together tightly enough to be in the same library they probably should be in the same namespace as well.  However, inner libraries should be able to set their namespace independent of of the outer library.)

 

 

"How does this help in not needing to load the members? Would this only work for dynamically loaded code?"

 

No, it should not only work for dynamically loaded code.  Libraries auto-load because there is the tacit assumption that everything in the library is necessary for the code to work.  If something is missing then the code won't compile.

 

With namespaces that assumption doesn't hold.  Just because Foo.lvclass and Bar.lvclass are both members of the NI.Frameworks.Widget.FunnyName namespace doesn't mean both must be loaded for either to work correctly.  Heck, they can be completely independent from each other just like two classes in adjacent directories can be independent.  They just happen to share the same namespace.

JackDunaway
Trusted Enthusiast

@Daklu wrote:

An lvlib is a functional grouping of code.  A namespace is a logical grouping of code.


Well stated. Decoupling namespace from libraries would solve a couple of currently-irreconcilable issues when creating distributables.

 

To add to Daklu's request, I think it makes sense to be able to declare Namespace for items not even owned by a library (LVLIB, LVCLASS, or XTCL). One canonical example might be standard libraries in vi.lib -- here we find logical groups of like-functions organized by palette (and likely in the same folder on disk), yet it's not necessarily desirable to put these groups into LVLIBs just for Namespace (because we get the undesirable side-effect of static linking between members).

 

One "workaround" to try to fix these anomalous linkages (while gaining the desirable Namespace of a library) for distributables is enabling "Remove unused members of project libraries" on Build Specs. This is a dangerous setting, and can be the downfall of a thoughtfully-designed API. It allows end-users of an API to unintentionally break the library's abilities during the build. (If a setting such as this were to continue to exist, it should not be at the build-spec level -- rather, it should be as part of the library (API) definition itself.)

 

Friendships (and Community Scope) are another partial reconciliation of conflating libraries with namespace -- friendships allow API designers to declare an "open channel" between scope of their own namespace and another namespace. However, there are some key deficiencies here, such as inability to distribute password-protected friended libraries, or have a friended library dynamically launch a community-scoped member from another library.

 

The current strategy of tightly coupling libraries with namespace is a great design decision to help incidentally avoid some key problems with name collisions (that existed prior to libraries), and has probably saved the bacon of countless LabVIEW devs. However, at the same time, this coupling makes it impossible to design design truly great APIs with the most cohesive DevX possible. I'm interested in searching for a future solution that could enable both the "incidental good API design" without precluding the "deliberate excellent API design".

tyk007
Active Participant

Just a comment that this is how namespacing works in .NET - there is a difference between assemblies ("physical" grouping of code in .dll files) and namespaces (logical grouping of code). A type in an assembly does not have to be part of the same namespace and vice versa, though it is often helpful for there to be some consistency or convention.