Jump to content

JackDunaway

Members
  • Posts

    364
  • Joined

  • Last visited

  • Days Won

    39

Posts posted by JackDunaway

  1. Queues are many-to-one. Events are one-to-many.

     

    Not explicitly true -- for Queues, an enqueuer and a dequeuer are both accessing the same Queue object, whereas with Events, the enqueuer and dequeuer are interfacing with two separate objects -- the event publisher and the event registration/subscription.

     

    Any number of writers may write to a Queue, and you may have any number of readers as well; stated another way, contrary to popular belief, you may have multiple asynchronous dequeuers pulling out of the same queue.

     

    Events have a bit different semantic than Queues in LabVIEW -- there must be one and only one Handler bound to an Event Registration at any one time, yet there may be [0,N] Registrations per publisher. With this extra level of indirection, I don't know if we can even properly classify Events as being something-to-something, but rather (N publishers)-to-(M registrations)-to-(0 or 1 handlers bound to a registration at a time).

     

    Breaking it down:

     

    Queues are many-to-many, one-to-many, one-to-one, or many-to-one, depending on what makes sense for your application domain.

     

    Events support the same configurations, though with one additional level of indirection (which enables a host of additional design patterns), and the caveat that there may never be multiple readers (Event Handler Structures) simultaneously bound to one Event Registration. This caveat is the one I would like to see lifted, that Events might act more like Queues, in order to better support concurrent processing.

    Interesting idea Piranha Brigade. I like the idea of a troop of asynchronous slaves chomping away at tasks from a single publisher. What advantages would you expect events to have over queues though?

     

    Actually the other way around -- Queues have the advantage in LabVIEW for the time-being for the Piranha Brigade pattern, because Event Registrations do not yet allow multiple handlers to be concurrently bound to a single registration. The run time behavior is literally undefined -- utterly random results in the total number of events handled, at least as of LV2012.

    • Like 1
  2. Cool utility! +1

     

    ...Wirebird Labs has done something like this in the past...

     

    Short answer: the concept=no, the tools=yes, the domain=yes. :-)

     

    The concept is like ... inversion of inversion of control -- check for dependencies, then inject the dependent. It's a fresh look on an old problem.

     

    On this topic, looking forward, I'm interested in considering both dev and deployment environments as disposable appliances -- self-contained environments with no external dependencies. One important factor here is minimizing footprint -- not so much from a storage perspective, but because bandwidth (i.e., time) is an expensive UX resource. In the meantime, searching things like "Segmenting the LabVIEW Run-Time Engine" describes an unofficially-support method of solving current probs.

     

    Our root motivations are the same -- reduce pain introduced by shuffling around large dependencies. And even though IoIoC may not be optimal in many situations (especially in non-strictly controlled deployment targets), it is precipitously close to other solutions using some of the same tools. :-)

  3. A VI is both beautifully and grossly overloaded to be many things.

     

    Give it a conpane and inputs/outputs -- bam, a VI is a function.

     

    Give it a loop -- bam, it becomes a process.

     

    Give it some outbound messaging transport mechanisms -- bam, active object.

     

    Give it an Event Handler Structure -- Bam. Actor. (To be fair, a VI is an actor all along... down to even the Space Constant... just many levels of pared-down actors)

     

    Now, start composing each of those roles into collections -- you get APIs, then libraries, then systems, then applications. Each of these levels of VI definition and collections of VIs requires different semantics and programming styles.

     

    I see the limitation of one Event Handler Structure per VI as a decision that has the potential to significantly improve our abilities to build the higher-level abstractions in LabVIEW that are currently laborious and suboptimal. For instance, this opens up new possibilities to expanding the API of VI Reference instances -- we can start to drop existing primitives (like Generate Event) onto a VI Reference, since that VI has defined itself as being able to handle a set of messages that it can receive, and could even declare types. Imagine: a VI could declare its asynchronous API (rather than having to manually route the plumbing yourself as a dev -- we rise from procedural definitions of behavior to declarative definitions. Though, perhaps this declarative definition is stored at the LVClass level and then routed to a handler process within the class? We can skin the cat a few ways; different syntax, same semantics.)

     

    Singletons, single instances of APIs or syntax -- those can be limiting or even crippling -- but right now I don't feel this proposal falls into this category. Now, if we were talking about only allowing one Event Registration wire (this one: post-17237-0-47132200-1386113552.png) -- I'd fight this tooth and nail, since it destroys semantics of a thoughtfully-designed active object in LabVIEW. (Spoiler: this wire and the Register For Events node, contrary to popular belief, absolutely have an N:1 relationship with any arbitrary Event Handler Structure)

     

    The Events API is perhaps my favorite API in the entire LabVIEW language -- syntax is gorgeous (five nodes and structure) and semantics are even better. Event-driven programming is the backbone of anything I create. Those of you who saw my NIWeek 2013 presentation are aware how excited i get on this topic! :-] I say this, just to emphasize good faith and optimism that even though we're discussing a restriction, what we're really talking about is bounding the bigger picture that could enable much cooler things.


    As with the other comments above, I'd be disappointed if this proposal is meant just to weld on the training wheels, yet incredibly excited if it's to enable better syntax and VI definitions for building systems. I'm just curious for OP to reveal a larger surface area of his genius and roadmap than a simple, controversial question.  :)

    • Like 2
  4. There's a lot of brainstorming going on around possible new features

     

    What value proposition do you offer, if we agree to limit a diagram to a single Event Handler Structure?

     

    My knee-jerk reaction is fight such a change (since, naïvely, it feels arbitrarily limiting, and perhaps for benefits that don't matter to me). But having thought about this quite a bit -- any changes that enable Events to be used more ubiquitously (including registrations for many shipping APIs, and registrations on different comm types such as Queues and Notifiers) would be welcomed.

     

    I can dream even of defining systems like Tomi describes on his newly-revived blog ExpressionFlow, where rather than having Terminals enabling synchronous dataflow between networks of VIs, we have Incoming/Outgoing Event (Message) Definitions that enable async dataflow between nodes (VIs). Here, a 1:1 ratio between VI:Event Handler probably makes sense, to simplify routing.

  5. Mitch Hedberg, on Constructor Injection vs. Setter Injection:

     

    I got a 'Do Not Disturb' sign on my hotel door.

     

    It says 'Do Not Disturb.'

     

    Its time to go with 'Don't Disturb.' Its been 'Do Not Disturb' for too long. We need to embrace the contraction. 'Don't Disturb.'

     

    'Do Not' psyches you out.

     

    "'Do...' Alright, I need to disturb this guy... 'Not...' SHIT! I need to read faster!"

     

    <xkcd-style-alt-text>I'm contemplating deriving all future API design strategy from comedians.</xkcd-style-alt-text>

  6. Stobber: have you considered creating a logger actor (service/subsystem/agent) dedicated to performing this action? Other actors in your system, when they want to write an event to the log, would not perform the log write themselves; rather, the event is brokered through this Logger Actor, which contains all procedural behavior for writing to the Windows Event Log.

     

    The logger subsystem would provide a VI called "Serialize to Syslog" which has no dependencies (including, not being contained within the logger's library/class). This means that any arbitrary system in your application only needs two things: 1) a lightweight, dependency-less method to serialize into your log format du juor, and 2) access to the endpoint (actor reference/address/mailbox/enqueuer) of the logger actor.

     

    I've had good success logging within a single actor (rather than as a distributed effort throughout the system) since the disk (or generally, log store) is a shared resource. The logger actor can do things like batch writes, and it generally frees your other systems from this otherwise expensive, blocking action.

     

    This doesn't answer your original question, per se, but could at least contain the Event Logger API to a single actor on the Windows target.

     

     

    ***EDIT: This method is not unlike the LabVIEW Syslog Protocol Reference Library linked by Phillip, except you'd be using your existing actors and transport mechanisms. Perhaps you can pluck the APIs from that reference library and plug them into your own system...***

  7. Eli, I've been running Parallels 8 since it came out (last year or so?) with this issue; Parallels 9 just came out a few weeks ago, and I'm yet to upgrade to try that (waiting for the dust to settle on that and Mavericks also).

     

    "I'm pretty sure this isn't LabVIEW's problem" << Anecdotally, I think it might be LabVIEW, since every other application in the VM accepts 3-key shortcuts, including CTRL+SHIFT shortcuts -- it's just LabVIEW that's having problems. For instance, open Chrome in your VM, go to a webpage, exit that page, and hit CTRL+SHIFT+t -- the tab will re-open. Likewise, CTRL+ALT+s and CTRL+SHIFT+s works in Notepad++

  8. Growing up, did you hear the kindergarten joke, "your epidermis is showing!"?

     

    Live and learn -- we all come to realize 98% of the time it's fine to have some epidermis showing, and that other 2%, you're going to have much earlier and much more distinct warning signs.

     

    Thoric, apologies for lack of a better response, but I've just stopped paying any attention to the report provided by "Find Items Incorrectly Claimed by a Library", having seen zero Real Problems in either dev or deployment environments. The compiler warns of all Real Problems.

  9. Thanks all for the response -- a team is currently chatting offline to schedule an initial meeting. And just to answer a few questions publicly:

    • This is a non-commercial, "after-hours", open source project for fun, but it's meant to help us perform our day jobs better
    • No picture controls; all visualizations are rendered in the browser using existing javascript libraries (LabVIEW<->js communication using JSON)
    • If you'd like to "follow along at home", ping me and I'll gladly send details to dial-in as a viewer on our video/screensharing brainstorming/work calls

    Best,

    Jack

  10. Greeting, wireworkers! I have an idea and a need for some software development tools, just not the bandwidth to develop them by myself. Would you help me?

     

    Problem description: I find myself needing/wanting to visualize dependencies of code modules in LabVIEW. A "module" is loosely defined here, as perhaps a library, a VI, a project...

     

    Current tools available: VI Hierarchy gives a nice view of static dependencies of a single VI; Class Hierarchy gives a decent view of a project's object model; the Dependencies section of a LVproj give a good listing of all static dependencies of the project.

     

    Rationale for a new tool: Make it easy to visualize how code modules are interconnected, to be used as a debug and design tool for system architectures written in LabVIEW.

     

    Want to help?: Just drop a line -- either private message or email. Ideally, you've got some experience with the LV Linker and Javascript; no worries if not, I can help out. Likewise, ideally you've found yourself wanting similar tools to enhance your experience developing systems.

     

    What happens to the tools we create?: The immediate goal is to help ourselves on our own projects and scratch our recreational programming itches; in the future, perhaps there's enough polish and interest to release open source to the community.

     

    Here are a few ideas:

     

    1. Dependencies of top-level application modules (interactive source: http://www.findtheconversation.com/concept-map)

     

    post-17237-0-69973300-1383338810.png

     

    2. Relative size of libraries and their inter-connectedness (interactive source: http://redotheweb.com/CodeFlower/)

     

    post-17237-0-56518300-1383338918.png

     

    3. How VIs connect to each other, grouped by library (interactive source: http://redotheweb.com/DependencyWheel/)

     

    post-17237-0-87047000-1383339060.png

     

    4. Coupling and cohesion between methods grouped by library (interactive source: http://bl.ocks.org/mbostock/4062045)

     

    post-17237-0-53328100-1383339187.png

    • Like 1
  11. Steen, thank you for the model, this helps as a talking point.

     

    Even though composition may solve your problem, one caveat is introducing a non-trivial amount of work in the form of creating proxy methods.

     

    For example, your VIFile composes an LVIcon, which has the method LVIcon::SetIcon(). Your application that uses the VIFile API probably needs access to the method SetIcon(), meaning you'll need to create a VIFile proxy that wraps SetIcon().

     

    Likewise, that proxy will need to be written in PolyVIFile, LVLibraryFile, LVControlFile...

     

    Now, we've created several maintenance points. What if the LVIcon::SetIcon() conpane (interface) changes? We'll have to go update all the existing conpanes (interfaces) of the proxy wrappers.

     

    The alternative to proxy wrappers is to create a getters/setters for the composed objects -- though this is suboptimal, and often breaks atomicity. You're breaking encapsulation, and potentially exposing the application calling the API to race conditions or even deadlock.

     

    Now, assume LVOOP gave us Mixins or Traits.

     

    The method SetIcon() is implemented by the LVIcon Trait (rather than the LVIcon Class), and then VIFile, PolyVIFile and so forth would declare the Trait LVIcon. The method SetIcon() is written only once, and can accept object types of VIFile, PolyVIFile, and so forth, in order to manipulate the parent objects which have declared those traits.

     

    One regard where Traits or Mixins differ from Interfaces is that Traits and Mixins define implementations, rather than just interface and contract definitions.

     

    The main motivations pushing for Traits or Mixins in LVOOP are all tied to developer productivity and mental well-being. Conceptually, it can make systems easier to synthesize by providing more accurate maps to mental models, and the logistics of maintaining codebases is substantially reduced (since we agree, codebases are a liability, not an asset).

  12. I actually came here to look for answers (and possibly post a question) related to this very thing. I found myself moving methods around to try and get them into a common place which made sense (to no avail). Ironic that this is the first thread in the OO section right now. Just putting in my $0.02 that you're not the only one feeling this way.

     

    Yeah, the important thing to realize here is that you're not incompetent; your LVOOP toolchain just makes you feel incompetent.

     

    Without a background in Python or Java or C++ or Ruby or PHP or Scala or ... -- with only a background with LVOOP -- you're not necessarily going to realize the root of the problem modeling systems.

     

    This is me; I learned OO on the LVOOP platform. Since, I'm studying elsewhere to diagnose my lack of productivity and lack of confidence in my designs using LVOOP.

     

    This is not a slam against current LVOOP; I'm all about continuous improvement and kaizen and working toward better toolchains and systems; it's important we continue funneling positive energy toward improving LVOOP. Other wildly popular languages are still continuing to develop and release new OO (and generally, core language) features today and over teh past years, and it's important to encourage LabVIEW to do the same!

  13. (Thanks, Steen, for the heads up to this thread :-] )

     

    Here's a quote from another conversation that relates to this thread:

     

    JackDunaway wrote:

    I've long considered myself insufficiently-talented to design object models [in LabVIEW] that "feel right". Bouncing methods and fields to-and-fro between classes -- waffling over inheritance vs composition to correctly model application domains -- i was displeased with myself and my work at the end of each day for still not getting it right (have you ever felt this way?)....

     

    Until a relatively recent realization -- many, many of my application domains simply cannot be modeled with the currently-insufficiently-expressive LVOOP language features. Class Mixins seem to resolve much of my heartache (though, i could probably be convinced of Traits or Interfaces)... (I suggest this makes LVOOP and other LabVIEW OOP APIs easier to comprehend for new users and be developed by advanced users, simply because the implementation mentally maps to the physical domain. The main motivation here is re-use; pain points include unsustainable proliferation of proxy methods)

     

    tl;dr -- you've got an application domain where neither inheritance nor composition is the correct re-use pattern.

     

    Using LVOOP today, I would tend to take drjdpowell's advice of inheritance as far as you can without breaking the map between the object model and your domain -- this might get you a little ways down the road of pushing common methods/fields up the hierarchy.

     

    Then, take shoneill's advice of composition. You'll have some grunt-work writing proxy wrappers to the methods you have composed in each of the subclasses (consequentially, introducing overhead and points of brittleness between the interfaces of wrapper and wrappee).

     

    Finally, take a tissue to those (manly) tears you've shed over your lack of Traits or Mixins or similarly-sufficient LVOOP facilities to express your application domain. Have a bourbon. Sleep peacefully with your system "that'll do just fine". Dream wistfully of What Can Be.

     

    (By the way, you mention Multiple Inheritance, I mention Mixins and Traits -- naturally we must toss Interfaces into the mix -- no need for us to get caught up in semantics and differences between these, further than to agree collectively we gotta have something. Once it's on the docket with a budget for the next LabVIEW release, let's dive into the nitty-gritty of which makes the most sense for our language)

  14. I am not sure I would want to support the idea of eliminating the FP from sub-vis.... That is one of the best things about LabVIEW that text based languages lack.  So, Jack, if you want to kill off the FP, you need to tell me how to debug my sub-vis just as easily as I can now.

     

    Agree wholeheartedly, and I think this can be done. I'll make it a point to start a new thread on this topic in the next several weeks.

  15. Since there's been a bit of chatter about Front Panel Cleanup -- four years later, I find the desire for a Front Panel Cleanup indicative of a more root desire to just "spend less time creating a functional View for the method interface; I'd rather delegate this task to the IDE and language definition".

     

    I've been thinking the correct way to do this is to allow SubVIs to be created without a Front Panel; instead, integrating the interface UI into the BD itself.

     

    This requires half a dozen small (perhaps, controversial?) steps redefining things like Terminals and ConPanes and Local Variables (spoiler: locals are properly deprecated, since true dataflow has no analogue to a traditional "local variable"), yet could fundamentally improve the mental model of how we perceive the links between VI components and how they represent the composition of logic.

     

    (e.g. -- currently, how would you explain to a beginner how data flows from a diagram to a front panel, and from the ConPane from a FP into a subsequent VI's diagram? the mental model departs quickly from the IDE representation, making LabVIEW a booger to "get")

     

    tl;dr: Front Panel Cleanup is a band-aid for the root problem of SubVIs being required to have Front Panels (no offence to the novice who first suggested this on the LV IdEx)

  16. Functional programming is a thing of beauty.

     

    Agree, wholeheartedly.

     

    I've pined for the past couple years to apply functional programming to all my application domains. A recent realization is functional programming simply just doesn't map to many problem domains. Key business logic such as actuation and user interaction often blows referential transparency (i'm finding that pure functions are better applicable in purely computational domains; personally, I just don't spend much time here).

     

    That said, the quest to eliminate mutable state in hopes of achieving pure functions has, at worst, led to more maintainable code. (Simply -- striving to minimize crossing code boundaries with data, and especially references to data or objects, for all levels of procedural abstractions, down to structures)

     

    I've found functional programming and object-oriented programming (see also "pants-oriented clothing") are just two roughly-orthogonal components to the bigger picture -- service- and actor-oriented programming.

     

    OMG, AQ, Scala; you're right. All this shit does converge to something useful.

    (A CLA Summit that focuses on practical LabVIEW implementations of programming paradigms; that's a CLA Summit I'd go to.)

    • Like 1
×
×
  • Create New...

Important Information

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