You are viewing archived messages.
Go here to search the history.

John Austin 2024-04-24 06:50:30

Ok, I've been thinking a lot about composable systems recently, and why I don't find visual programming languages like blueprints very flexible. Wrote up a blog post about it. Basically, I think the value graph is a more fundamental primitive for computation than execution graphs. johnaustin.io/articles/2024/composability-designing-a-visual-programming-language

Greg Bylenok 2024-04-24 15:36:21

Just an observation: "value graph" seems analogous to "data flow" in a data flow/control flow sense.

John Austin 2024-04-24 15:53:27

It's similar, but not quite the same. Value graphs are distinct in that a node only ever executes once. It's more akin to a build-graph. Where-as dataflow expects values to be flowing through and nodes have several values over the course of execution.

John Austin 2024-04-24 15:55:29

I've actually been trying to find information about this type of computation, that's not in the context of build system like Bazel, Nix, etc.

For example, if you squint, Git is also a value-graph -- it's a big directed graph where every node holds a single value, which is defined entirely by the node's inputs in a pure way. 🤔

Jeffrey Tao 2024-04-24 16:51:29

Framed another way, a value graph is like ~provenance~ seen in reverse. Usually when we talk about data provenance its from the perspective of understanding the inputs that produced a particular result. A value graph seems more like starting from the inputs and building up to the result.

John Austin 2024-04-24 17:27:38

Yeah! I like that perspective. Merkel trees, for instance, are also value graphs.

John Austin 2024-04-24 17:27:58

Any piece of the value graph is recoverable if you have the required inputs.

Jeffrey Tao 2024-04-24 17:41:26

Hmm, this makes me think about visual programming for computational notebooks. Notebook code tends to be focused on the production of specific outputs, not reusable code. Actually the first thing that comes to mind is Ultimate Plumber: github.com/akavel/up

John Austin 2024-04-24 17:49:21

Cool reference, I haven't seen that!

John Austin 2024-04-24 17:50:00

Yeah, many notebooks are just fancy build graphs for data. Very much a value graph. 🙂

Marek Rogalski 2024-04-25 06:23:28

IIUC UE Blueprints, which are used as an example of execution graph, are not composable because they force the designer to sequence the nodes. (This is a really cool observation!) Is it possible that Unreal Engine Blueprints are just missing the operations to split & merge signals? I don't know UE well enough but it doesn't seem like a fundamental issue with execution graphs. Am I missing something?

John Austin 2024-04-25 06:32:41

There are operations to split and merge execution wires, such as branch (a split), but the key is there is no split operation for an execution wire that retains the program semantics. A branch semantically changes the program (because it only takes one or the other).

John Austin 2024-04-25 06:32:57

The only semantically sensible "split" operation for an execution wire is to run the nodes in parallel, but that comes with other issues.

Dany 2024-04-26 05:48:00

Miqula also has value graphs. When I started coding it, I didn't even know blueprints had "execution" wires, how could one do such a hideous thing! To split the execution, I use subnets, for example in a condition, one for true and one that is executed for false. That doesn't solve all problems though, if one would do for example

foo != nullptr ->

foo->IsValid() ->

-> both connected to an && node

you don't need to do subnets, it just does the most sensible thing.

As for side effects, a "regular graph" has none, except assertions (exceptions). To do effects on the world, I use a behavior tree (which is nicely composable). The leaf nodes have regular graphs, which then may contain nodes with side effects (for example to send messages / spawn objects).

Be aware that dataflow programming (with pure functions) is a different model. Most people are used to do the "little robot in your head" that does stuff, one after the other (which is procedural programming). In dataflow, you are wiring dependencies / data together to create new data. You look at the data instead of the instruction.

I'm curious as how you want to design around these problems and how it fit's into an ECS.

Greg Bylenok 2024-04-25 16:28:00

Does anyone else think of "configuring" as distinct from "programming"? Some activities I consider "configuring" and not "programming": much devops work such as Terraform, YML files for build pipelines, even commonly labeled "programming" of a VCR/DVR.

Greg Bylenok 2024-04-25 16:30:00

This question prompted by latest FoC podcast. Maybe my distinction is not academically interesting. But personally, I find "configuring" activities inherently unsatisfying, while "programming" demands enough creativity to keep me interested.

Jimmy Miller 2024-04-25 16:46:16

I think many times the distinction for me ends up being a matter of interface. I feel much more like I’m programming when doing the CDK vs doing Cloudformation. Yet, I’m accomplishing the same task. I don’t think it is because one is TS and one yaml, but the kinds of concepts I have to think about and the ability to build abstractions.

Configuration, to me, ends up being a fill in the blank rather than a crafting. It’s like painting by numbers. Even though in the cdk, I am given a bunch of material to work with, and constraints on it, I still get to put that material together. I still can look at how it was implemented, I can still tear it apart and do something different. I can’t with configuration. I’m stuck listing details I don’t want to list.

I definitely find all configuration tasks deeply unsatisfying and it’s one of the things I don’t like about “low code” tools as they are generally made. They are just configuration. No way to dive in, no way to remix, to take parts apart and make them do something new.

Greg Bylenok 2024-04-25 16:59:47

Yes! This relates to the very end of the episode, where (if I interpret correctly) Ivan imagines a world where general purpose programming languages are replaced (or supplanted) by domain-specific tooling. To reach that point, it seems we need to constrain the problem space to the point where the activity of programming becomes less interesting. Maybe I focus my attention elsewhere, though, to the output of the activity rather than the activity itself.

Another small distinction in my mind is the addition of boolean logic and branching. I know, there are plenty of programming languages that don't involve branching. I know I shouldn't be constraining myself to the Von Neumann architecture. Still, branching offers freedom that makes the activity of programming more intellectually interesting.

Stefan Lesser 2024-04-25 17:10:55

My naive distinction between programming and configuration is that the former is specifying dynamic behavior of a system while the latter is providing initial values to it.

Jimmy Miller 2024-04-25 21:40:40

For what it’s worth Ivan’s definition of domain specific includes things like Elm. So I’d assume he’d imagine not a less powerful setup, but a tailor made approach. I definitely think there is a danger in going the direction of configuration though.

Justin Janes 2024-04-25 21:44:18

Sounds like Racket Lang could be a solid bet if they can withstand the elites knocking performance and distribution issues out. I do know someone was playing with emitting web assembly from Racket for distribution and runtimes.

Dany 2024-04-26 06:23:12

I see it the same way as Stefan Lesser. The configuration is declarative programming that defines constant values (like HTML / CSS..). I think a PL should be able to do both (and distinguish between the two). You can have branching in a declarative PL, but it will be resolved at compile time.

One could argue that an executable is also a "constant", so all programming is configuration, but I think the difference is that the interactions are defined in the executable, if you have a constant, they are defined in the player.

My last blog post touches on this.

Tak Tran 2024-04-26 07:34:53

I agree with Jimmy Miller in that it’s all about the interface. Configuration done badly, feels like bureaucracy eg, filling in a tax form - you don’t know what to put in a lot of the times and it’s very tedious. Yaml/Json interfaces encourage this type of interface. When designed well, it’s part of the system eg, games that make you “configure” the game by playing the game

Stephen De Gabrielle 2024-04-26 13:45:31

Ivan imagines a world where general purpose programming languages are replaced (or supplanted) by domain-specific tooling.

In some ways I think we are already there: javascript on the client, backend in C/C++/java/Python/C# etc. Shell scripting for OS, YML for build pipelines.

In other ways, we are a long way off. An example:

  • say you are a nurse manager running a new service you have staff you know the laws relating to healthcare provision, safety, there are agree services, metrics and tariffs. How do you do this? what you do is run it on a bunch of spreadsheets. Why - even low code tools require you to bring in a consultant to get it working acceptably - if you are running a large service that is widespread you may eventually put together a business case to procure a system. (assuming there is a vendor for what your need). When the service winds down that patient information is lost.
Stephen De Gabrielle 2024-04-26 13:46:56

there are limited options for professionals who are not programmers to get systems that do what they need. Current low code systems come with a bunch of compromises and assumptions they may cost more than they are worth.

Greg Bylenok 2024-04-26 13:56:13

Another potential distinction here, from the discussion above: some freedom to define relationships between different parts of the program. If we lock the user into a pre-defined schema with pre-defined relationships, then we fall squarely on the side of "configuration".

Stephen De Gabrielle 2024-04-26 13:56:48

Sounds like Racket Lang could be a solid bet if they can withstand the elites knocking performance and distribution issues out.

Racket is interesting because the metaprogramming facilities open the doors to building a wider variety of programming languages.

The performance question is interesting, because Racket has excellent performance, but it isn't a system programming language like Rust or C++ - and doesn't pretend to be.

So you wouldn't run Racket on a large scale - but DSL's for professionals - the machines they use are mostly idle - the size and speed of the Racket is just not noticeable.

What is missing is DSL's(future of coding!) that support the needs of the users.

Racket has tools to help make those DSL's (as do many other languages) - but the DSL's for non-programmers don't exist yet.

Stephen De Gabrielle 2024-04-26 14:36:47

Some of the most interesting programmers I can think of are from other professions. I know a number of doctors who were licensed professionals with years of experience who taught themselves to program to solve problems that mattered to them. (I'll acknowledge survivor bias because I only know ones who succeeded.)

As programmers they are quite varied, but unlike a professional programmer, designing DSL's to suit their professional needs never occurred to them.

Ivan Chebykin 2024-04-26 20:43:42

Hi everyone, I'm currently trying to think of ways to improve OpenAPI developer experience, can someone check out the design doc for a simplified OpenAPI generator: chebykin.org/posts/openapic

Dennis Hansen 2024-04-27 20:34:10

Random thought/question. I've noticed canvas based design tools have converged on a panel configuration of "Layers | Canvas | Properties | (and sometimes Timeline)"-- as opposed solving the underlying needs another way. Is this pattern the end-all-be-all? Or a local maxima? I tend to think the later.

Stefan Lesser 2024-04-27 21:20:02

I like to think most of how we do programming/computing these days is stuck in local maxima. It becomes the end-all-be-all because it’s too difficult, risky, and takes too much effort to reinvent lower levels of the stack to leap elsewhere in the solution space.

And the incentive structures we have in place focus on short term value extraction, which favors innovation at the edges, ie. “Let’s see what we can do with this” instead of “Is this the right approach? Do we need to rethink it?”

Generally speaking, if it works, the odds are more in your favor if you use it to invent something new on top of it where you get to define your own category instead of investing your time trying to invent something better that has to compete in an established category.

Personally I think there is a lot of interesting concepts from cognitive science on how we think, categorize, and mentally model interactions with embodied and enacted cognition that would be super useful for designers and developers in the design tools space to utilize, but that’s a whole different domain and once you’re in the “let’s build stuff, throw it at the wall and see what sticks” mode it’s hard to make room for exploring such ideas as it will take some time to make the connections to software design, which cognitive scientists naturally don’t care about.

Dennis Hansen 2024-04-27 22:13:44

Thanks for the response. I agree. Taking the time to design the primitives 'right' rather than doing anything immediately useful is very risky- not just financially but socially, emotionally, psychologically, etc. I get the idea of turning towards more immediate utility. But like the frustration of being stuck in paradigms like the layer/canvas/properties and many others is a persistent driving force for probably most of us here. I agree that it be worth it if new categories are created- but the vision is sufficiently unclear that unless one enjoys the road they risk suffering with no reward.

Also, I do agree with your personal anecdote. I believe any generalize software primitives that can give rise to new categories would emerge fundamentally directly properties of human cognition (spacial reasoning, categorization, etc). I find asking myself "How would I most like to design X" gets me closer to that.

At the end of the day progress will be made when people are dead-set on making it.

Ivan Reese 2024-04-28 00:11:14

In the interest of finding a root cause beyond just "it's a local maximum", can you list every app that comes to mind when thinking of this convergence? Like, don't go looking for more examples, just name all the ones that are already top of mind for you. (I have a hunch.)

Ivan Reese 2024-04-28 00:13:11

(Just to avoid making you feel like I'm setting you up — I want to understand what you mean when you say "canvas-based design tools")

Arvind Thyagarajan 2024-04-28 00:17:09

The no/lowcode shelf -- webflow, wix (etc) bubble, adalo, softr, glide (etc), builder, bildr, sketch, Figma (etc), framer x, a few more I can picture but can't immediately name

Dennis Hansen 2024-04-28 00:20:56

Was mostly newer tools that seem promising and marry a wider array of digital creation functionality. Lots of time they look like a “Figma for X”: Plasticity (CAD), Fable, Vectary, Spline, Modyfi, Rive*

Dennis Hansen 2024-04-28 00:21:37

@Arvind Thyagarajan no-code stuff also are big ones that fit the mold- tho perhaps less “canvas based” per-se*

Arvind Thyagarajan 2024-04-28 00:33:25

I get the feeling this thread is relevant:

đź’¬ #thinking-together@2024-03-09T10:29:03.296Z

It's about designing the right "physics" for the task, and I do think the local maxima you described stopped short somewhere. They give you final design but not interstitials and states or the temporality that connects these things, or they might give you actionability, even predicate based sequences, but no crafting of complex branching logic, for example.

Disclosure: I'm a node-wire live-prog buff. I thought Yahoo Pipes was the cats whiskers way back when. And today I know we can do even better (I'm working on it!)

[March 9th, 2024 2:29 AM] jimkyndemeyer: Software products are physical products. That's why they're hard to design and engineer!

The physicality of software is kept at arms-length in a vector-based design tool. Here, the strength and focus is on surface level aesthetics and exploration though mocks — many, many mocks. All needed. All useful. But a mock does not a product make. A mock is an incomplete story of software physics. Which brings us the other side of the spectrum...

The IDEs — the code editors. The product you ship is here, so "I guess someone has to go there". First challenge: To most people it's walls of inexplicable symbols and weird (even hostile?) punctuation. Then, with code, you're essentially play-acting as a computer. You have to "speak computer" fluently to feel at home here. It's a love/hate relationship of running programs in your head. Mostly failing to do so. Then learning to get better at debugging. Eureka moments of finally solving the puzzle that unlocks a bugfix! Endlessly restarting programs to reset state. Today, even after multiple decades of investment in IDEs, coding is still 100 times harder and less fun than it should be! How can we truly move the needle?

A traditional IDE deals with the how to fully describe the physics of a software system. Writing and editing algorithms. Managing data flows. Figuring out logic. Painting pixels. Sending data at the speed of light over the network. But the IDE doesn't actually let you see the program as it manifests to the user in the final medium. It's running somewhere else — the browser, on your phone. This is where vector-tools have the IDEs at least partially beat. Yes, they're just mocks, but the vector-tool tool sees the mocks alongside you. This changes your relationship with the tool. Thinking and touching — moving, dragging, scaling, rotating, duplicating — seamlessly blends on a canvas, and it just feels good, even fun! IDEs and editing code as text offers none of those things with today's tools, and it just feels like... friction!

So the letter to Santa reads as follows:

Dear Santa, give me the best parts of a vector-based design tool, plus the best parts of an IDE, rolled into one — but with none of the downsides. Thanks!

Christmas can't get here fast enough.

Dennis Hansen 2024-04-28 04:31:22

Great thread. Never heard of yahoo pipes- very cool. I agree that the “what are the new physics” is the right question to be asking. To be honest- I think the canvas is the right approach because it really just means a physical space. Like as if you are god, starting with a canvas is saying “let there be light”. To me, everything can and should be derived from the physicality of the canvas, even panels like layers and properties (if they are needed at all!). If the primitive elements on the canvas are flexible enough, you could compose node-wire type software- but with more flexibility on how it operates, naturally.

Arvind Thyagarajan 2024-04-28 14:50:33

Yes! In fact, I think the node-wire paradigm naturally exists in an infinite canvas almost by definition, you have various node primitives you can add to the canvas, position, and inter-link and there's physics in the linkage (data flow, action sequences, temporality, nesting, 2D position etc.)

What I can't (haven't) wrapped my head around yet is how we'd design a higher order node-wire paradigm (in all the complexity it deserves) into the blank canvas using even lower order canvas-based primitives/physics! Right now I'm working with a node-wire live programming infinite canvas as the base layer, underneath which is ye olde textual code

(OK, I shalln't mention node-wire again for fear of sidetracking a thread about the future of canvas)

Dennis Hansen 2024-04-28 15:04:45

No I think you brought up a great point actually about the need to find a higher order representation (between node wire and code) and to be honest I think you answered you question with what you said in the first paragraph: “add to the canvas, position and interlink”. It’s my hypothesis that enabling the addition of any kind of object (numbers, text, geometry with dimensions) and linking them directly on the canvas might enable just that. If you add the ability to toggle visibility as a property and toggle links on and off themselves and add some form of dynamic repetition I believe you can make anything (though there’s a lot of nuance i haven’t quite figured out). Obligatory ~I have no idea if this will actually work~ tag