Hacker News new | past | comments | ask | show | jobs | submit login

Control flow is hard to describe visually. Think about how often we write conditions and loops.

That said - working with data is an area that lends itself well to visual programming. Data pipelines don’t have branching control flow and So you’ll see some really successful companies in this space.

Alteryx has a $8b market cap. Excel is visual programming as well.

Aren't conditionals and loops easier in visual languages? If you need something to iterate, you just draw a for loop around it. If you need two while loops each doing something concurrently, you just draw two parallel while loops. If you need to conditionally do something, just draw a conditional structure and put code in each condition.

One type of control structure I have not seen a good implementation of is pattern matching. But that doesn't mean it can't exist, and it's also something most text-based languages don't do anyway.

> If you need two while loops each doing something concurrently, you just draw two parallel while loops.

Not quite. You'd need to draw two parallel boxes, each of which is strictly single-entry/single-exit, and draw a while loop in each box. This is because a while loop

     v         +-->[fn]--^
  -->*-->«cond?»           +-->
depicts parallel flows that do not represent stuff being done concurrently! Once you acknowledge that, pattern matching actually becomes easy: just start with a "control flow" pattern and include a conditional choice node with multiple flowlines going out of it, one for each choice in the match statement. You're drawing control flow so it's easy to see that the multiple flowlines represent dispatch, not something happening in parallel.

Here's a picture of what I was talking about:


Now, the two while loops, as shown here, have no dependencies between each other and are indeed processing in parallel. However, there are various mechanisms in LabVIEW to exchange data between the two loops, the most common being queues, in which case they process concurrently.

You can also have a for loop iterating on an array.


In LabVIEW, it's nice because it's trivial to configure the loop iterations to occur in parallel (if there are no dependencies between iterations), using all available cores in the computer.

And by pattern matching I meant something like the pattern matching and type destructuring you find in SML, Ocaml, F#, and Elixir.

Yes, that's really just abstracting away the control flow I was depicting in my simple diagram. It's treating "while" as a higher order function of sorts, with its own input(s) of type "data flow diagram connecting types Xs and Ys". That's the best you can do if your language only really deals in dataflow, as w/ LabVIEW ]. And that's really what leads to the difficulty you mention with pattern matching. Pattern matching on a variant record is inherently a control-flow step, even though destructuring variables in a single variant should clearly be depicted as data flow.

Not sure it's that hard, what about Σ and 𝚷. Branching conditionals are also easy to represent graphically

One of the unappreciated facets of visual languages is precisely the dichotomy between easy dataflow vs easy control flow. Everyone can agree that

  --> [A] --> [B] -->        ------>
represents (1) a simple pipeline (function composition) and (2) a sort of local no-op, but what about more complex representations? Does parallel composition of arrows and boxes represent multiple data inputs/outputs/computations occurring concurrently, or entry/exit points and alternative choices in a sequential process? Is there a natural "split" of flowlines to represent duplication of data, or instead a natural "merge" for converging control flows after a choice? Do looping diagrams represent variable unification and inference of a fixpoint, or the simpler case of a computation recursing on itself, with control jumping back to an earlier point in the program with updated data?

Either of these is a consistent choice in itself, but they don't play well together as part of the same diagram unless rigorously separated.

A different point is that some high-level abstractions do have a fairly natural visual representation. This even includes the "functors" and "monads" that are well-known in FP. In general, one should not be surprised if category-theoretical abstractions turn out to be representable in this way. (Many visual languages actually turn this into a source of confusion, by conflating operations on an atomic piece of data with operations on a stream or sequence of singular data points. A stream is a kind of functor, which is why it (with its peculiar operations) is endowed with a simple representation in dataflow. But there are other functors of interest.)

I've always thought that the best solution for disagreement is to simply try everything and then figure out after the fact what works and what doesn't. I don't think there should just be one visual language, we don't just have one programming language and if we did you could bet it would be something terrible. The biggest hurdle is the implementation of the UI, it's hard to make it usable and a lot harder than just putting characters on lines.

The implementation of the UI could be made generic. Make a UI that allows for playing with boxes and arrows in the usual visual-language-y way, and ultimately outputs a serialized, optimized representation that can be fed to a compiler-like pass. Then the semantics, and the pre-defined components to go with it, can be defined separately.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact