visX Is a Visual Interface to Wolfram Language

A visual programming interface for Wolfram Language lets you drag blocks, wire them together, and auto-compile to code. It includes nested functions, list mapping, GPT integration, and runs on a desktop Electron app. Built for teaching non-programmers and rapid prototyping.
Questions this video answers
February 23, 2024
Desktop Electron app built in TypeScript/React with an SVG-based canvas
visX compiles diagrams to Wolfram Language and runs them via Wolfram Script on a Wolfram kernel
nhoff@visx.io
Chapters
Hello, everyone. I'm going to be talking today about a visual programming language that I've been working on based on the Wolfram language. I'm going to show you the demo here. For most of the time, just give you a little introduction while people are coming in. The core of the idea here is that people often think about technical computation in terms of functions that get plugged together. We talk about it that way. We say, take your function and give it to N integrate and then send that to Plot. Put the CSV into an association or hit it with normal. We talk about data flowing into and out of blocks, blocks that have inputs and outputs. And partly that's just because that's often how programmers think about it. But also the Wolfram language, with its unified symbolic structure, I think is well suited to that way of thinking. So I had a thought that many people have, which is, let's draw these diagrams and make them actually computable. So I'm going to show you my prototype that I've been working on here for a visual programming language. Visual. Essentially a visual interface to the Wolfram language. And my goal in this talk is mainly to get feedback from you. So please tell me what you think. I want to know. Do you like it? Do you not? Is it useful? Is it not? Ask me questions or connect with me afterwards, send me an email and I would love to talk N H O F F AT visx IO so you can see here, this is the interface I'm working on. So I'm just going to start with showing you how one one works. And then we'll get into some more examples. You can drag blocks like this. Here we RAW input. I'll take another one. So we have blocks on the screen. Now we're going to want results so we can see the output. Now let's do one plus 100 or something. And now we want plus so we can go through where is plus symbolic and numeric computation and mathematical functions. And yeah, there's plus. So we drag that onto the screen. So here's the regular plus function. It's a block that takes inputs, and I'm just going to wire these together like this and I wire that up to the output and we have this little evaluate button up here. What's happening here is that this interface is taking your diagram, compiling it to equivalent Wolfram language code. It's running it on the kernel, on my machine, my local kernel, and collecting the answers and sticking them back into the diagram for you. Okay? That's the basic idea. Inputs go into Blocks, they produce outputs. You can see the results. Drawing diagrams this way would get tedious fast, as I'm sure you can imagine. And there are better ways to do it that I'll get into later. Let's first look at a little more complicated example. This isn't really that complicated. So here's the cosine function. This would be cosine of x coming out of here. What comes out of here is the regular cosine of x. And I'm going to put that into integrate. Integrate takes a function and a variable with which to integrate. And now I just combine those into lists. So let me evaluate this. The output of this list is going to be cosine of x and the integral of cosine of x. And I also put that into plot. And the second argument of plot is just this list x04pi. And. Yeah, out comes our result. So, as you can see, blocks can take inputs either by wiring them directly in from other blocks like this, or just by typing some Wolfram language expression into an input box. Here you could, if you really wanted, explicitly say list x 0 and then times 4 and PI if you wanted to do that. But this is just clearer. Let's go one more step of complication. I'm going to show you how some Wolfram language expressions that you might want to write would render out as vizx blocks. So we'll take an example problem of just calculating the first thousand digits of PI in Mathematica code or Wolfram language code, which I will use interchangeably. You write something like this, real digits n PI. And you need to take part one because that's what real digits gives you back. So we transform this into blocks, n PI, 1000 goes into real digits goes into part one. Now set is just the regular Wolfram language set function. If you type, you know, x equals Y in Wolfram language, what that really means is set x comma y. I'll evaluate this and maybe not widely known, but set does return the value it sets to. So this is going to be a list of the first thousand digits of PI. While it's evaluating, I see this question, what is used as the front end to render the output of the computations? This is a desktop app, it's an Electron app, and I communicate with the kernel and it produces these results and I paste them back in. I'm not sure if that's what you were asking. Ask again if not, okay. 314159. So they're the first thousand digits of PI. Now let's count the occurrences of each digit. So we want to see how many zeros are there, how many ones, etc. To count the number of zeros, you would write something like this. Count PI digit 0. But we want to count all the digits, not just zero. So now look down here we have count high digits, and in there comes all the whole range from 0 to 9. So look at this little port here. It's not the regular triangular port. This kind of looks like a brace. That means that this block is mapped over its input. It is essentially this. Sorry, this what you would want to write is countdigits PI slot. Make a pure function out of that and then map it over your range. So this will take the count block and start. Apply it to the first one, apply it to the second one, apply it to the third one. So we have 93 zeros, 116 ones, 103 twos, etc. Okay, now say we want to make a list plot of that. There's an annoying little problem, which is that Lisplot thinks that the first number corresponds to number one on the x axis, number one, the second number to number two. But that isn't what we have. Let me go down there. I wrote some of this. So we have 93, 116, but what we actually want is 0 comma 93, 1, comma 1 16. Fine. What you do in Wolfram language, then is you just write this pure function list of slot and then your countpidigit slot and map that up there. So how would that work in physics? You can make blocks like this that contain other blocks. So this is countwithdigit. And inside here, this countwithdigit is just a regular block like any other. I can make it smaller. It has inputs and outputs, but inside it is a completely separate canvas. I can put any blocks on there. I can connect them however I want. And countwithdigit compiles to a Wolfram language function that takes inputs and produces an output just like anything else. In this case, it's really simple. It just does what I set up here. It's the list. It just takes the list of its input and then the count of its input, and that is mapped over range 09. And I give it to listplot. This is just Mathematica. It's just. It's just a Mathematica expression, a Wolf language expression. And so I can put a second argument to Lisplot saying that I want the axes to be labeled as count n digit. Did you write Vizx in JavaScript and use JavaScript to call the Mathematica kernel. I wrote Vizx in JavaScript. Yeah, TypeScript actually. And I use JavaScript to call the mathematical kernel. Yeah, I just use. I just call Wolfram Script. I just compile it to Wolfram language code and give that to Wolfram Script. That's all I do. Okay, well, I think you get the basic idea. We'll do one more thing, which is that let's. So this plot is for the first thousand digits of PI. And you might be interested to see what it would look like for 1000 digits and a million digits and a couple other examples. So I'm going to take everything we've done so far and wrap that in yet another function here. That's going to make a chart. So let's look in there first. Let's just look at pie chart. So it takes N of this thing we wrote first that calculates the first. The first I said thousand but digits of PI. Now this will get compiled into pie chart. Open square bracket, length of PI, close bracket, colon equals. So I can use length of PI as a variable inside the function like you can with any other Wolfram language function. And I'm taking length of PI here and winding it into the second input of N. And now we use countwithdigit. Again, this is a canvas within a canvas to make our plot. But now it'll be parameterized by the number of digits of PI in the list. OK, so here it is for 100, 1000 and a million digits, PI. And as expected, it kind of flattens out. Now, inside these canvases you sometimes. Which basically means inside a Wolfram language function that you write, you sometimes have results that you want to see inside the function. Like in this case, let's say you want to verify that count with digit which produces this list is really doing the right thing. And that when I put it inside this outer function, it didn't mess something up. So in the first we have this. Now this pie chart is getting evaluated three times. So in this result block up here, let me move it up here. I need to work on this a little bit. But this is the output that this block would see the first time through the loop. It's the number of. What did I say? In 100 digits of PI. I think if I go up here and I go to two up here, then everything in here shows me the result the second time through the loop and the third time through the loop and the numbers get bigger, as you can see, just so you can see intermediate results. The reason I Thought this one might be useful is that sometimes you're writing Wolfram language code and you want to see intermediate results, but you've created this expression which is a full line of code and you just want to pull out one bit of it in the middle and say, what does this thing equal during the evaluation of the function. It's easy here to do that by. You just pull off a link from the whatever value you want to see into a result and there you go. Okay, I'm sure you get the idea. I have a couple more examples of neat things that I'll show you and then we'll save time for questions. There's no reason that everything you write should have to be blocks. Sometimes you just want to write some text based code and there is nothing wrong with that. And so I give you the option to just give me a text box into which I will type Wolfram language code. Please splice it indirectly. And like calculating Fibonacci sequences, you just want to use a little for loop. Just please give me a for loop. And so this is a regular physx block like any other, except instead of consisting of blocks, it consists of code and you can map over it and it acts like any other function. Now you can compile. Let me go back to this PI digits example down there. There's nothing magical going on down here. If I want to take this, say I want to take this count with digit thing and I want to see the Wolf language code underlying it, I can click this little book bookish icon there and it will compile just that block. And we're gonna have to wait for a few minutes. This is slow, but I'll have to speed it up for, you know, when people really use it. Right. So this is all it's doing. It's just a way to create Wolfram language code. And there's no reason this has to be in some kind of brutal full form. We're about halfway through. I'm going to go through some more examples and then we'll do questions at the end. Okay. Yes. Let us talk about functional programming. There are lots of times in the Wolfram language that you want to say something like this. You want to select elements from a list that satisfy some function. Now you don't want. See, the even Q is a regular function that takes an input and produces an output. Let me evaluate. I could say over here, like I could say Even Q of 8 and it would say true. But when you're using select like this, you don't want to say Even queue of some number. It's the function itself that you want to apply to every element of the list. An often requested feature is to have these lines that come out the bottom of the block that represent the block itself. And so that's how you would write something like this in PhysX. But often you don't want to just put a block. You kind of want to put inputs into the block that are then fed in as a function to the other block. So let's say this is how you do that here. Say you want to select all elements of this list that are greater than 2. You can take greater, leave the first block open. Now greater, with its first input unfilled and its second input filled, is essentially a function of one argument. It takes one argument and produces one output. It's like saying this, it's basically exactly this. And you can give that as a second input to select and it will work the same way. I have this nice sugar for map. The little curly brace thing that really only works if you want to use map in the traditional way. If you want to use mappinny or any other functional construct in a non. In a non simple way, then you can't explicitly map over the block. So then you can do this kind of thing. You take map, you take the block itself. And this could be any composite block or anything you want. Put that into the first argument. Now we have this is here some matrix A, B, C, D. And then if you want to map at level 2 specifically, you can do that here. One more example, just because it's neat. Hope this one works. You can write any Wolfram language code you want in here, not just for simple stuff like one plus one. Here's an example using the entity system. So here's flight data I'm going to take. This looks at every flight that went from Boston to San Francisco yesterday. This is a Wolfram language symbol that you can use. And here are three flights. Apparently there were three flights yesterday. As you can see, the results show up the way they would in the front end. So it's okay. So let's take the first. Take the first one of those and we'll take entity property flight recorded altitude. Now what is this thing? When a line comes in the top of a block, there are some cases where you want a block to take on the function of something else in regular. So the way you have to write this. Let me, let me just show you. I'll just put a comment here and show you what I mean. The way you have to Write this in Wolfram language is you write the entity, whatever, close bracket, then open bracket again of the property. So the thing coming out here first is the entity that JetBlueflight. Now I want to say entity of the property. So this block needs to take on the function of the entity itself. A little confusing, but whenever you want to write these structures here, this kind of A of B of C kind of thing, you need to have a block link coming in the top. Okay. Give it a dateless plot and there's the altitude of the flight. Well, I think you get the idea. If you want to get blocks on the screen. All these examples I'm showing you are examples that I have kind of pre made. If you don't want to get blocks on the screen by laboriously dragging everything from the library here, which you probably don't and I never do, you can type Wolfram language code in down here. Like I'll say, well, like that example. Okay, whatever. Sin X X. How about zero to PI? And I'll say, well, that should give me zero. Let's see. So what, what's happening now is it takes some time because it takes that Wolfram language code, it gives it to my local kernel, it parses it because you don't have to type it in like this. You can use any input form expression there. And let me evaluate this and make sure I get zero. It'd be funny if I didn't. So you can use any syntax you want there, which means you can go out to the web, copy, paste Wolfram language code, and stick it in there and transform it into blocks. Oh, is that. Yeah, that's the world's biggest zero I have to fix. That's kind of a bug where it always takes up the full width of the block. So I'll fix that. But anyway, And so this is just an easy way to get blocks on the screen in. If you don't even want to do that and you just want to describe the problem that you have, you can type it into a second block down here. And this will essentially give whatever you type in to GPT and it will transform what you typed into explanations and blocks. So what's an example? What should I type in there? This is my placeholder. Well, fine. How many births would fit in the sun? Now, you are going to wait with me and we will see together if this works. Because GPT gives you something different every time. Sometimes it says no, I don't know, think about it. And sometimes it gives you detailed code and explanation. Now it's going to give back explanation code, explanation code and all those bits of code will be transformed into blocks. So this is going to take some extra double time. Meanwhile, I'll look at some questions. Nice. Like echo. I don't know what echo is. I thought I knew most of the visual programming systems, but I don't know. That one reminds me a bit of the boxer project again. Don't know. I'll have to read about that. Thomas says I've always wanted something like a block showing boundary, initial conditions and range restrictions for conditions. I don't know what that means. I will have to spend time reading about it. Okay, so hey, it worked. Did it use the entity system? It did. Star radius set sun radius, Planet Earth radius set earth radius. Next we can calculate the volume of the sun and the volume of the earth. Yep. 4/3 PI r cubed sets, sun volume, sun volume, earth volume. Okay, so it's getting it right. It's getting it right. I wish this is something I want to build later. I wish it wasn't using so much setting. I wish it would take this instead of setting the value to Sunradius, it should just take the value that comes out of here that it would set to Sunradius and wind it right into here where it says Sunradius cubed. I just need to do a bunch more more intelligent parsing of the responses and better transformation into blocks because this really is just text based Wolfram language code but rendered as blocks, which isn't. Why don't you just write the code? I'd rather it link it up nicely, but I can figure out how to do that. Good. Well, this went both smoother than I thought it might and faster than I thought it would. Let's think about Thomas's question here. He says I've always wanted something like a block showing boundary and initial conditions. Actually, I don't know if anyone else can see this. Don't know. Okay, next question. What type of applications do you think are best suited to be programmed with VisX? Excellent question. That is the main question that I have on my mind. So yeah, what's the use for this if any? I think there are a couple of possibilities. The first one that comes to mind for me and most people is non programmers students essentially learning to code. This would provide a lower barrier to entry for the Wolfram language. People won't have to be worried, you know, they won't be intimidated by syntax. What the heck does slash ampersand mean? And all this. Not that it's complicated, but it is Just intimidating sometimes. And something where you can point and click, put blocks on the screen, connect them up is easier to get into. Second reason, right now this is desktop software. You download, double click install and it runs on your local kernel. I'm considering making a web based version of it where the evaluation happens in the cloud. This means you don't actually need even a Wolfram kernel. You don't have to even know anything about the Wolfram language. You don't even have to know that it's backed by the Wolfram language. You can just pop, type something in here, connect blocks and see what happens. This is even a lower barrier to entry for people who want to do some analysis but don't think that they are programmers. Now I think this might be a good way to teach students programming, but I don't think I should end there. This is not the only programming language you'll ever need and eventually you're going to want to write regular programming text based Wolfram language code in a text editor and or in a notebook and run it normally. But this is an on ramp. Okay, number two, there are lots and lots of people out there I've talked to. Let me back up one step. This is not the first iteration of this kind of product. I've built prototypes, talked to users about what they might like, gotten feedback changed, it went back to the users get more feedback. So this is what people currently tell me that they're excited about. And during all of this kind of user interviews and user interaction, I've heard a lot from people who are kind of technically minded. People think people who do drug development, people who are people who do finance, people who spend all their days in spreadsheets. These people work with numbers all the time, but they're not programmers and they need to do some analysis, transformation of their data. And they either write really bad Python code that they don't enjoy at all and doesn't work very well and is unmaintainable, or they write completely terrible Excel functions which they also don't like and are unmaintainable. And I think something like this might help people like that. You take your CSV file, you drop it in there, here comes my CSV and you can look at it, you can transform it in simple ways, you could do it in complex ways and then out comes your output CSV. So yeah, that's number two. We're out of time, we're almost out of time. So let me say, oh, there are some more questions that come in. I am looking for beta testers anyone out there who wants to poke holes in this, click on it, try to crash it, or tell me what you would use it for. Contact me nhoffizx IO N H O F fizx IO I'm interested in what you think and what you would use this for, if anything, what you think other people would use it for, if anything, what I should change, what I should remove. So there are a couple minutes left before we end. I'll look at some more questions. Is Typescript doing the rendering or is Wolfram Language doing the rendering of the VisX user interface? TypeScript is doing the rendering. This is essentially a giant Typescript React app. What you are looking at here is regular React user interface elements. These are electron menus and all of the stuff on the canvas here is all svg. Okay, well we're almost out of time here, so with that I will thank everyone for attending. Email me if you're interested in being a beta tester. Email me if you have any feedback, anything you want to tell me and thank you for your attention. Bye.
More from Guy

Cheryl Strauss Einhorn | The Human Edge: Smarter Decisions in the Age of AI | Talks at Google

Rachel Glennerster | Innovation and the Center for Global Development | Talks at Google

Rebecca Winthrop | Rethinking the Purpose of Education in the Age of AI | Talks at Google

Dr. Robert Wachter | A Giant Leap: How AI Is Transforming Healthcare... | Talks at Google






