LabVIEW Idea Exchange

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

Allow overriding of Equality and Comparison operators in LVOOP

Status: New

I have only recently started using LVOOP but one shortcoming in my opinion is the inability to override the Equality and Comparison operators.

 

In other object oriented languages one can override the Equality operator, thereby specifying when two objects are to be considered equal. This is very helpful for using built-in search algorithms.

 

In LabVIEW two objects are considered equal if all of their fields are equal, just like with clusters. Now say one has a class User with the properties ID, Name, and Password. If I want to search an array of User objects to see if a given ID already exists, I have to use a for loop to run through all User objects and compare the IDs. It would be much easier if I could override the Equality operator and set it to just compare the IDs and disregard the rest. This way I could now simply create a new User object with only an ID and then use the Search 1D Array function to find any object with the same ID.

 

The same goes for the Comparison functionality which is useful for using built-in sorting algorithms.

 

I know this is probably opening a much bigger can of worms than I can imagine and as a way around it one could always create a UserList class that stores internally a 1D array of all IDs, which could be used to do the searching. However, in the future it might be nice to be able to override some if not all operators.

5 Comments
tst
Knight of NI Knight of NI
Knight of NI
I think there might be another alternative implementation.

Since all classes inherit from the LabVIEW Object class, NI could add the relevant VIs to that class, thus allowing us to override them.

___________________
Try to take over the world!
AristosQueue (NI)
NI Employee (retired)

I'm going to dump on this idea, then come back and support the idea, and then leave it in the quasi-undecided state that it has lingered in for the last several years.

 

This is an interview with James Gosling, developer of Java, Bjorne Stroustrop, developer of C++, and Dennis Ritchie, of C language fame:

http://www.gotw.ca/publications/c_family_interview.htm

 

Search for "operator overloading". The first hit you find is Gosling discussing operator overloading.  Gosling left operator overloading out of Java, and he discusses why in this interview. Gosling's thoughts on the subject were (and are) a big guide for me when considering operator overloading for LabVIEW classes.

 

In this interview, he mentions Multiply as a problem. LabVIEW can solve that one because we have multiple primitives for the different kinds of multiplication. But we have only one Equals prim, Less Than, etc., and the comparison prims are even worse can of worms. Suppose you wrote a Unicode String class to manage Unicode text in LabVIEW. Is the Equals prim case sensitive or insensitive? That's just one case. Operator overloading the comparisons opens the door to an equals prim that doesn't really check all the fields, a less-than primitive that isn't transitive, two objects for which both Less Than and Equal are true, or a comparison that has side effects (like writing to a file -- see "left-shift operator used for output" in C++). And, wow, if the object contains a refnum, does Equals check if the refnums are the same or does it check if the object under those refnums is the same object [think named queues] or does it check if the value under those refnums is the same [think two unnamed queues with identical elements]? These are subtleties that cause massive pain to very experienced programmers, pain that seems ill advised to open up to the LabVIEW community, especially when LV's mandate is to provide programming power while minimizing programming danger. I don't want our users to have to think, "Hey, I should check if the Equals prim is working right". I'm very loathe to have the basic primitives of the language have non-NI-defined behavior, especially the comparison prims.

 

There have been requests for the Sort 1D Array and Min & Max prims to take an additional input that is a VI Reference to the sort algorithm to be applied. That's an idea I would support long before opening up the basic language primitives. Of course it has the drawback of you have to drop a static VI reference on your diagram every time you want a particular comparison behavior, annoying for something that you want every time you compare a given class.  On the other hand, at least there's something on your block diagram that says "you're not really using Equals here".

 

Ah, but that suggests a possibility: a class author could simply create a subVI where that static VI reference is already wired into the node, and then give the new VI an icon that looks just like the primitive. Hm... that means that the visual mental confusion that we were avoiding by not having operator overloading can be created anyway. Doesn't it make sense then to go ahead and have operator overloading? 

 

Maybe. But the user of the class still is aware when he/she drops Sort 1D Array from the palette versus droping Class.lvclass:Sort 1D Array.vi. Three days later they may forget that they dropped this alternate thing, but at least when they were originally writing it, they knew they might have a problem there. 

 

That suggests that if the node dropped with something that the class author could not fabricate -- say, some glyph that went outside of the 32x32  boundary -- then we would know that this node was not the built in primitive. And that means that if we did have operator overloading, a class author could do this:

 

1) write a VI and tag it somehow saying "this is my version of Less than". 

2) when a less than prim had his class wired up to it, LabVIEW could automatically delete  the Less Than prim and put this VI call in its place, as long as LV also drew some glyph that says "this is not the standard Less Than prim". 

3) Using the Less Than prim, LV could automatically generate functions for Greater than (negate less) and equals (neither less than nor greater than), and thus supply the other comparison primitives with functionality.

 

Great! Now we have a way to visually identify the class on the diagram and there's no way for different comparison prims to conflict with each other. But we still have downsides to this:

 

A) There's no way for a user to say "but in this case I really do want to drop the standard < primitive".

B) The equals prim is way more  efficient than calling Less Than twice. In fact, a user written comparison would be more efficient than calling Less Than twice, but that way leads to inconsistent prims.

C) The Less Than operation might still be non-transitive (A < B is true, B<C is true and C<A is true, which is logically impossible), a hard bug to track down. 

D)  Actually, NaN, the representation of floating-point not-a-number, does have strange comparison rules in the < and == prims, but it still gets sorted just fine by Sort 1D Array, so there is at least one data type where overloading < would still not be enough to get Sort 1D Array to work correctly. 

E) The question of comparison for classes that contain refnums is still open to interpretation by each individual class author. 

 

But, really, these are all the fault of the class author, so why not open that door as long as the diagram makes everyone aware when they're stepping through that door? Well, the answer comes down mostly to: there's very little pressure to open that door, and if there's such a yawning abyss, there's reluctance to open it until pressured. 

 

So, at the moment, the pressure against is greater than the pressure for. You're welcome to kudos the idea to shift that balance.

gb119
Member

I would dearly love special oeprator methods for LabVIEW classes - preerably polymorphic dynamic dispatch methods so that I could implement binary operators with different types of operand. Of course that would need polymorphic, dynamic dispatch methods first (which I guess means defining a method resolution order - probably polymorphic then class and sub-classes must be subsets of ancestor class polymorphs so that LabVIEW can always find at least one method implementation no matter what the run-time type on the wire is).

I would also quite like to see special conversion dot methods that would convert class->other type or other type->class and the editor would insert them as needed. This would allow a form of constructor method, but also to wire a class into a primitive without the primitive needing to be implemented - perhaps not as flexible, but maybe a little more predictable?

Finally, in the academic science and engineering circles I move in, Python has become increasingly prominent as another language we use routinely, and that, of course, does do operator overloading and all kinds of crazy special methods - so it might be that the idea of operator overloading and and the meaning of an operator not being always totally consistent is something more LabVIEW users are familiar with?

--
Gavin Burnell
Condensed Matter Physics Group, University of Leeds, UK
http://www.stoner.leeds.ac.uk/
Nate@UT
Member

Are there any data types which can be members of a class's private data which are NOT part of a comparison/equality test?  I was hoping to get away with storing private data in a class which is excluded from comparison between two objects of that class by storing it as a Variant, but even variant data is included in class comparison.

Rather than full-blown operator overloading, it would at least be a great feature to have a class's private data members be excluded from equality operator by a simple right-click menu on the private data member's icon and a menu selection to the effect of "Ignore this Data Member in Class Comparison" or something of that sort. 

wiebe@CARYA
Knight of NI

>Are there any data types which can be members of a class's private data which are NOT part of a comparison/equality test?

 

No.