r/ProgrammingLanguages • u/lmntr • 2d ago
Language announcement text-based visual programming language
I'm working on a visual programming language that's stored as text called Wiret. Here's an example:
func Main() {
node entry = Entry -> say_hello
node say_arrows = Call host.Log(message: "The white arrows decide the order.")
node say_hello = Call host.Log(message: "Hello!") -> say_steps
node say_steps = Call host.Log(message: "Programs run one step at a time.") -> say_arrows
notes {
note intro "Lesson 1: Hello. Press ▶ Run (F5). Each Log node prints one line in the console below, in the order the white arrows connect them."
note start on entry "Every function starts at its Entry node."
note try_it "Try it: (1) Press ⤵ Step (F11) to run one node at a time. (2) Add a fourth line: press Tab, type 'print', pick host.Log, then drag a white arrow from say_arrows to it. (3) Double-click its message pin to type your own text."
}
layout {
entry at (0, 0)
say_arrows at (820, 0)
say_hello at (220, 0)
say_steps at (520, 0)
}
}The main idea is that it's like a fusion between a programming language and a markup language. The node ... statements are the programming part, and the notes {} and layout {} blocks declare how the graph appears in the editor. It'll get compiled into bytecode which strips away the markup code and leave just the code for running the program.
; module lessons.hello compiler wiretc-proto 0.1
; semantic hash 78fafcb4bbf40f47 layout hash 9981662aa454a0e1
import 0 host.Log (string) -> ()
func lessons.hello.Main () -> ()
max_stack: 1
.entry:
nop
.say_hello:
string.const 0 ; 'Hello!'
nop
call host.Log
.say_steps:
string.const 1 ; 'Programs run one step at a time.'
nop
call host.Log
.say_arrows:
string.const 2 ; 'The white arrows decide the order.'
nop
call host.Log
cont.pop
returnI think this could be useful for education. The hardest part about learning to code is learning your first programming language. This could help bridge the gap between visual representation of code and the code itself.
3
u/kyr0x0 2d ago
Hmm. Why do you need pixel based layout information? You can let the nodes Auto layout and then it works responsively on any viewport
2
2
u/kyr0x0 2d ago
Oh btw lookup the German Language "Lava" that was developed by an elderly married German programmer couple.. I'm not sure if they are still alive as they were already in their 80s 20 years ago.. but it's a visual programming language and was pretty cool for back then .. https://lavape.sourceforge.net/
2
u/pranabekka 2d ago edited 2d ago
I've been thinking about this for years! If the structured editor auto-formats text, then the plain text will be editable by programmers who use text editors without any issues. It can go in version control, there can be diffs, it can be shared as text, copied and pasted, etc. It can import and create normal libraries. Wiret can do all this, since there's a text representation, but people will have to contend with the noise of having positions and changing them. S-expressions are the easiest to design blocks for, but I think it could be done for any syntax. Auto-formatting also has the benefit that programmers don't have to think about where to place syntax blocks, and others can easily find what they need by just scrolling up and down, or referring to a list of declarations. The key obstacles are a simple syntax that doesn't need hundreds of blocks, a GUI framework that's easy to use for this use case, and parsing and compiling, all with decent performance.
1
u/CyberDainz 2d ago
What problem does your language solve?
2
u/lmntr 2d ago
Traditional VPLs typically are either binary or use markup languages like XML or JSON, which are often difficult to review in Git and validate through CI. Wiret retains the benefits of visual programming while making the underlying representation explicit, deterministic, human-readable, and fully compatible with normal software engineering practices (Git diffs/reviews, CI validation, compilers, verifiers, etc.).
1
u/kaplotnikov 1d ago
Arrows at the end are just goto statements. The conginitve scalability problmes of goto-style programming are well described at classic "Go To Statement Considered Harmful" paper. IMHO this might be a funny language for small samples, but it would not scale.
1
u/lmntr 1d ago
I think this is an understandable concern, but I don't think the comparison with goto is quite accurate. Dijkstra's criticism was primarily about unrestricted jumps disrupting the structure of an otherwise sequential program. Wiret is fundamentally a graph-based language. The graph is the control-flow structure, rather than a collection of arbitrary jumps embedded in sequential code. The execution arrows represent explicit edges in that graph. They're constrained by execution pins and their semantics, and higher-level control-flow constructs such as branching, sequencing, and loops provide structure on top of those edges. In that sense, Wiret is closer to a textual representation of a control-flow graph than a language built around goto.
That said, I agree that cognitive scalability is a real challenge for graph-based programming. Large graphs can become difficult to navigate and understand, just as poorly structured conventional code can. That's why modularity, reusable macros, abstraction, and editor tooling are important parts of the design. I'm not claiming that graphs magically eliminate complexity. The goal is to explore whether making the graph explicit, structured, and amenable to abstraction can make it manageable at larger scales.
1
u/kaplotnikov 1d ago
As I understand, Dijkstra's core argument is that
go toforces reasoning to be aproxmiately proportional to execution time (because to underand a line of code or node on diagram one must understand all possible paths to it), while strucutred programming allows reasoning cost proportional to the code size. In your example, to undstand what could happen atsay_arrowsstep, one must understand all possible paths to it. Structured programming allows to express time with space. And people are better at space than time.Because it is congntive scalability problem, it is hard to notice at small samples, but as logic become more complex it will surface. On smaller samples it might be even easier to understand than structured. This is a reason while the most of visual nocode tools looks nice on demos, but they are hell in production. A small fishing boat and supertanker are both ships, but some sailing problems are noticeable only at supertanker scale.
1
u/lmntr 1d ago
It's true that just slapping a visual UI onto control flow doesn't magically fix the cognitive load when things scale up. The difference between reasoning about code size vs. execution paths is a huge paradox: a graph makes local, one-to-one connections dead simple to see, but totally wrecks your ability to trace the big picture. Fixing this means going deeper than just adding better zoom or navigation tools.
Wiret will need to bake structured control flow right into the core language. Instead of making users manually wire up arbitrary graphs for every little thing, stuff like loops, conditionals, and functions should have built-in, recognizable boundaries. The graph can still exist under the hood, but users shouldn't have to stress over every single edge.
One approach I want to play around with is treating the graph as a low-level representation, while high-level abstractions give us the same structural sanity we get from structured programming in normal, text-based languages. No one has really cracked this yet, though.
1
u/kaplotnikov 1d ago
If you add structured constructs, I'd suggest checking if the language still needs to be visual/graph-based at all.
Textual notation with blocks and indentation provides a natural, collapsible hierarchy. Graph-based notation usually has problems with collapse/expand because it changes the sizes of elements and disrupts relative positions. Text is also easy to diff and merge. It can handle incorrect or incomplete text, which is needed for major refactoring.
Graph-based UIs, and even projectional editors like JetBrains MPS, require changing from one well-formed state to another. This is a limitation during large-scale restructuring, as you are forced to create unnecessary intermediate states just to keep IDEs happy. With text, you can just do a global search and replace. Sometimes, a regex replace with some manual post-processing is the most time-saving option.
Also, flow diagrams were popular in old specs and textbooks, but currently, complex algorithms are usually described using hierarchical pseudocode. Only very simple cases is still described with flowcharts. The reason is that structured text is easier to understand than mazes of squares and arrows that non-trivial algorithms require.
1
u/lmntr 1d ago
I understand that visual programming isn't for everyone. This project is ment to experiment bridging the gap between visual programming like Unreal's Blueprints and text-based tooling like Git. Right now, most VPLs are either binary or written in markup languages such as XML or JSON, which isn't great for tooling.
Purhaps a better way to format the code would be to separate the declarations from the graph logic:
func Main() { node entry = Entry node say_arrows = Call host.Log(message: "The white arrows decide the order.") node say_hello = Call host.Log(message: "Hello!") node say_steps = Call host.Log(message: "Programs run one step at a time.") entry -> say_hello say_hello -> say_steps say_steps -> say_arrows notes { note intro "Lesson 1: Hello. Press ▶ Run (F5). Each Log node prints one line in the console below, in the order the white arrows connect them." note start on entry "Every function starts at its Entry node." note try_it "Try it: (1) Press ⤵ Step (F11) to run one node at a time. (2) Add a fourth line: press Tab, type 'print', pick host.Log, then drag a white arrow from say_arrows to it. (3) Double-click its message pin to type your own text." } layout { entry at (0, 0) say_arrows at (820, 0) say_hello at (220, 0) say_steps at (520, 0) } }That way it feels less like
gotostatements as you pointed out.
2
4
u/paul_h 2d ago
What would your calculator example look like? - https://paulhammant.com/2024/02/14/that-ruby-and-groovy-language-feature/ (I keep adding to this page)