LabVIEW Idea Exchange

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

Dot convention for accessing nested LVCLASS properties

Status: New

Let's assume the following two classes. Prop 1 is of type Class 2.lvclass. Both data members have their corresponding property accesors created.

 

Class1     Class2

 

 

I suggest simplifying the access to the nested class properties using dot convention similar to cluster elements. Like this

 

Read

 

 

 

 

 

 

 

 

 

Write


View my profile on LinkedIn
11 Comments
Mr.Mike
NI Employee (retired)

When I made LabVIEW Class Properties I initially planned to support dotted properties, but people who knew better than me said to leave it off for another release. So, I did.  I can guarantee you that you won't be seeing it in 2011.  That said, I will give kudos to any idea that helps keep me employed Smiley Very Happy

 

(I should point out that it is actually possible to make a "dotted" property, but you need to know about various property names.  Just set the short property name to "Prop 1.Prop 2" and the long property node to be "Prop 1: Prop 2."  In the accessor do the code you drew above.  Yes, this is a major pain in the butt, but it is possible ;))

 

I should ask though: would you expect it to work for just classes, or classes and references?  Just classes is complex.  Classes and references combined would be very complex.

 

Thanks for your feedback.  I'll keep it in consideration for the future.  I hope you're finding the feature useful. 

-- Mike
Vladimir_Drzik
Active Participant

Mike, thanks for the clarification. I didn't know there were multiple property names. You are right that it's possible to actually make the dotted property. And you are right that it's a major pain in the butt Smiley Wink, currently.

 

"would you expect it to work for just classes, or classes and references?"

For my typical use cases, it's enough to have it work for classes. Other users might have different points of view though.

 

"I hope you're finding the feature useful."

I do indeed. However, I would be more happy if there wouldn't have to be two additional (almost dummy) VIs for each single property I'd like to access. They kinda clutter the project. Loading takes longer, saving takes longer, SCC operations take longer. But yes, I'm not currently able to propose a better solution Smiley Sad.


View my profile on LinkedIn
JCC_(SK)
Active Participant

Pravdu máš

jlokanis
Active Participant

Since the property node uses the dot notation to allow access to sub properties for non-class property nodes, leaving this out for class nodes seems inconsistant.  To me, this is more like a bug than a missing feature.  You have trained the LabVIEW developer to expect this behavior from the property node and then you don't allow it for classes.  If you are going to use a property note for class data access, you need to make it consistent.  Otherwise, you should have invented a new kind of note for this purpose.

 

I would love to see this feature added.  The current implementation leads to complex diagrams that are hard to follow and hard to fit on a single monitor.

 

My only additional request is that it works with DVR wrapped classes as well as normal classes.  Again, to be consistant with current behavior.

-John
------------------------
Certified LabVIEW Architect
AristosQueue (NI)
NI Employee (retired)

What follows is not an argument against the idea. What follows is an elaboration of the problems with the idea and why it isn't just a slam dunk.
 My goal in posting it is to explain why it is more of a feature than a bug -- namely, it requires significant design consideration to make it work cleanly.

 

When reading a dotted property, there are no issues that I know about.

When writing, the dotted property syntax for a by reference type means something very different from a by value type.

 

Consider Type A which has a member of type B which has a property C. You create a node that is "On A, write B.C".

 

If B is a reference type, that decomposes into

"On A, read B. On B, write C".

 

If B is a value type, that decomposes into

"On A, read B. On B, write C. On A, write B." (The decomposition is shown nicely in the pictures in the original idea.)

 

It isn't the inplace operation that it is with a reference for two reasons:

  1. There's no guarantee that A actually stores a B directly. The value of "On A, read B" might be a computed value. The classic example is reading a Person object's Age property, which might be computed from the stored Birthday and today's date. Writing the Age property could back compute the date.
  2. When you change the value of B, you then have to pass it back through the "On A, write B" function in order to validate that the value is still a valid one for A. The write might return an error if this isn't a valid value to ever write into an A. With reference types, the author of A has to assume that the value of B could switch without A's knowledge, so such A has to be written to be ok with any value that B takes on, except for immutable values, which are checked the first time the reference is written.

With reference types, the dot notation fully discloses all the work that the node is doing -- you can see a read a read of B followed by a write of C. With value types, the dot notation doesn't make a programmer aware of all the operations involved. Is that a strong argument against the feature? Perhaps, perhaps not. Judgement call.

 

But it gets weirder. Now let's consider type A. It could be a reference type or a value type. If it is a value type, then the sequence used above

"On A, read B. On B, write C. On A, write B."

works fine. But if A is a reference type, you actually need:

"Lock A. On A, read B. On B, write C. On A, write B. Unlock A."

Not all reference types come with a way to hold onto a lock across multiple operations. In fact, I know of none in LabVIEW that do other than the DVR.

 

What that means is that reference types using value types would not be able to support the dotted properties at all, leading to a mishmash of sometimes supported and sometimes not. Is that mishmash situation an argument against making the dotted properties work in those cases where they can be supported? Judgement call.

 

Both of these problems get linearly more complex the more dots you add. "On A, write B.C.D.E" decomposes into a longer sequence of locks, reads and writes.

 

None of these is a showstopper. We might find a visualization of the property node that reflects the decomposition into three functions. We might decide that disallowing the operation when we can't acquire a lock is fine. I pushed it off of Mike's original feature list for LV class property nodes because we weren't taking the time to work on these issues. We have not had the priority to push this feature higher in the list since then.

drjdpowell
Trusted Enthusiast

AQ wrote:

Not all reference types come with a way to hold onto a lock across multiple operations. In fact, I know of none in LabVIEW that do other than the DVR.


But isn't the DVR the only reference type needed for this idea?  By-val LVOOP objects and DVR's of such objects are the only way to use LVOOP property nodes.

 

In implimenting this idea, there would need to be some method of overriding the default behavior by providing an explicit property method, for cases where one needs custom code for some reason.  

 

-- James

AristosQueue (NI)
NI Employee (retired)

> But isn't the DVR the only reference type needed for this idea?

 

At the moment, yes, but that's shifting. In the not too distant future, I *believe* there will be some hardware APIs that have LV classes as property types. They may have already shipped some drivers that do that -- I don't keep up with those APIs, I just know I've been asked about them. So if you have a DAQ refnum with a class as a property, we would need a way to lock the DAQ refnum while we do the read-modify-write sequence in order for this feature to work.

 

Again ... I'm not saying this can't be done, just that it isn't a bug that it wasn't done in the first place.

 

> In implimenting this idea, there would need to be some method of overriding

> the default behavior by providing an explicit property method, for cases

> where one needs custom code for some reason. 

I wouldn't expect so.

 

a) I can't think of any programming language that has syntax that allows that. That isn't a proof of anything, but it generally biases my initial judgement -- takes more evidence to convince me that we should strike out on our own.

b) No such support exists today for dotted properties on reference types. I realize that users can't create such reference types, but among all the arcane requests that HW engineers have made over the years for their APIs, that hasn't been among the requests.

c) The "On A, write B" VI is where you put your custom validation logic if you want to prevent certain transitions. Yes, you are validating the whole class, not a single property change. Is that what you're hoping for? A by value "on nested property changed" handler point? That's usually handled by simply providing a new property on A that sets the deep nested property internally. In that sense, you already have such overrides available today.

drjdpowell
Trusted Enthusiast

In that sense, you already have such overrides available today.

 

That's what I meant.  We can already implement nested properties by providing explicit property VIs for each one.  But that's a lot of work that would be alleviated by allowing an automatic default behavior.  But we would still need to be able to provide a custom VI if needed for some reason.

 

 So if you have a DAQ refnum with a class as a property, we would need a way to lock the DAQ refnum while we do the read-modify-write sequence in order for this feature to work.

 

Or you would just disallow this idea for any reference without a locking feature.

AristosQueue (NI)
NI Employee (retired)

> That's what I meant.  We can already implement nested properties by

> providing explicit property VIs for each one.  But that's a lot of work that

> would be alleviated by allowing an automatic default behavior.  But we

> would still need to be able to provide a custom VI if needed for some reason.

 

Yeah, that would raise a red flag for me.

 

Note: Everything past this point is ONLY about the override aspects. It does not change my evaluation of the original idea as "something that sounds like a worth while thing to do at some point." The following is a knee-jerk response. I haven't thought about this deeply, and there may be ways of working around the problems. I'm just highlighting the problem and saying "providing override ability for the outer class to override the inner class' property VI in dotted property notation sounds like a bad idea on first pass."

 

Consider... you're looking at a block diagram that looks like this:

 

Untitled.png

 

That syntax should clearly indicate which VIs are being called. Suppose that value is supposed to be rounded when it is written, but when you probe the value of the Alpha output, you can see that its value is not being rounded. So you open up Beta.lvclass:Write Dbl.vi -- sure enough, on the diagram you can see the call to the Round To Nearest function. So why isn't it being rounded? The answer -- after a lot of searching through the code -- is that someone has added a new VI to Alpha called "Alpha.lvclass:Override Beta.lvclass.Dbl.vi" and that's being called instead, and it is using some other method on Beta.lvclass to set the Dbl value. Or, more likely, it is just storing the value locally and not even trying to write it into Beta (because it also overrode the Read VI). You can also flip the problem around where the value *shouldn't* be rounded, and the override is applying the rounding... that's in some ways harder to find because in that case, Beta.lvclass:Write Dbl.vi *is* being called.

 

This is a different sort of problem from the usual "which function is being dynamically dispatched to?" because there's nothing in Beta.lvclass:Write.Dbl.vi to indicate that this VI is a dynamic dispatch VI -- because it *isn't* a dynamic dispatch VI. This is closer to the very frustrating operator overloading issue in text languages where you can see the function that should be called, but the function is never being called because someone injected a new interpretation of the syntax at a higher level. It is massively frustrating to diagnose problems in such a language because you cannot trust what your own eyes are telling you about the code. It is the equivalent of the "come from" statement... you know "go to N" jumps to a line number? Well, "come from N" causes your code to just jump from N to whereever the "come from" is located -- making the original code impossible to read because you can't tell visually that execution will be cut off.

 

If you have "overridden" a write to a nested property, I would neither draw it the same nor would I make it selectable the same. That is a separate propererty of the Alpha class entirely, and I would not suggest changing it. In fact, if you added "Alpha.lvclass:Override Beta.lvclass.Dbl.vi", I would leave it exactly where it would be if you did that today:

Untitled2.png

There's no way for the author of Alpha to counterfeit this and make the reader of the code think this is a call to Beta.lvclass:Dbl.vi because the text doesn't change color; if you find some way around that, I'd pick a different counterfeit prevention scheme. Either way, it would look visually different, and both options would exist in the menus -- specifically because they are two separate methods. Just because you have written your override doesn't mean that in your implementation you're actually invoking Beta.lvclass:Write Dbl.vi. You might be using some other facility on Beta.lvclass to set that Dbl value. The developer writing the calling code might need to make sure that the exact function Beta.lvclass:Write Dbl.vi gets invoked.

 

Now -- let me stress -- that's my own bias as a language designer, and LabVIEW might not end up that way because a lot of other people would be weighing in on it. I just think that kind of syntax abuse is a generally bad idea. If we can find ways of compensating for it then maybe I might go for it.

Alex5
NI Employee (retired)

AristosQueue brings up good points about the complication of collapsing writing to a single node. Reading on the other hand has a lot of value and use, and should be easier to implement. Right?