-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Flow-control concept #7
Comments
I did a first very hacky approach in "flow_control_delay.pn". This might be a way to go BUT also produces non-trivial side effects: notice 1 field gets updated immediately, the other 2 NOT even though 1 of it should. Think this is related to the nodes list order. |
I think the update frequency should be factored out/customizable, so that people can choose when to update. One thing (possibly only a tangent) I think would be very useful, if pyno could automatically create nodes by wrapping existing functions from a given module (doing some signature analysis on the way, possibly relying on typing information). |
Am 6. November 2018 16:42:55 MEZ schrieb Christoph Buchner <notifications@github.com>:
The bigger aim here being to make something similar to
[LabView](http://www.ni.com/labview), just with Python.
Flow control as I understand it (maybe badly) should be automatic/user
invisible, from inputs to outputs. I don't know how e.g. vvvv handles
this internally when there are several inputs.
Flow control in LabView is NOT invisible. The opposite is the case it is actually THE reason for most strange constructs like reference variables passed in and out e.g. file read write blocks or using sequences by just passing variables in and out not doing anything to them, etc.
Have a look a the delay block I mentioned before - it uses one of these LabView techniques... ;)
One thing (possibly only a tangent) I think would be very useful, if
pyno could automatically create nodes by wrapping existing functions
from a given module (doing some signature analysis on the way, possibly
relying on typing information).
This way, it would be easy to build up a node library, e.g. from python
builtins, numpy functions, etc., without having to write them all
yourself. Imagine e.g. being able to just use `numpy.sin`. Probably
some blacklist or somesuch will be necessary to reject functions that
won't work, as the dynamic nature of Python (especially on the return
type) will make it quite difficult to do this reliably.
I was thinking the same, but changed my mind for the moment as this is quite some work for doing and maintaining and in the end the one block you need will for sure still be missing (murphys law). Everybody can build and share subs or collections of subs already e.g. on github (like Icestudio).
|
Ok, so maybe I don't exactly understand what is meant with flow control. I'll take a look at the delay block. Being able to wrap existing python callables (or objects in case of fields) does not mean you can't write your own code where needed! it just means you won't have to implement half the python stdlib or numpy functions before you even get started, and code reuse would be much better (e.g. of other functions you have written before). Also, it would enable you to just call() the callable instead of having to go through eval and friends. But I'll grant you, doing a reliable analysis to determine the set of arguments and returns could be hairy. |
Also, speaking from personal experience, node-based languages are full of strange constructs if you come from text-based programming. I'm happy that I groked vvvv after a while so that I used it for several years, it was overall an awesome experience! |
I don't used vvvv - I used LabView quite lot some years back (v4, v6 to 8, 9 may be up to 2013). Comming from LabView I would say using Pyno on the level std funcs would need e.g. better wire or connection draw facilities (like on schematic or PCB CAD tools as mentioned in #3 (comment)). For now I am quite comfortable with the higher level character using multiple std funcs in one single node, makes the design a bit more abstract and may be better understandable. Of course reuse is bit more of a problem. Finally Pyno should have all you propose I agree on that actually! This is of course just my opinion. As said thanks to the new subs you can already start wrap your favourite std func in "blocks" and share them e.g. via github. There is nothing stopping you from doing that. I think @honix would even include them into this repo if you issue a pull request - but that is just a guess. ;) |
About dataflow I can say that LabView has lot of beautiful tools and tricks but most of them include having to introduce new elements and LV ended up having so many that basically everything can be done in several different ways. I don't think this is where Pyno should end up - we should keep everything as simple as possible and only make it as complex as needed. That is why I started experimenting with the delay example. |
So, im doing some work in separate branch. Subjects of change:
Any node now will have So you can use more than one function and bind main function to def helper(a, b):
return a + b
def add(a=0, b=0):
result = helper(a, b)
return result
call = add It can be lambda expression: call = lambda x: x Or make fast bindings to libraries (only pure functions for now, maybe methods later): import calendar
call = calendar.isleap Bad news is that i drop function tuple return separation, as really function returns only one value, and separation of tuples is only syntactic sugar. Almost all examples used multiple return values is broken now. |
We can try to reflect return type notation to restore multiple returns feature. def process(response: int) -> Tuple[int, str]: |
Can you elaborate a bit what's the reasoning behind these changes? What about supporting the old "single function" node as well - just having both (in the same element)? |
This way is little more explicit to user. We want to take user function, but dont know what to take. Let user make this step. Also it more adaptive to foreign functions. User will not make wrapper, but just bind needed function to And techinically this is most "okay-ish" way to do pythonic reflection. Just take what we waiting from user, read signature, and make node representation. upd: It is possible to auto-bind function if there is just one user function. But it is little lack of consistency i think. |
Progress report. I done with type exctraction 8e78777. Here is screens. Multiple return values using type annotation: Usual tuple outputs as tuple itself: It is really one way to do it properly and it is. How do you think guys? |
Looks great! Did not think it would be so "easy"/fast to do what I suggested. :-O |
That would allow whole python script in one single node. Interesting. I'm not familiar with reflection (even though I learn from wiki I was already using it before ;) or return type notation of python. What about the scope? Is the import or are the helper functions available in other nodes too? I the old mode could be supported along the new it would keep compatibility with old code... (however honestly to say there are not too many progs out there to modify). Or use a default wapper to make the old code compatible with the new node? |
@drtrigon scope is node closed. I think it is good for bunch of reasons. First of all node's code becomes self-contained and everything-with-me. Yes, i considering to modify old patches. There is some breaking-rules changes. Maybe it is not all of them. |
I think node closed scope makes sense. About compatibility with old nodes and pyno-files, basically if you get code w/o
just add The other thing I am reasoning about is whether |
LabView Dataflow Programming Basics: http://www.ni.com/getting-started/labview-basics/dataflow Just found that document - this is the language I got used to, may be helpful here. |
Helpful would be naming of node output values, may be from comment? Importing via fields is obsolete now, correct? I implemented the flow control example in new style (pull request will follow) and noticed that it makes more sense now, but the fps are by about a factor 10 lower than they should be given the delay around 1...3 fps (using 0.1s should result in about 10fps, right?). |
Yes, default return names are not helpfull now. I will look for some signature's arguments naming. Nodes is scope closed, nothing to leak in leak out (except G['item'] for globals). Field can import something if it used in this field (inter-field will work too i belive). Fps may show wrong. Need to check. |
Thanks for LabView link! |
Return naming is possible now! d53ec7c |
@drtrigon yes, self pin is the way i want to do it. Node will have self pin, which is pointer to the node. Then we can query node to execution by for example Need to check it for theoretical errors. |
Does executing in parallel mean mutli-threaded? As this could end up in hundreds of threads running in parallel when comming to subs containing other subs etc. |
In the end, i think your patch/collection will have to form a Directed Acyclic Graph. You should be able to use some graph theory package like networkx to easily obtain an ordered representation of the nodes in your patch. This you can then process in turn (and in parallel where proper, e.g. with concurrent futures and friends). If you get cycles, you have to break those up with a delay-by-one-step node (cf. vvvv). |
I have to correct myself, LV also works in parallel, see "clumps": NI LabVIEW Compiler: Under the Hood: http://www.ni.com/tutorial/11472/en/#toc3 |
Hi. For the last year I've been exploring visual-programming for real practical applications. My initial idea is to give DeepFaceLive (https://github.com/iperov/DeepFaceLive) users the ability to modify the logic of program nodes interactively, without resorting to source code. The conclusions I came to are:
Therefore, the nodes should be interactively programmable in a lightweight language like python.
A node system that has a fixed pipeline and has fixed views for users, such as buttons, text and numeric fields, is not difficult to implement. Conclusion. Is it possible to design such a general-purpose node system that would be both intuitive for the user Or is it just fundamentally impossible? |
@iperov welcome! My thought is that visual programming is good for simple tasks, realtime interactive systems. Like it's good for searching right combination of nodes to get the effect you need. But it almost always is about combination a to b, a to c to b, and because of that it limited to such simple tasks. It is good for realtime, because almost any state of your nodes on canvas is syntactically correct, so you can iterate freely. Sometimes you don't understand the logic, but love the effect. To contrast with textual programming, the last has more ways to connect things. It is harder to write in textual, but expressiveness is better. It's kind of combination too, but the size of possibilities is huge. Text is always abstraction, and you must learn a language to recognize and use its forms and relations, while visual things is limited by links and nodes, that way one can express only primitive constructs. As you mention, when we try to make visual language low level-ish, it become spaggeti pretty fast. Text is compact and it usually hides complex semantics, when visual thing usually don't work with semantics well because of like more physical approach of arranging words. This is why I'm no longer a visual evangelist. I still love the systems like vvvv. When I just started to program, this thing was like mind blowing, because of fast iteration cycle and great premade examples anyone can modify. But text has a cypher in it, and it is it's great power, that allows one to insert in it almost any semantics you need. |
Im considering to develop flow-control mechanics for pyno.
Right now pyno do the update of all nodes 60 times per second. It is good for real-time systems, but bad for other classes of programs, for example calculator. It is also a waste of processor time.
This aproach also seen in vvvv visual language. It also reminds me functional nature of algorithms. In some cases it seems more natural to just define operators, put some data and dynamicly (!) see the process. Dynamic nature is one of main goals of pyno.
Another approach is flow-control - the way to execute nodes in order you need. It will allow to do condition branches and loops (can be main loop done this way?).
Examples is UnrealEngine's blueprints, cables.gl and VL from vvvv guys.
They differently solve this concept. I mostly like cables.gl approach, it bulds around signal concept as i understand it. There is signal and data wires. Signal wire activates execution of node. The semantics of signal wire may vary from node to node.
My goal is to do easy to understand but powerfull flow-control concept, so pyno will be used for broader classes of programming.
Ideas are welcome.
The text was updated successfully, but these errors were encountered: