[HN Gopher] Pyflow - Visual and modular block programming in Python
       ___________________________________________________________________
        
       Pyflow - Visual and modular block programming in Python
        
       Author : amai
       Score  : 141 points
       Date   : 2022-01-31 16:44 UTC (6 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | tekacs wrote:
       | Another attempt in this space recently is https://natto.dev, by
       | Paul Shen (https://twitter.com/_paulshen).
       | 
       | It's a really interesting platform and his Twitter feed shows you
       | all sorts of interesting and innovative uses he's making of it so
       | far!
       | 
       | See this previous HN thread on the topic (though it's evolved
       | quite a bit since!) --
       | https://news.ycombinator.com/item?id=26790285
        
         | mrits wrote:
         | I worked on something very similar for my company about 10
         | years ago. The lesson I learned is it was much more robust to
         | have a flow of data than a flow of code. I still think it's
         | really cool though.
        
       | realitysballs wrote:
       | It's like the grasshopper of Python
        
       | dang wrote:
       | Is this different from
       | 
       |  _PyFlow - Visual scripting framework for Python - NodeRED
       | alternative?_ - https://news.ycombinator.com/item?id=29955623 -
       | Jan 2022 (53 comments)
       | 
       | ?
        
         | _joel wrote:
         | Looks like it. I thought I'd heard the name before...
        
         | punnerud wrote:
         | Not the same. This post is to a git-repo with active
         | development, compared to the first post where the last commit
         | was more than two years ago.
         | 
         | Both about PyFlow, but the first one should probably not be
         | used. They also changed the license from Apache 2.0 to GPL-3.0
         | (probably a smart move).
         | 
         | That make this post deserve some time on HN. Glad that someone
         | is breathing fresh air into the project.
        
         | detaro wrote:
         | yes, appears to be an independent project, started after the
         | one you linked petered out.
        
           | dang wrote:
           | Thanks!
        
       | spywaregorilla wrote:
       | I love blueprints in ue4, but I think I don't like the look of
       | this. It's weird to me that each node seems to be an arbitrary
       | block of code. I've long wished for such a feature in unreal's
       | blueprint visual programming language. However, I wouldn't want
       | it to be the default. That kind of undermines the point of it
       | all.
       | 
       | I would want 99% of nodes to be single function calls.
        
         | lgessler wrote:
         | It makes more sense when you consider that this seems to be
         | intended as an alternative to (Jupyter, etc.) notebooks, which
         | are a major way of communicating methods in the data science
         | segment of the Python community. Notebooks are linear sequences
         | of cells with an arbitrary number of lines of code inside of
         | them, and these cells can be executed one at a time in
         | arbitrary order. A lot of the time the dependencies between
         | these cells (whether it be conceptually, programmatically,
         | etc.) is not linear. There therefore arises a lot of cognitive
         | load in both trying to present (via comments, etc.) this
         | structure as a writer and parse this structure as a reader.
         | 
         | I imagine that is the kind of problem this is meant to solve--
         | drawing out and visually solidifying that structure. From this
         | perspective, I'm not sure if there's much apparent value in
         | making the 1 cell <==> 1 function call constraint the default.
        
       | TruthWillHurt wrote:
       | Cool. Now the question is where does it run, and can we split
       | blocks to serverless functions, or have a "cluster-mode" where
       | each block can be executed on dedicated/specialized/available
       | node.
        
       | agumonkey wrote:
       | It's surprising how the lazy node graph thing is spreading. I
       | find it a superb model for most things (and, broken record
       | moment: sidefx houdini or alias maya can show you how far one can
       | go in this model. hint: james webb far).
        
         | moritonal wrote:
         | Lazy is an odd choice of words? Lazy normally means that the
         | data is only derived when needed, but most graph models work by
         | pushing data wrapped as events through pipes?
        
           | agumonkey wrote:
           | fair point but if you only push what's changed, isn't it lazy
           | ?
        
             | throwaway17_17 wrote:
             | 'Push what's changed' is not a typical description of
             | 'lazy' evaluation. As was said in a sibling comment, lazy
             | is more of a demand-driven evaluation. However, I think you
             | are more likely leaning into describing reactive
             | programming paradigms. the description in parent is not
             | exactly describing reactive, but it is certainly in the
             | 'wheelhouse' of reactive programming. Typically, node based
             | compositing is definitely reactive, and is most often lazy
             | as I discuss in a sibling post.
        
         | ReleaseCandidat wrote:
         | And 3D Compositing software like Nuke, Flame, Fusion, ....
         | 
         | And don't forget about Blender!
        
           | agumonkey wrote:
           | yeah all these compositors are from the same era.. it's funny
           | how they all rapidly and naturally converged onto these
           | ergonomics
           | 
           | blender is closing in
        
         | throw10920 wrote:
         | Where does the "lazy" come from? Is that just another way to
         | say that it's a dataflow graph?
        
           | agumonkey wrote:
           | yes, lazy, dataflow, reactive, I wrap all this in the same
           | bag. Am I wrong ?
        
             | chrisseaton wrote:
             | Lazy is usually used to mean demand-driven, as opposed to
             | input-driven, in my experience, so exactly the opposite of
             | this, but different people mean different things. (Did a
             | lot of my PhD on dataflow.)
        
               | agumonkey wrote:
               | These systems are a bit of both though. In compositing,
               | unless you add a final "view" node, IIRC, node
               | computations are not triggered.
        
               | throwaway17_17 wrote:
               | I think, as parent implied, this is more of a semantic
               | issue than any substantial disagreement. You are, in most
               | instances of compositing systems of this style, correct
               | that the computations are typically not triggered unless
               | some view node is utilized. Additionally, if your view
               | node is in the middle of some chain of nodes, only those
               | nodes before the view would actually be performed. This
               | is somewhat similar to the usage of lazy in regards to
               | the operational semantics of programming languages.
               | Again, as parent states, lazy 'evaluation' is basically
               | demand driven computation. Python is not a lazy language,
               | it utilizes eager evaluation by default. So in the sense
               | that Pyflow seems to be a sort-of 'visual
               | programming'/dataflow frontend for Python, I would assume
               | that it is eagerly evaluating the code in the order of
               | dependencies as determined by the graph.
        
               | agumonkey wrote:
               | I assumed pyflow nodes would be "lazish", not the code
               | inside each node
        
               | chrisseaton wrote:
               | People sometimes say 'non-strict' to mean 'can be lazy
               | but not required to be'.
               | 
               | I think Haskell is actually non-strict, and not lazy, for
               | example. It's important because hard to optimise
               | otherwise!
        
               | agumonkey wrote:
               | and you know it got me thinking, languages are trees, and
               | haskell tweaks it into DAG (shared call-by-need) ..
               | evaluated one way, but in the context of UIs you get a
               | larger graph set it seems, where any node can evolve and
               | the consistency of the whole graph needs to be
               | rebalanced. Just thinking out loud.
        
               | chrisseaton wrote:
               | Programs as trees and graphs is a special interest of
               | mine as well https://chrisseaton.com/truffleruby/basic-
               | graal-graphs/.
        
               | agumonkey wrote:
               | Oh man, I'm trying to go back into parsing and
               | compilation (and the usual tree/graph processing) right
               | now. This is pr0n material :)
        
       | howmayiannoyyou wrote:
       | Can you imagine the popularity of a UI component driven version
       | of this (along the lines of hypercard I guess), if web-based? I
       | suspect the market for that would be MUCH bigger.
        
         | riskneutral wrote:
         | Why would web-based ensure a much bigger market? If you have a
         | one-click installation process, then a desktop app seems much
         | more appropriate than a web page for a programming / data
         | analysis tool.
        
           | ReleaseCandidat wrote:
           | Why not have both with a PWA :-D
        
         | halflings wrote:
         | What do you mean by "UI component driven version of this"
         | exactly? Like this, but to build UI components somehow?
         | 
         | FWIW, there are plenty of graph-based dev tools, especially in
         | the data science & ML world, and they seem to only fit the
         | nerdiest of audiences (like mine!) ; not very practical for
         | most people.
        
       | erwincoumans wrote:
       | It looks great. I've been using ImGUI + ImGUI Node Editor for a
       | synthesizer GUI. It should be easy to create Python bindings for
       | that as well. In case someone is interested in such Python
       | bindings, reply or +1. See https://github.com/thedmd/imgui-node-
       | editor and my simple synth GUI here:
       | https://www.youtube.com/watch?v=LPwPJuKbASs
        
       | sdepablos wrote:
       | How it this different from any DAG-centered orchestration tool
       | like Dagster or Prefect?
        
       | dbish wrote:
       | Very unreal engine blueprint-like. I always wondered why that
       | caught on with game engines but (partial) visual programming
       | isn't used by folks pretty much anywhere else besides some
       | introductory programming courses/tutorials or kids projects.
       | Personally, I think the abstractions could be useful for other
       | domains like building/prototyping ML models too but so far no
       | user demand for the tools.
        
         | spywaregorilla wrote:
         | UE blueprints make the game engine api discoverable. Doing low
         | level code in bps sucks. But stringing together engine calls
         | feels good.
         | 
         | edit: basic math is a good example.
         | 
         | (a+b) / c * 3 + 7 is very easy to write out in code, but is
         | going to include the following nodes to express
         | 
         | a
         | 
         | b
         | 
         | +
         | 
         | /
         | 
         | c
         | 
         | *
         | 
         | +
         | 
         | 7
         | 
         | and lines between them to connect data and functions. Gross.
         | Ue4 technically has a mathematical expression node for this
         | specific case but its one of the more painful things without
         | it.
        
           | snarfy wrote:
           | I really wish they'd just bring uscript back.
        
             | spywaregorilla wrote:
             | They're releasing an open source scripting language
             | sometime this year called UnrealVerse to go along with UE5.
        
         | jefurii wrote:
         | There are at least two popular visual programming languages for
         | electronic music: Max/MSP (cycling74.com) and PureData
         | (puredata.info).
        
           | ReleaseCandidat wrote:
           | And Reaktor Core
           | 
           | https://www.native-
           | instruments.com/fileadmin/redaktion_uploa...
           | 
           | and Primary
           | 
           | https://www.native-
           | instruments.com/fileadmin/ni_media/downlo...
        
         | andi999 wrote:
         | Well there is labview with a dataflow model, multithreading use
         | is extremely easy in such a setup.
        
         | seemaze wrote:
         | This form of visual programming has been used in 3D modeling
         | and visualization industries for 15+ years [0-3]. It's an
         | excellent gateway to real programming, but any complexity
         | quickly overwhelms the visual organization of nodes.
         | 
         | [0]https://docs.blender.org/manual/en/2.79/render/blender_rende
         | ... [1]https://www.rhino3d.com/6/new/grasshopper/
         | [2]https://blog.vectorworks.net/what-is-marionette-a-look-at-
         | ve... [3]https://dynamobim.org
        
           | klixto wrote:
           | I have been working in some tutorials for blender/sverchok.
           | In the case if someone is interested. :)
           | 
           | http://www.victorcalixto.xyz/tutorials/sverchok/sverchok
        
       | phailhaus wrote:
       | > Link blocks to highlight dependencies, Pyflow will then
       | automatically run your blocks in the correct order
       | 
       | This is a problem. If you require users to define dependencies
       | for you, they will make mistakes and things will go wrong in ways
       | that are incredibly difficult to debug. This is already a huge
       | pain point with Jupyter notebooks, and they're only one-
       | dimensional!
       | 
       | Have you considered going the route of Observable notebooks [1]?
       | In an Observable notebook, each cell can export at most one
       | variable. This means that the notebook can automatically
       | determine dependencies statically, run cells in the correct
       | order, and even show the user a viz of dependencies.
       | 
       | [1] https://observablehq.com/
        
         | mrtranscendence wrote:
         | Wait, what is it about exporting only one variable at a time
         | that makes it possible to determine dependencies statically?
         | Why not two variables? Or three? If you're determining
         | dependencies based on variable names it seems like that would
         | be possible.
        
           | phailhaus wrote:
           | You're right, it's more due to the fact that Observable
           | requires you to explicitly export variables. However,
           | limiting it to one has a couple advantages:
           | 
           | 1. You don't recalculate other variables if only one needs to
           | update. For example, if a cell exports two variables, and a
           | dependency of _one_ of them updates, you 're forced to re-
           | evaluate the whole cell.
           | 
           | 2. I think the UX plays out simpler if you limit it to one
           | variable. It basically reads like `myVar = {...}` at the top
           | of the cell. It's a bit trickier if you try to support
           | exporting multiple variables at once.
           | 
           | 3. If you find yourself needing to tie several values
           | together, you can still manage it by exporting a single
           | dictionary value!
        
         | brrrrrm wrote:
         | Isn't this readily solved by a user convention such as only
         | updating one variable each cell? Why limit users based on
         | mistakes they haven't made yet?
        
           | phailhaus wrote:
           | User conventions don't work, because there is no mechanism
           | for enforcement other than "hope they remember!" I would say
           | most users don't even know about this convention, given I
           | work in an environment where notebooks are used heavily and
           | have never heard of this. Because these mistakes are allowed
           | to happen silently, they _will_ happen, and it will almost
           | certainly make the code harder to manage.
           | 
           | On top of that, Pyflow seems to rely on the user to define
           | dependencies between blocks as well. This means that the user
           | would have to both perfectly maintain the convention of one-
           | variable-per-block, but _also_ link every block that touches
           | that variable going forward. Without ever making a mistake.
           | It 's such a well-defined graph problem that it's practically
           | _made_ for computers to handle, not fleshy people.
           | 
           | This is why tools are so important: they can impose
           | constraints that allow you to act more freely elsewhere. When
           | I change a cell in Observable or add a reference, I don't
           | have to think. The engine handles dependencies for me,
           | without fail. I can't make an entire class of errors, which
           | means I can just focus on functionality.
        
       | throwamon wrote:
       | This is very close to what I wish ObservableHQ/Pluto.jl had.
       | Their reactive model already allows you to branch off, connect
       | arbitrary nodes and re-run only what's needed, but the visual
       | ordering of the cells is still very inflexible.
        
       | d--b wrote:
       | Shameless plug: Same for Javascript and without the links :-)
       | https://www.jigdev.com
        
       | architectonic wrote:
       | I had worked on such a tool by extending pyqtgraph's flowcharts.
       | Mainly executing the nodes when their input changes and showing a
       | glowing box around the one running at the moment. Flowcharts
       | supports multiple terminals already and I had added some custom
       | nodes. Node execution must be delegated to a background thread so
       | the gui is not blocked while the node executes. Doubleclicking a
       | node shows a window for setting up the node. A custom class of
       | nodes shows upon doubleclicking a simple python editor, upon
       | execution the terminals get automatically the values of the
       | variables carrying the same name as the terminals. It has been a
       | lot of fun. I had used petl and pyspark for lazy loading so one
       | could build large etl workflows.
        
       | tylerl wrote:
       | Does anyone know of a more generalized framework for doing this
       | kind of thing? I'd been meaning to write a framework kind of like
       | this for some time, but never got around to it, and was hoping
       | someone else would. This one unfortunately doesn't really check
       | the important boxes, but it's a good start. I was hoping more
       | for:
       | 
       | * Target language agnostic (this one seems to get mostly there)
       | -- the nodes communicate data/logic flow, you then
       | serialize/deserialize accordingly. * Focus on data flow, not just
       | execution -- IO from nodes, visual indicators of data types
       | (colors or something) * Capable of visually encapsulating
       | complexity -- define flows within flows * Ideally embeddable in
       | web apps (e.g a browser/electron frontend or something)
       | 
       | These are pretty popular to embed in complex "design" oriented
       | applications, especially ones that involve crafting procedures by
       | non-programmers (e.g. artists, data scientists, etc). Examples
       | where this is implemented that come to mind include Blender,
       | Unity, and Unreal.
       | 
       | A core part of the fundamental _design_ of each one of the
       | successful implementations is that they allow efficient code to
       | be crafted by people who don 't think they understand code.
       | Making it visual helps engage the brains of certain kinds of
       | people. The "code as text" paradigm is spatially efficient, but
       | it's like a brick wall for some people.
        
         | jcelerier wrote:
         | Having had to do that quite a few time, for instance for audio
         | / control / visuals graphs in https://ossia.io as well as some
         | proprietary stuff, I'm pretty much convinced now that it's
         | easier to just whip up the graph data structure that fits the
         | problem rather than trying to make a generic framework for
         | that. Every time I tried to use a library of dataflow nodes it
         | ended up not doing what I wanted the way I wanted, and
         | rewriting something tailored to the use case was just much
         | faster especially considering that you likely want user
         | interface features which will be specific to what you are doing
         | with your dataflow graph.
        
         | solarkraft wrote:
         | Hey, same about looking for a generalized framework, but I'd
         | approach it from the other side.
         | 
         | I'm pretty okay with the general shape of code (a nested tree-
         | type structure), but think the possible interactions are
         | unnecessarily awkward by being forced into a text editor.
         | 
         | You ought to be able to effortlessly fold, move around and
         | disable/enable blocks of code. There's not much of a point in
         | allowing indentation or whitespace mistakes and it doesn't
         | usually make much sense to select a part of a token (or often
         | even just a token without the block it's attached to).
         | 
         | These issues can mostly be fixed by representing tokens and
         | lines in a tree-like structure of nodes, for which useful
         | editors already exist.
         | 
         | IDEs try to retrofit these things into their text model (the
         | most advanced one I'm aware of being IntelliJ), with automatic
         | indentation fixing and folding, but even the best attempts
         | aren't even using 20% of the potential.
         | 
         | My most jarring example of how _bad_ IDEs still are at this is
         | folding + disabling (commenting out): When I comment out a
         | block of code because I don 't care about it that is folded
         | because I don't care about it, it shows it back to me even
         | though _I don 't want to see it because I double-don't care
         | about it!_
         | 
         | (Side note: I'm aware XCode doesn't do this, but it's far from
         | general)
         | 
         | There is so much effort put into concepts, parsing and
         | whatever, and everything uses trees, because that's the natural
         | way of reasoning about code. Why are we still stuck interfacing
         | with it through an awkwardly serialized version?
        
         | epilys wrote:
         | There's Google's Blockly: https://developers.google.com/blockly
        
         | javierluraschi wrote:
         | We are working in https://hal9.com which is language agnostic
         | and allows you to compose different programming languages;
         | however, we are focused at the moment at 1D-graphs but have
         | plans to support 2D-graphs in the coming weeks.
         | 
         | If you want a demo or just time to chat, I'm available at
         | javier at hal9.ai.
        
         | dumdumdumdum wrote:
         | https://github.com/msgflo/msgflo + https://app.flowhub.io/
         | 
         | Time is a flat circle. I'm sure this has been attempted
         | countless times before, but it never seems to stick around.
        
         | timroediger wrote:
         | I've been working on a more general framework. Its not public,
         | but I'm happy to chat with anyone who has a specific interest.
         | At present it consists of the following elements: * Language
         | specification - code is stored as json. * Compiler with an
         | interpreter, Javascript, Typescript and Rust backends. * Editor
         | - not quite the classic style node editor. Our new design fixes
         | a lot of the problems and complaints with the old style node
         | editors, particularly information density and spaghetti layout.
         | * Language Server - provides type hints, etc to the editor. *
         | VSCode extension - integrates the editor and compilier into
         | VSC.
         | 
         | Also of note, the language is statically typed, with generics.
         | It handles loops, branches, and functions are first class.
         | Recursion is not supported at present.
         | 
         | In time we also plan to build a LLVM backend, so an
         | intermediate language won't be required. Currently the compiler
         | is written in TS, but as it matures more we intend to make the
         | language compile itself.
         | 
         | If you want to talk, seek me out (I work for Northrop Grumman
         | Australia).
        
       | tda wrote:
       | I am wondering if this could work for async programming. I once
       | used a Discrete Event Simulation software that had an excellen
       | graph based program editor that really showed the dependencies of
       | the model very clearly. I later realized that Discrete Event
       | Simulation is conceptually very similar to async programming. I
       | would love to explore async programs as an animated graph. Anyone
       | know if such a thing has been tried?
       | 
       | The modelling software I was thinking about is FlexSim by the way
        
         | idealmedtech wrote:
         | LabVIEW uses a graphical language and gives very easy access to
         | parallelism and message-based software architectures, though it
         | can be quite difficult to learn and is plagued by lots of bad
         | existing code. See OpenG [1] for some examples of good code.
         | 
         | [1] - https://www.ni.com/en-us/support/downloads/tools-
         | network/dow...
        
       | raintrees wrote:
       | As a past user of Borland's ObjectVision, I would appreciate
       | seeing this project developed far further... Similar to the
       | Mindstorms programming interface, sometimes the object-based
       | modular containment assists with abstraction/black box thinking.
        
       | dukeofdoom wrote:
       | Recently Embaracedero (formerly Borland) released "Delphi for
       | Python" allowing you use their visual tools with python too.
        
       | mrlinx wrote:
       | How well does it handle web-requests to the outside?
        
       | brrrrrm wrote:
       | I like that this is basically Jupyter/Colab extended with an
       | explicit cell dependence graph.
       | 
       | However, I think this needs some serious brand work to
       | distinguish it from "visual programming," which multiple
       | commenters have already confused it for.
        
         | throwaway17_17 wrote:
         | Can you explain how this is not 'visual programming'? The
         | interface seemingly allows for arbitrary code to be written and
         | then graphically arranged in a dataflow-like format. If you
         | mean that the fundamental elements of 'code' are the text
         | inside each block, how is that fundamentally different than if
         | each block was a black-box whose functionality was implemented
         | using more blocks?
        
           | brrrrrm wrote:
           | The emphasis of this project seems to be text based coding
           | and visual description of dependencies at the cell level.
           | Visual programming, at least according to wikipedia, refers
           | to "manipulating program elements graphically rather than by
           | specifying them textually," which this project does not do.
        
             | throwaway17_17 wrote:
             | Not really in disagreement. However, I think that there is
             | more than one level of granularity to this project. If you
             | were to step back to the level where someone has a
             | 'library' of these blocks of code (which seem to be able to
             | present a 'black-box' style presentation) and then visually
             | placing them and connecting the inputs and outputs of those
             | various blocks is essentially visual programming within the
             | meaning of the standard definition, like from Wikipedia.
        
             | zozbot234 wrote:
             | Dependency relations are very much "program elements".
        
       ___________________________________________________________________
       (page generated 2022-01-31 23:00 UTC)