Jump to content

Daklu

Members
  • Posts

    1,824
  • Joined

  • Last visited

  • Days Won

    83

Posts posted by Daklu

  1. 2 hours ago, Aristos Queue said:

    The unused options do not add anything to the complexity as far as the user having to create more code or having more difficulty reading the code that they do create using the framework.

    Here you're talking about the complexity of an application that uses the framework, in which case I agree the application's complexity isn't necessarily increased by the unused framework options.  (This is especially true if the person inheriting the code has previously used the framework.  I'm not convinced it's true if the inheritor knows nothing about the framework.)

    I'm talking about the complexity of the framework itself (which is also what your original comment seemed to refer to) and how easy it is to build a mental model of how the thing works.  More behavioral exceptions and options make it more difficult to understand, which I equate to being more complicated.

    2 hours ago, Aristos Queue said:

    Depending upon how the option is presented, it might not even add anything to the complexity of adopting the framework (there are plenty of optional terminals that we just gloss over on commonly used functions and never bother to even read about).

    I completely agree how an option is presented can dramatically impact how a user perceives the complexity.  I disagree optional terminals add zero complexity to the framework.  It may be an insignificant amount of additional complexity for those who see it and mentally discard it immediately, but even in that extreme case it still takes a non-zero amount of effort to process that option and decide where it fits in the mental model we're creating.

    2 hours ago, Aristos Queue said:

    While the learnability of a framework might be impacted by options, I don't think the complexity is changed by them. Does that make sense?

    While learnability and complexity are not exactly synonymous, in my mind they're at least very closely correlated.  What kind of complexity are you referring to?

  2. 19 hours ago, Aristos Queue said:

    A framework's artificial complexity is only from the things that the framework forces on your code, not the options that it enables if you choose to buy into it.

    AF and DQMH without priority queuing are no more or less complex than AF and DQMH with priority queuing. 

    I disagree. While it is entirely realistic to build apps without using priority queues, having this option available does add complexity to the AF and DQMH.  

    If you show someone a regular piano and an electric piano/synthesizer and ask then which is more complicated, what do you think they'll say? Having more optional features available, especially when they're easily discoverable by users, adds complexity.

    Users are going to spend a non-zero amount of time considering those optional features and adjusting their mental model of how the framework works.

  3. 6 minutes ago, ShaunR said:

    As far as I'm aware. There is no guarantee (or expectation) that priority queues enforce ordering, only that higher priority messages will be executed before lower priority messages.

    The AF priority queue does enforce ordering.  The DQMH priority queue does not.

    (I'm not advocating for one or the other... personally I think priority queues are a bad idea.)

  4. 1 hour ago, drjdpowell said:

    Thought I'd show an example of "complexity" of a framework...

    That's a great example, and I'll add that I think your conclusion holds even if you didn't look at the implementation.

    On the surface the conceptual model presented by the AF seems more complex.  It has multiple priority levels available whereas the DQMH has only a single priority level.  But the AF implementation behaves predictably--messages sent in order (with the same priority level) execute in order, while the DQMH implementation may not.

    On the other hand, I think Fab strongly recommends only sending Exit/Abort messages as priority, and as long as one follows that rule you could argue DQMH is simpler.

    ------

    Thinking about it a bit more, in my mind there are at least three different kinds of complexity:

    1. Code complexity:  How hard is it to understand a block diagram.
    2. Behavioral complexity:  How hard is it to understand how a single component will behave under various conditions.  (Or how complicated is the conceptual model of the component.)
    3. System complexity:  How hard is it to understand how changes in one part of a system affect other parts of the system.

    Seems to me the DQMH priority message is simpler than the AF priority message in 1 and (arguably) 2, but takes a huge hit to 3 when multiple priority messages are sent.

  5. 20 hours ago, ShaunR said:

    This is why I said in an earlier post that people confuse architecture and frameworks...  Many people choose one framework and fit everything inside it, making it their architecture.

    Yeah, I agree with you for the most part.  Maybe that's because the applications LV developers are typically asked to write are a small fraction of the kinds of software that can be written.  My projects almost always boil down to some sort of machine control or acquire/analyze/present.  (I've not heard of anyone building a load-balancing web server, a cool 3D game, or a spreadsheet using LV.)

     

    20 hours ago, ShaunR said:

    And lets be frank (or brian). Most LV frameworks are written and intended to be just that.

    Eh... that may be true for some of them.  There's an inherent impedance in connecting non-AF code to AF code that tends to encourage people to use AF for the entire app.  (At least there was last time I looked into it 6-7 years ago.  It might be better now.)  Most of frameworks listed I haven't used enough to evaluate how easy it is to connect to them with non-framework code.  (DQMH, Aloha, DCAF, etc.)  I agree that it would be nice if it were easier to connect components that use different frameworks.

     

    20 hours ago, ShaunR said:

    So LVOOP is "accidental complexity"? :D (Just teasing)

    It certainly can be, but it's not necessarily the case.  Remember that that app has to satisfy all requirements, not just the functional requirements.  I believe any technical problem that can be solved by LVOOP can also be solved without it.  But my projects also have requirements like the number of hours I can spend developing it and it must be maintainable by John Doe.  So, I choose to use LVOOP because I don't have to build the functionality I'm looking for and John Doe doesn't have to learn my custom LVOOP-ish code.

     

    20 hours ago, ShaunR said:

    I don't really think it is a thing by these definitions when talking about complexity. Rube goldberg code exists but it isn't really "accidental". It is the product of brute forcing a linear thought process rather than iteratively designing one. Neither case is "accidental".

    I agree the terminology is bad, but you're getting too hung up on the common meaning of "accidental."  In this context it is used simply as an antonym of "inherent complexity."  (I've also seen "inherent complexity" referred to as "essential complexity," if that helps conceptualize it.)

  6. 1. What application architecture do you use for higher-level organisation?

    I'm going to be pedantic and change my answer, since the options listed are frameworks, not architectures.  😋

    The architecture I most frequently use is the "hierarchical actor architecture."  If one were to ask for a little more detail, I'd say "hierarchical actors with asynchronous name-data messages."

  7. 44 minutes ago, ShaunR said:

    Maybe I'm just getting too hung up on "accidental" and what it implies.

    The things I've read always refer to it as "accidental" complexity, but you can think of it as "unnecessary", "incidental", or simply "non-required" complexity.  It's just complexity in a system that isn't a necessary to meet the requirement (both functional and non-functional) of the system.  System complexity is a subjective evaluation, so these are more abstract ideas than concrete rules to follow.

  8. On 10/3/2019 at 3:08 AM, drjdpowell said:

    A big part of the payoff of a good framework is making large complex applications simpler. But it's hard to see this when you're on the wrong side of the learning curve.

    Hmm... I'd slightly change that to say the payoff of a good architecture is in managing an application's inherent complexity.

    IMO, the whole point of a framework is to increase productivity, so a "good" framework is one that does that.  Naturally, the frameworks we're talking about here are neither wholly good or bad, just good or less-good for a specific set of project requirements. 

    I disagree with the claim that a good framework makes complex applications simpler.  An application with complicated requirements is going to have some minimum amount of inherent complexity.  The best a framework can do is help eliminate accidental complexity.  However, I believe minimizing accidental complexity is more a product of good architecture than a good framework.

    One of the reasons I don't use frameworks is because they force developers to fit the application into the framework and tend to impose architectural decisions that are better left to the system designer.  The best frameworks (again, IMO) do not impose undesirable architectural decisions on the system designer.

     

    [Idle thought:  I suppose it might be useful to differentiate between "application frameworks" and "component frameworks."  My comments above refer to application frameworks, which I'm not convinced exist yet in Labview.]

  9. On 9/27/2019 at 2:14 AM, drjdpowell said:

    I, in using Messenger Library, seem to spend almost no time bothered by problems caused run-time type mismatches, so I am not much impressed by the edit-time type safety if it comes with the negative trade offs of requiring large scripting tools to work productively. 

    I have experienced the exact same thing using LapDog over the past 10 years.  There are very few (if any?) times when I have to have to write lengthy boiler-plate code that could be made more efficient with scripting.

  10. I chose, "Other publicly available message-passing-style 'framework,'" though I could have also chosen "Your own or your company's internal framework or templates" or "Other (please post, this includes architecting each application from scratch)" since outside of a few templates I typically write each app more or less from scratch.  (I will yank modules used in previous apps and modify as needed, but I don't typically bother making them into reuse packages.)

    Predictably, I use LapDog, and I'm glad you put "framework" in quotes as messaging libraries aren't frameworks.  :)

     

    [Edit - BTW, thanks for posting this poll.  I was going to ask the same question at my CLA presentation but had to cancel my trip at the last minute.]

  11. 9 minutes ago, Darren said:

    ...I contraindicate XControls because of numerous stability issues I've seen with them in large applications over the years.

    That's in line with what I remembered, but I didn't want to spread misinformation.  :)  (Age plays havoc on my memory.)

  12. On ‎5‎/‎31‎/‎2019 at 9:12 AM, Darren said:

    One of those employees is me, but I am always clear when I discuss this topic that my recommendation against XControls is my personal opinion and is not an official NI position.

    My apologies if I misrepresented what you said.  Can you elaborate on why you recommend against using XControls?

  13. 36 minutes ago, Aristos Queue said:

    Any CLA should be able to recognize/use/edit an XControl because it is a part of the language, and not an obscure part (like, for example, "Enable Database" on a subVI). 

    I am under the impression XControls have more or less been relegated to the rusty nails bin. I know I've seen NI employees recommend against using them in presentations. 

  14. On ‎9‎/‎24‎/‎2009 at 4:51 PM, Dan DeFriese said:

    Do we (LV) have any LV class instance initial value editor?

    Nope.  AFAIK the only way to set a class constant value is to write a VI setting the object's value, then copy the object with the desired values from an indicator and paste it onto the block diagram.

     

    9 hours ago, Petr said:

    Any ideas? Recommendations? Tools?

    I (as most developers I know) generally avoid using class constants on block diagrams and have adopted something more like what Dan suggests.  Good ideas win out...

    For example, all my classes have a "Create <MyClass>" method that more or less acts like a constructor.  The only time I ever drop a class constant on a block diagram is for typing operations (eg: upcasting or downcasting an object) or inside the class' Create method.  You can use either parameters passed into the Create method or accessor methods to set the value of the object--it's a design decision.

    I quit using class constants to instantiate objects (other than in the Create method) primarily because it reduces flexibility.  When I see an object wire on a block diagram, I want to know that object it going to work correctly.  If a class has a reference-based construct--such as a queue--as a member, then an object instantiated from a class constant is not going to work until I call a method (eg: Init) that obtains the queue and stores it in private data.

  15. Wow... was it really four years ago that we talked about this?  Time flies when you get old...

    I don't think I've used futures again since this thread** so I can't speak to the attitudes of the larger community, but my terminology preference is "future token" and "redeem."  I do agree with Shaun though, it probably doesn't matter as long as you communicate it effectively and are consistent.

    [**My development focus over the last several years has shifted from pushing boundaries on actor-oriented and messaging systems to figuring out how to refactor, componentize, and deploy an NI-RT application across different target platforms.]

     

    • Like 1
  16. I've never thought of eliminating the object out for methods that do not change state... interesting idea.  One side effect of doing that is you are also ensuring no child classes can ever change their state in the overriding method either.  That may or may not be desirable in any given situation.

     

    Just out of curiosity AQ, how do you arrange your block diagram when making calls to multiple non-state-changing methods?  Do you just run the class wire underneath the methods that don't return an object?

×
×
  • Create New...

Important Information

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