Jump to content

robijn

Members
  • Posts

    171
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by robijn

  1. Hey that's a very nice... uhm well summary is not the right word. The discussion is quite complex as this shows. Thanks for the effort.

    I think referencing objects do not give a real conflict with dataflow. You only need to realise that if you use them at multiple places you may get a problem. But I think LV should solve that with native locking, in whatever way. There's a separate thread for that. If this locking is done, there is hardly any difference left between a containing wire and a referencing wire. Then the locking mechanism instead of the dataflow mechanism will arrange the serialisation. A starter won't notice.

    Joris

  2. Agreed, just as LabVIEW and dataflow are a way of thinking. It is pretty easy to see where someone has thought in "C" in their head and then translated into LabVIEW. I suppose the same is true for OO-LV vs non-OO LabVIEW style. I'm still making the conversion myself, having been rather set in my ways after 15 years with the language. (I have a long delayed pet project that is being rebuilt in OO now, it's just a lot of work).

    Hi Mike,

    Can you maybe tell a bit about how you do the OO part of it ? LV's native OO or other ? What were the considerations for that decision ?

    Joris

  3. In response to this The need for lock in get-modify-set pass

    Is there anyone that would share a project where by ref OO is required to solve a problem efficiently in a simple way, so that i can see from my own eyes that this is really something missing in LabVIEW?

    jacemdom@videotron.ca

    For loadable drivers, complex measurement configurations, complex result storage. Parser building, file synchronisation (building up a tree of files), representations of various DUTs, representation of (different) products produced by a machine...

    I think if you don't know what you are missing then you don't miss it. You don't seem to have a need to work object orientated. That's fine. LabVIEW does not force you and will never do so.

    Read a good book about the subject and maybe you will find places where it can be useful in your projects. You are trying to find out why we don't want back, while you should try to find out why you may want to try to design object orientated yourself. I don't say you have to, but speaking for myself, the topics you raise are passed points. It seems like you're defending NI, something for which there is no need, NI can do that itself.

    I further don't think you would be convinced by a project. OO is a way of thinking. You can live without but once you're hooked...

    Joris

  4. I also believe that forcing it to be by ref, creates unneeded complexity in the architecture.

    A native referencing system allows to leave a lot of added weight out. You could consider it simpler actually. You would not need to notice that you are actually using a reference. Like in Java. A starter does not see the difference. He does not use the data in parallel at two different places. And if he does, he has a bigger problem with the current system than with a refencing system.

    Don't forget young programmers are all used to work with objects. If you tell them that LabVIEW may wait a while before you can execute a method until an other method running in parallel is completed, they may (should :) ) say: "Hey that's great, in C I had to write all that protection code myself." And this behaviour would be perfectly natural, just like a VI can only be executing once at a time.

    This document explains a lot. Something that I agree with it that keeping dataflow is important. The argument that it prevents problems when using data in parallel is oversimpling the situation by far and I think it's wrong. For me the document contains no argument against a referencing wire, only arguments for.

    "It may even be possible with LabVIEW, to give the tools needed by the domain expert to translate is knowledge directly to the computer without the aid of the CS guys" I think it was in the graphical system design summit and i remember seing Jeff Kodosky ther also.

    I will have succeeded when i'm no longer needed!

    I think that's what I'm doing in my job constantly. I create the generics (e.g. framework), others use them (And me myself too, BTW). It's needed because the complexity of a measurement system as a whole is often quite big. But the complexity in specific areas is not very big and other users can handle it there. There is so much stuff in common between the various tests that I only need to write the more complex generic stuff and enable the other users to write the specific code for their test without too much of a hassle. That's the nice thing about power users, they enable others to work with LabVIEW.

    Success with your exploration of OO in LV.

    Joris

    I hope this topic generates discussion that would help NI to implement an excellent synchronization mechanism in LabVOOP. I hope that all talented individuals in the community participate this discussion to help NI to reach this goal. I also hope that if you just have time, it would be great if you could surf the computer science resources to find out what kinds of new techniques there exists for synchronizing access to shared resources. A Large community may find much more innovative solutions than a hired few engineers at NI. Let's give NI the power of open source design :)

    I really hope to see more NI designers in the discussion. So far I am quite disappointed by their presence. Stephen fiercely continues to defend his standpoint, which I can appreciate and respect. But it looks as if noone at NI actually thinks what so many of us power users think. Very strange. Maybe NI disallows discussing these issues outside the company, which I could partially understand.

    Joris

  5. That is my question...How can you make that possible? How can you make a "follow the datawire debugging" scheme in a by ref design? I don't see how one can follow the data in a by ref design...

    You could attach a probe to the wire and see what the object's attribute's values are... You could open a diagram and set a breakpoint. Maybe you could have a front panel and block diagram per instance of an object...

    In the diagram things don't look different at all. It's only the behaviour on life-start and life-end where things are different. The current systems creates a new object when you branch a wire, and removes an object from memory after the data in the wire is not used anymore (this is the simple version of the story ;) ). A referencing system creates an object on request (allows to have a constructor) and removes it on request (allows for a destructor; may allow for automatic destruction when an object is not used anymore but this is tricky business). The fact that the programmer needs to request a new object prevents having "parallel universes" by accident. The "request to create" could in practise be the constructor placed on the block diagram, just like a method is placed now.

    Joris

  6. i don't see objects when i model (software or any other modeling)...i see data and functions that act upon it...i don't unite them as one to create objects...i see them seperated...

    Noone should force you to use OO. To use OO should never be a target on itself. All programs I'v written that use OO aspects don't do that everywhere, only for the parts that it's useful. But I don't think the usefulness of OO is something that should be discussed here. It's already in and it will never leave LabVIEW.

    And obviously you can build OO systems without native language support. "C with classes" was the first implementation in C, it was done only in #define's etcetera.

    I don't know how to qualify the corners, but one thing i know is that i'm not in the same corner than the ones who believe that LV lacks native by ref modeling tools. If NI wants to add them in the future, so be it, as long as they never forget the original simplicity of the dataflow implemented by the fathers of LV.

    I agree with you that's essential. I believe there is a lot of power in dataflow. The route of the data on the diagram tells so much. But dataflow only works locally, in a VI and towards its subVIs. For the app as a whole dataflow is not appearent. We use functional globals all the time (I hope you do as well!) to store more complicated things that need to be accessed from multiple places. A functional global does not follow the dataflow paradigm, as it stores data in shift registers. So at that point the dataflow ends (or starts). You can use dataflow up to the functional global, and even inside the functional global, but once you place that functional global in multiple VIs the dataflow is disturbed. The same modified data does not flow in and out, a lot of data may be stored inside the VI.

    Dataflow is a great concept, but there are limits to it. The trick is to go past the limits in the best way. A functional globals is a such way, the event structure - a fascinating solution by NI - is such a way and native referencing OO would be another.

    Can "by ref" OO offer, you have bug, follow the wire?

    You mean you are affraid debugging is going to be more difficult ? Then NI should add features to make that possible. It is quite important to keep it "Rapid development".

    Joris

  7. I think that it a get-modify-set pass that could easely be protected or locked in a native implementation of GOOP, just as it is locked in openGOOP. But probably more important is the fact that if by-ref in general was natively implemented in the same manner as other languages, there would be no need for a get-modify-set pass at all.

    Yes that's what I meant as well. Immediate actions on the referenced object. Why retrieve and store it in the first place ? That was only necesary for GOOP, but not for NI ! The GOOP-ers could not access the stuff under the bonnet of LabVIEW, but NI can.

    The differences between the currently implemented static objects and referenced objects are very small. The diagram of a method would look the same. A big plus would be that there would be no object-set and object-get methods, or wrappers required. That's all just extra code that we need to carry around every time, which conflicts with a reason to go for OO: preventing code duplication.

    Having a referencing wire would allow for constructors and destructors. I completely agree with Jimi the current system is not true OO. The state of the object should always represent something in the real world and this is currently not enforcable. With con/destructors, if I would destroy an object of class IniFile, I could flush the file data and close the file nicely. Or for a driver you could free resources (eg. close a port). And on creation the state should be known as well. Generally speaking, you can keep things consistent. That is impossible now, the programmer can screw things up easily. If he branches a Keithley2000 wire and performs different operations on each object, the objects do not know of eachother and the state of the multimeter is incorrectly known. The language construction should prevent this to be possible.

    I hope NI changes its mind and changes the implementation to ref-wires in LV9. There would be no real problems with that, programs written in 8.20 would still work. On converting to 9.0 wire branches would be a problem, but it could be solved by inserting a copy constructor at that point. The class will need a copy constructor for that, but it could be added automatically on conversion. So the door is still open.

    Joris

  8. What about this problem (which I mentioned in an other thread).

    Let's assume each method is derived from a template method and retrieves the object data at the beginning and stores it at the end.

    Now, if you have three methods:

    - refresh (stores timestamp of refresh in object, and calls the following 2 methods)

    - retrieve scope wave (reads wave from scope and stores it in object)

    - retrieve scope settings (reads scpe settings and stores them in object)

    would this mean that each method retrieves and then stores the data ? Rather inefficient. And there need to be an exception for the first method, because it should store the updated data before calling the others. Or read and store after calling the submethods...

    What do you think about this ? What have been your solutions on GOOP (and maybe other LV OO systems) ?

    Let me make this statement: A referencing OO system does not need a Retrieve-Modify-Store system where you retrieve all data and store all data.

    Joris

  9. Because of the high performance gain the can be achieved and the ability to make recursive calls. Take a look at my entry at wish list.

    If you have wire level reentrancy you usually would not need recursion. You could then call methods of other objects which is usually what you want recursion for: traversing a tree etcetera. You only cannot revisit the current object.

    Joris

  10. You would need to clone method dataspases when wire branches, but you can do it lazyly by cloning only those method dataspaces that are going to be used. Then LV should also have stateless VIs which wouldn't have a state, you should use these when ever you don't need a front panel or uninitialized shift registers. This way you can avoid dataspace copies when they are not really needed. LV now copies buffers when wire branches. Why couldn't ir also make a copy of a few dataspaces. After all most class methods don't really need state so in this paradigm they would be stateless.

    I think you're cutting a corner here. There is (AFAIK) one stateless VI type now, the subroutine. All others have at least some state, even reentrant VIs, and this state data has probably become more for methods. A VI that has no "used" frontpanel objects and no shift registers is almost stateless already, so why introduce a new type ? I am in favor of storing the VI state with objects, also for front panels. That is ideal for drivers. But it is useless to store VI states with objects if objects are cloned without you notice it, like they currently are. Really, make some examples for yourself and you will be convinced. It's only interesting if the object wire would behave like a native reference.

    Joris

  11. Take a look at this :D Is this the can of worms you are *pointing* to ? :D

    No I was talking of a future native implementation by NI. The reference they would introduce, to what exactly would it point ?

    If it were to point to data in a shift register, then that data should be able to become altered without the VI that contains the shift register knows it. That means you would throw the encapsulation of a functional global out of the window. Bad...

  12. When this is not the case you could use create a reference to the class using a "REF" operator.

    Yeah right and get all the problems of C... No thanks. That's why you can't manually create a ref in Java. If you have an object (=ref) in Java then it is always poiting to an existing object (unless the reference is explicitely made NULL). Besides, in LV, what should the reference then point to, to an object in a shift register ? Which you can then silently modify without the "owner" knowing about it ? That's a can of worms.

    Because in concurrent multithreading system like LabVIEW, using references requires concurrency control like semaphores to control the simultaneous access to the reference, the same performance cannot be gained than what can be gained with dataflow objects.

    Well, don't we all have semaphores on our VIs that control parallel execution of the same VI ? We use this mechanism to make sure calls to functional globals (LV2 style globals) are serialized correctly and fairly. This shows it can be VERY efficient.

    Joris

  13. Hi everyone,

    I want to point out that any "retrieve - modify - store" system has a problem: when/where do you retrieve and store the data when calling an other method of the current class ?

    I see two possibilities.

    1. You do that in a wrapper VI. This has the disadvantage that each method needs a wrapper VI, so you effectively double the number of VIs. Code replication. If you want to call a method of the current class you don't call the wrapper VI but the method VI directly, and you hand it the object data directly.

    2. You do it in the method VI. Code replication over there. Before you call an other method of the current class you need to store the current object (if you have made any modifications) , bacause the other method retrieves the object again.

    Neither way supports calling two methods in parallel. Because they would not modify the same object but two different objects and on return of the methods, both data sets would be saved to the same object in the repository so one set of modifications would be lost.

    The way to prevent this would be a system that immediately stores any change into the object. Like you would handle an object in any other language. Much more intuitive, less prone to error and much much less code replication. Think outside the GOOP box !

    Joris

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.