Live CEOing Ep 761: Language Design in the Wolfram Language [LinkObject, Messages, and More]

Stephen Wolfram reviews language design for the Wolfram Language, proposing two new predicates: ValidStructureQ for checking syntax and structure, and CurrentlyValidQ for time-dependent validation of external objects. The discussion covers message reissuing, code-assistance features, and how existing functions like URLs and associations handle validity checks.
Chapters
All right. Hello, everyone. Welcome to another Wolfram Language Design Review, part of our Language Completeness and Consistency series. And we have three seemingly simple topics for today. They won't turn out to be. First one, when is a link object valid? Oh, boy. Right.
So there are two kind of invalid LINQ objects, and of course, we're going to be talking about various other objects, but just for concreteness, we're starting with link objects. So there are the syntactically invalid ones, right? You do link object of foo, or they're ones which are simply expired. And as of right now, we have sort of various internal functions to test whether something is alive. So, for example, if you were to copy that input or to just reevaluate that input, then.
The input.
Yeah, the input. Then you see, the formatting goes away. Because that was an object that was valid in my session when I created that, but it is no longer valid in your session. So that's how you can tell that, you know.
Right. So that's one possible. I mean, another possibility is that we would maintain the formatting but indicate invalidity, which I've seen elsewhere.
Right.
Yeah, I think we do that. Like, on, like, channel objects, they have kind of a dynamic display of state of the channel.
But although the issue of, you know, being able to tell at a glance whether they're valid is interesting, but there's a more fundamental issue of being able, you know, a systematic method for being able to tell whether things like link object are valid from code from. From a program.
Right.
The whole question I raised that because in the kernel objects I wanted to be able to accept link objects as arguments. Then the question was, well, is that thing actually valid? Should I care? Should I test it before I incorporate it into the kernel object? And then I saw that you can just make up your own link object expressions and nobody complains.
Let's take the example of a URL. Okay, I got a URL foo.com bar is it valid? Is it not valid? If I write H, X, T, S, colon, slash, slash, whatever, it's probably not valid. But if I have a plausibly valid domain, you know, it might be down that day. Is it valid? Is it not valid? See what I'm asking? I mean, there's different senses in which things can be valid. So, and to me, you know, like, does a File exists q urlexists q? What does exist mean for URL? Is it going to 404? Is it. Is it going to DNS resolve? You know, what. What level of. Of exists is.
Is It Right, so I think. Right, so I think we can perhaps separate, you know, system internal things to completely external things like link object, node object, cell objects, you know, input stream, output streams. I think those all have sort of well defined notions of is this thing open and you know, can you dereference it and get non junk output out of it?
Well, does it point to a thing that's actually there? Which is the same issue with the URL?
Well, it's not entirely the same issue in that the URL is a thing that exists in the world beyond Wolfram language. And when you're dealing with that world, we had better have provided you the, you know, the APIs for doing that. But this class of objects are objects that only the Wolfram system knows whether or not they exist. Okay, what about no other knowledge anywhere?
Okay, what about parallel. Parallel processes? Parallel Wolm kernels?
Yeah, there I have a very specific notion of validity. And so a kernel object knows whether it's valid or not. And I mean, same as with URLs. I mean, same question with file name. Is a file name valid if the file exists or is it valid if it's syntactically correct? I mean, if you have a file.
Then what if it's a named pipe?
If you say create file, then you always have an invalid file name as argument by definition.
Right.
And if you. So I think, I mean programmatically with all of these, I mean most of these are not things that you are supposed to input. They are produced by some constructor. And the same problem happens whenever you design a data type. You have your objects and you need to know whether the objects are valid so that you can format them correctly and accept them as arguments. And so you see, always seeing code that implements data types, you always have some kind of validity predicate and each one has its own. And so my plea here would be to introduce system wide valid queue predicate that could be used by overloading for all kinds of objects.
Yeah, I think it's a good idea. But whether valid is the right term or whether it's active queue or something.
Yeah, I think active queue is probably a better name certainly for the system internal ones. Right. Link object we have a very well defined notion of is this an open link that we can read and read or write from right notebook object, cell object maybe also process object certainly input stream and output stream.
You know, like what are some other words other than, I mean valid? I don't.
Well formed.
Well formed isn't the right point. Well formed isn't the point, the point is not that it's formed, the point is that you can actually do something with it.
Right, like that.
Right.
And just to reply to that, to further emphasize, right, that link object is well formed, it doesn't point anything in the current session, but it's a well formed link object.
Yeah, this isn't a good name, but instantiated Q, I mean, you know that conceptually I think that's a similar sort of thing.
Yeah.
Or exists Q maybe accessible Q.
There are other classes of objects like interpolating functions or solutions of partial differential equations and they always have a particular head. But if you type one in, you get chunk. Right. So there is a definite notion of validity for anything that, that we call an object.
But, well, but I, I, I think that's pushing it the, this notion, what, way too far. I mean, any expression can be valid or invalid in that sense, right?
No, not if it's a purely symbolic expression that doesn't pretend.
Well, URL is a purely symbolic expression, right. It, it has no other than format values, it has no definitions attached to it. I mean, that does have a notion of validity and that, you know, it's marked valid queue internally.
Something about this feels similar to the discussion we had in last week's Hyper Architecture Check in meeting, where the issue at hand was Larry was wanting to add some code to check if like a task object was still running or not, and if it was running, cancel it. And I think what's interesting about that is that it's a question of you want to do some operation, if some condition is true. And that's like there's a name for this. It's time of check, the time of use. It's like a standard thing in software that can sometimes go wrong. And I wonder if that applies here, right? Where if it's almost fundamentally not a well formed thing to ask if something is valid, if that thing can become invalid through no act of the program or anything you have any control over. If you were to write on one line in a program URL valid queue, that website could go down the next millisecond and the operation you would do next would fail. So it's not really necessarily a meaningful thing to ask, is this thing valid at this instant? Because it could change at any given.
Moment and link object has this, I mean, in the way that a link object might become dissociated. I mean, one way is that it doesn't correspond to a system object inside the kernel. The other is that it corresponds to a system object inside the kernel, but the other side of the link died and the kernel doesn't know it yet.
Yeah, right.
So, I mean, the basic point is all of these, okay, the interpolating function is a different case because the interpolating.
Function, I mean, once it's valid, it's valid for all time, whereas a link object, you could wr, right? You could close or write an E off to the LINQ object, and then the same expression is no longer valid.
Okay, what do you think of the name currently valid Q?
I mean, I think I'm having trouble evaluating the, you know, any of these possible suggestions without a better understanding of what Roman's hoping to achieve. Like what the next step would be, assuming that this function, whatever we call it, it returns true or false. What happens next?
Can you dereference the object is really the question. That's what this is answering, yeah.
For example, I want to write a function that accepts an interpolating function as argument. So I would write F of.
I.
Question mark, valid Q.
Well, just because it's valid Q doesn't mean it's useful for you, right?
It doesn't mean, yes, it is, because that counts.
No, no, Roman, let me finish. Roman, let me finish. Roman, let me finish. It doesn't mean that, you know, it's defined for the right number of variables or defined for the domain you're interested in or, or anything, right? I mean, and there are ways you can test each one of those things, but, you know, just because. Just because it's been marked valid cube in the kernel table doesn't mean it's at all useful for you.
Okay, so look, here's the client, take.
A step back and ask you to write a formatting rule for interpolating function. So you need some kind of predicate in that formatting, right?
Which is.
You don't really care how many variables it has. But was it. Is it. Is it valid? I mean, that was.
Well, it's quite literally. Does it pass system private valid queue? Because.
Yes, and I would like to have a system valid queue instead of a system.
Okay, so listen, listen, I've got a claim. I don't have the names, but I've got a claim for what? This.
What?
What? There's two ideas. One is valid format Q. Okay? Is it of which this would pass valid format Q? It wouldn't pass it if you had seven arguments that were symbolic here, okay? Valid format Q currently valid Q. This fails this here. In the case of interpolating function currently valid Q and valid format Q will always return the Same answer in the case of a LINQ object, they will return different answers in general. And currently valid queue, I claim, should actually sort of try and do the dereference. So for example, currently valid queue on a URL should actually try and, I don't know, do a read from the URL or something to determine if it's currently valid. Now, okay, you could ask. Okay, so here's a slicing of that something could be currently valid for reading, but not currently valid for writing. And that's a subtlety.
Yeah, I mean, you know, in the case of link objects, I actually don't know of a general test that could be applied in, you know, in, in any reasonable state that the link object would be in that would give you this information.
I mean, what, what the, what the formatting rule is based off of is, you know, some internal, you know, test that Steve Wilson gave me a decade ago, which is presumably, you know, does this thing appear in the table of known link objects to the kernel and therefore it will attempt to write to it, but. Or read from it, but there's no guarantee that that operation will succeed and. Or not hang your kernel.
Okay, yeah, well, and this was the class of test I was thinking of when I gave my input to this agenda item. Just basically, is this expression connected to an internal system object?
Okay, I've got a suggestion, guys. Yeah, I've got a suggestion. My suggestion is we got these two things. Valid format Q, currently valid Q and currently valid Q could have a second argument different depending on what the objects are here that gives the, you know, the sense of whether, what, what does currently valid mean, like, you know, file exists or something. Or it could be, but currently valid Q by default with one argument would make a reasonable heuristic decision on what it means. So currently valid queue for a file if the file doesn't exist would be false.
So this is mostly a function for objects with external state.
Yeah, that's correct. That's what it is. And, and the internal state objects, this is still useful even for the external state object. Valid format queue is still useful.
Yeah, that would be useful, for example, as an argument, simple argument test without wasting time.
Yes, but now I want to write.
The name because format suggests to me that it's somehow related to formatting.
Right, okay, so I mean, that was.
The sense that I, when I suggested well formed queue. I mean, maybe it's not a great name either. That was the sense in which I thought that function would work, that it's, it doesn't have to hit the network or the file system, it's based purely on the structure of the symbolic object.
Valid structure Q.
Is valid Q. Not.
No, it's. No, that. Because we're all confused every time we bring up valid queue. Every time we bring up valid Q. Okay, we get confused because actually there are two different things, right? That's why we should separate it. Valid structure queue. Because if you see that in a piece of code, if it says valid structure queue of link object, okay, you know that that's not going to test the link object, you know, it's just testing the structure currently valid Q, you know that that is a time dependent thing. It's not just testing the structure.
So for immutable or internal things, valid structure Q would be two for everything that was produced in a. In an approved way.
Right.
Result of an interpolation. Yeah, when you're opening, opening a link.
And yeah, it's all valid structure Q. I mean that link object at the top there would be valid structure Q. True, but it will be currently valid Q. False.
Yes, I mean that's, that's the function I'm after. If it's called valid starter Q. Okay, I could probably live with that.
Okay, you were asked to that one. I thought you were asked for currently valid Q.
But no, no, because I don't care about that. I want code that accepts only syntactically correct inputs. And I mean, the internal code works the same. If you look at the library, the LINQ library, the kernel bindings, then when those functions return a link object, they first check whether it's syntactically valid, and then when they actually need to use it, then they actually check.
And to be clear, The interpolating function example is testing not only that it's syntactically valid, but semantically valid, which may be sure.
Yes, but I mean the way to do this is to set some internal bit when you create it, and then you don't have to waste any time.
Okay, but fine, but are we happy with valid structure Q? An interpolating function? If it is not semantically correct, then valid structure Q is false.
Yes.
Yeah.
Okay, well, that's what I'm proposing here. And I, I'm proposing that as a kind of an escape valve, we have second arguments probably for both of these things that can give more color to whether something. What it means to be currently valid.
Yeah, I mean, I'm imagining like, it seems like there are a lot of functions in the system like, say like take packlet object Q as an example, whose current behavior is basically what this new valid structure queue thing is they do basic syntactic checking, so to speak, of the structure of objects.
Yeah, well, I mean, we can hire a bunch of these functions.
Yeah. But I think you can look at all of the star Q asterisk Q functions, and some are type. Some are type tests, which are useful, but others are simply.
Okay, so here's another one currently valid to. You know, this isn't a good name, but actively test, do the ping those kinds of things as.
Yes. So you would not only be content with the link object being open, but you would actually try to. You would actually tickle it and see whether it's still alive.
Right. So let's just take a little.
This could hang the kernel. So I'm not sure that's a good idea.
Well, I understand, I understand, but, but that, that's, you know, that's what you're signing up for, so to speak. Okay, let's just have a quick look here at. At which of these. What's the fastest way. Okay, so file exists Q. I'm gonna. I'm gonna list candidates for things related to this. File exists queue. File format queue. No. Finite field element primitive queue. No. Okay, hold on, let's just take a look here. Array queue. No, no, not really.
Right.
It takes rank and Q asked Q What the. Has asked Q?
Probably something for the question framework.
Oh yeah.
Maybe not as many Q functions as we thought.
Yeah, they're not as many of these.
Yeah, most. Most are type. Type of property tests.
Binary image Q. Yeah, that's. That's more of a content test. Byte array Q. It's not again, it's. It's a type test.
I mean, I wonder if it'd be fair to imagine this hypothetical valid structure Q function as being keyed on the head.
Right.
So you. It might be something like. You may not. There might be situations where you don't care necessarily what the type is. You just want to know that whatever it is, maybe, maybe there's like three types that you generally accept.
Exactly, exactly. Just want to know if it's garbage or not.
Okay, so the timing would be that currently valid queue would over time be defined for all our internal data types and be available via app values for implementers of new data types.
So it looks like biosequence queue is such a function.
That returns true on strings. Right. Or I guess there's. I know there's also a headset the.
Principal uses message is returns true if the argument is a valid biosequence expression and false otherwise.
Yes. But what it means is something a little different than what you think it means. Okay, I agree that. Okay, so let's write that down here because the point there is that I think that if you give it, if you feed it. Interesting, interesting.
Does it, does it want to have a biosequence head?
I guess it does.
Inputs with heads other than biosequence will be false according to the documentation.
Okay, so it's a type tester really.
But there's one interesting case that is association queue, which is a bit more than just telling whether it's an association, because association expressions can be invalid because if they turn us on. So this is kind of a candidate for.
Okay, so valid structure Q would apply to associate association Q. Valid structure Q on an association.
Right.
So you're right. Association Q of an empty association is true, but association Q of an association containing blank is not true because it's not backed by. Right. That's just a pattern. It's not backed by a hash map.
I think it's like anything where the head, like these functions don't just check heads, they check that the internal contents are semantically consistent. So I think biosequence Q would actually fall into that same category. Maybe not for strings, but for something with head biosequence.
Right.
You could imagine valid structure queue of underscore biosequence would just call biosequence Q of that same value.
Just type association.
Right, Right.
Delete the ghost to eight, have just a blank as the second argument. Then it'll give you false or anything.
Any.
Any chunk.
Well, I wouldn't call that junk. But it's a normal expert, not backed by a hash. Right. I mean that's very useful if you're going to be calling match Q and the two argument association whose first key is A goes to 6.
I wonder whether there's some way of indicating that it. Yeah, I just put.
Sorry.
Yeah, I wonder if there's some way of indicating that this is head keyed. So in other words, that. Because in this association case you might say, oh, if it isn't a valid structure, it means it's garbage. But that's not garbage. The thing you have there.
Right.
It's really.
But it's not an association. Right.
Right. It's not an association in the sense that it's not backed by a hash.
Map, but it is association.
Correct. Yeah.
And it's also like it's a semantically meaningful pattern in some sense.
Right, but. But you couldn't, for example, do key extraction. Right. I don't think you can, you know, do that association of, you know, key of A. I don't think that'll work because it's not a true association.
Yeah.
Well, but, okay, so my only concern here is valid structure. If it's false, suggests it's garbage. But it isn't in fact correct that it's garbage. It's just that it's not behaving.
Yeah, it's garbage. It's garbage in the sense that you could not pass it as an argument to a function that accepts an association like association map or any, any function that you could still use. I mean, it is a symbolic expression, just like. But it's not an association.
Right.
Nick is pointing out symbol cue and video cue our examples.
Molecule Q.
Right. Audio Q. Hold on a second. The thing about something like molecule Q is it's asking two questions. It's asking both is the head molecule and are the innards molecularly appropriate?
No, it's documented that a molecule with improper valence will issue a message but is still molecule Q.
Oh yeah, that's the other issue. Q functions can be quite inconsistent about what they do with edge cases.
Well, but okay, so for us, is, is a molecule within correct valence. Valid structure Q? I think. No, I think if it, you know, you know, eg, if something issues a message. That makes it an invalid structure, that implies it's an invalid structure.
It's not clear to me why this decision was made about molecule Q. There's nothing in the documentation suggests why it's useful this way and not the other way.
And we don't have any molecule adjacent folk here, so.
Right. Yeah, I mean, you know, the real question is. Yeah, your question is valid structure Q of expert, if true, indicates that.
You.
Can do with expert what you can do with sort of any, I don't know what fully processed object with the head of expert.
Well, no, because of the state issue, I guess you can attempt it, but you'll get a. A fail. A fail thing rather than. Well, for the current, you'll get a different failure.
Yeah, I mean, look, currently valid Q is things that don't evaluate because they evaluated to failure. You're done. Right. Currently valid Q is things that sit there as objects but might not in fact instantiate properly.
A good example of currently valid queue is scheduled task active queue.
I see. So currently value of a task object, does task active mean it's running or does task active just means it isn't? It isn't. You know, it's meaningful and could run.
Well, I, I Guess Scheduled task active queue is. Is the deprecated name. It's not clear what it was replaced with. There isn't a task object.
Well, okay, so. So who knows what that like it is an act.
Like there's an active or there's some property of task object that you can read.
Yes.
Right, well, where I believe it means, you know, it has, you know, non zero. It has a positive number of repetitions, which. Okay, so number in the sense that something's currently. That it's currently running on its last one, I believe is what it means.
Yeah. An example in the documentation suggests a cloud scheduled task that could be stopped and scheduled task active queue would then return false. But then, then you could restart that task and it would return true again.
I met LC on a live stream is pointing out a syntactically valid object can have a semantically valid referent that happens to itself represent an indirection. In which can. What syntactic semantic is a false dichotomy? I don't understand this. Maybe it refers to something we talked about earlier. Right. Look, I think we have a direction here. Let's try and fill out currently valid Q and valid structure Q and see what they apply to. Okay. See whether they make sense.
One question, I assume. Does anybody disagree with the proposition that valid structure queue of a failure object can be true? Like, it's not like all failures are invalid, it's just.
Oh, absolutely.
Failure. Yeah. Okay. If it's a malformed failure.
Yeah, if it's a malformed failure, then it's false. But if it's a successfully formed failure object, then valid structure queue is absolutely true for it.
Yeah, I agree too.
Yeah, just wanted to check that. I think that's a litmus test. Are we actually understanding that this is not something like.
Well, we're reading its name valid structure queue. It's not valid queue, which will be completely unclear what the hell it is.
Yeah. Okay.
All right. Onward. Message reissue.
Right. So a common. So we have an example here of a utility function that, you know, sort of appears periodically where. Right. We want to test parameters and we can do that by calling pre existing functions, but of course we don't want to be issuing messages from random heads. And so we, you know, so basically we run the test quieted and then, you know, if it failed, issue a new message with the new thing. And it might be much nicer if we had something where we could, you know, just have a single function that, you know, did the thing and reissued it. And so after thinking through the sum I. I don't know that anybody has per. Has proposed this exact thing. But my proposal is that we want something like, irrespective of the name, a function like message reissued, which takes the expression and then says, well, map messages, issue them as head. But it also tells you whether or not a message was actually issued. So you can use this as a predicate and not just as doing the.
How does it tell you if a message was issued? I mean, doesn't it just return. Oh, I see. This thing has a return value. The side effect is issue the message. The return value is true or false.
Whether it. It.
It actually did the reissuing, whether it actually issued a message.
I understand. I don't. We have another function that tells you it doesn't check effectively tell you whether a message was issued.
Yes. So. So you. You'll notice that. Well, I guess. I guess. I guess, you know, Danny decided to write this in a different way where he just. I mean, this example comes from Danny's code, but, you know, we can really. Yes, I'm pretty sure that you are the person who wrote level Q.
Okay.
Great. So you're here and you don't even recognize your own code.
I rarely do. It looks too smart.
Okay, well, maybe Jose suggested it to you and you're just a person who committed it.
Got it.
So. Right. But you could also have envisioned writing this as, you know, a quiet of check of blah, and then have a second argument that issues the messages and return. True, but this is sort of a sufficiently common idiom that it seems like maybe we want to do this. And there. There is this utility, there is this WFR called message replace, which does just reissuing part. And, you know, I'm not sure. I haven't looked at the details of how it's written. And Rick was invited, but apparently he can't make it, which I don't think is if we really want to into the details of message replace, we would need him. If we don't, then. But, you know, I don't think. I think his message replace is sort of too general and too confusing. I think what we want is something simpler that just allows you to, you know, change the head, maybe change the tag and sort of returns it. But, you know, since it's the first time I'm actually proposing this thing, it might also be good to see if anybody else has any thoughts about whether this is a sufficiently useful thing to be.
Well, okay, so the issue is there's a couple of points here. So first point is the cosmetics of Deep inside your code, there's some message being issued and you want to spoof where it comes from.
Right. And Right. And so right now, I mean, this is a very simple example of, you know, testing an argument, but Right. It could also be right somewhere deep inside your code you're calling solve. But you don't want to see random solve messages. You want to see, you know, my function messages.
Right.
For the D1, yeah. Do you want the same message content as the solve thing, or do you want something different?
Usually the same is okay. I won't say that's perfect.
It's sometimes different.
I mean, yeah, we could have message spoof and also message replace. There's room in the world for both. Or, or it could just be, I.
I so want a symbol named spoof.
I mean, looking at a step back, it would also be useful just to know whether certain arguments are acceptable without tying them to messages. I mean, I mean, I mean, I have this problem all the time when I write parallel implementations of certain functions. So I have to read through the documentation and figure out all the ten different calling sequences. It would be much easier if I could just do a trial call and if it works, then I can accept the argument. Otherwise I will go sequential. So I think that something like checking whether something is valid as an argument without necessarily issuing a message would also be useful.
Well, I suppose if we gave a second argument to valid. I mean, maybe this is pushing it too far. But if we gave valid structure queue a second argument of like what to test for, so we could have like level spec and then it could.
Be useful, is going to evaluate its argument. So what you want, what Roman wants is, you know, he wants something like check argument structure of F of blah, blah, blah, which doesn't evaluate its arguments, Right?
Yes, that strikes me as impressively difficult to obtain.
But also, what would the syntax for that be? Would that be like one goes to something, two goes to string level specific?
No, I would actually take the very expression that I want to eventually evaluate and first do a test drive. But I understand that in general this is impossible. And what we see above is quite a bit of a hack.
You don't know. You won't know if something will evaluate without evaluating it is, I think, what.
It comes down to. I mean, that example there doesn't really have any structure in the second argument. So it might be that the level spec would be different in that case than if the second argument were a 10 deep nested list or something like that.
I mean, this question of whether f Of XYZ is very similar to the valid structure cube question.
Well, but that's for output. That's for inert things.
No, I know, I know. Valid structure goes through inert things, but this is something where do a test drive first pass. Is it obviously wrong? You know, look, it's kind of like check obvious things.
Plausible arguments.
Q.
Read mind the brackets.
Well, I mean, there are things where we definitively know that.
Well, we. Well, we only definitively know them if we state what our expectations are. Right, Like a level spec. Right. I mean, there's a well defined, okay, notion of what's a valid level spec. But you need to tell this function which of the. The arguments is the level spec.
Okay, let me give an example, okay, that. Okay, this relates to a thing I really wanted to do. For the language, we have syntactic correctness. Okay. For the language we know, if it's syntax valid, we don't have sort of. This is relating to my semantic grammar stuff for English, you know, you a. You know, a cactus cannot be happy so far as we know.
Or mine is very happy.
Yeah. The plants in my Plants vs Zombies garden, when I water them, they clearly smile and become happy.
Okay, all right.
Okay.
I like the zombies.
The. Oh, God, why am I not coming up with something?
I mean, it's related to type. Type correctness, right?
Yeah, yeah, yeah. But I mean, there's. There's. There's a whole idea, which we've been exploring a lot in the case of natural language, of when do things. When are things semantically, you know, a mountain can't go to the store. Just doesn't.
True.
You know, a mountain is a fixed object. It doesn't take a trip to the store, except poetically. And so similarly, in our language, this basically doesn't mean anything, just as even, you know, plot sin X foo doesn't mean anything, even though in principle, I mean, just like if I type in log, open bracket, close bracket. Okay, in principle, log, open bracket, close bracket could be a symbolic expression that I can pull apart and use for things. But we have decided that it is. Is sufficiently plausibly meaningless that we carrot it and we give a message.
You wouldn't know the plot sign X is semantically invalid until you tried to evaluate foo inside of plot.
That point.
Would that work? Or does. Or does plot. Check the unevaluated foo, Brett.
Well, plot gets the.
If you define foo outside of plot as, you know, list X01 or whatever, that will work.
Okay.
It may only be plot that does that at the moment. I think like parametric plot won't.
Right. And also assuming that X has no global value.
Correct.
Right.
You know, food would have to be something that is at evaluation, you know, or upon evaluation, a valid iterator for plot or valid variable spec for plot.
But one can imagine other examples like this where the semantics are slightly implemented slightly differently and where it absolutely matters whether you do or do not evaluate the thing as to whether it's semantically sensible.
What are the. I'm having a little trouble, like, understanding what are the use cases where you would want to check this property of like, is this function call valid but not actually do the function call if it's invalid? I mean, I can think of some obvious cases like maybe if a function has side effects.
Code analysis. I mean, this is what I've wanted for code analysis, that somebody who types this in, it should be flagging this just like it flags them aspelling.
Okay.
So Connor, here's an example that is real. Okay? Suppose I'm writing some special plot function and I want it to work the same as plot, but it's, you know, doing something special. So how do I test that the second argument of my plot function is correct?
Let's give a more concrete case. You want a function called, you know, foo plot that is just going to feed itself to plot, but with special options set for plot.
Right.
And the question is, can you test foo plot on the way in, or do you have to wait until it gets all the way to plot and then fail?
If you write code that's specific to, you know, the, the argument structure you want for flu plot, you can write test code for it. But that, you know, what I'm trying to say is that we should be tempering our hopes with reality here. This is basically going to be a syntactic task, plus maybe case by case details, if we want to go that far. I don't think Roman does. He's. He's got general functions to deal with. He can't afford to. To write special code for every possible input to. To test for validity.
Okay. What I'm suggesting here is something I've really wanted for a long time. It is semantic plausibility. Okay? There are cases, just like there are cases where you can confuse syntax coloring, where you can have things which are syntactically correct, but. Or for example, scoping, but the scoping coloring doesn't know that.
Yes, that does happen.
It's rare though. It's very rare. And the question, I think with X.
Equals X, does it? But. But that's not commonly done even, Even though it's legitimate.
That's right.
I must be, I'll have to find a different example.
Okay, all right, fine. There are cases where you can do it. Question. I mean, okay, so first point is semantic plausibility. That, you know, it's just like spell checking. Yes. There are words that are, you know, correct spelling. You know, there are words we didn't know. Like, like we didn't know the word. I think, I think as of yesterday, at least, we didn't know the word poly algorithm. Okay. Which is a, you know, it's a somewhat valid word.
I, I, I, I protest to use of the word we.
No, no, I, I said we as in the spell checking system.
Oh, I thought it wasn't in our dictionary.
Yeah, I thought you had elevated yourself to royalty for a moment.
No, I was, I was not really they, no, but I mean, my point is, if we could do the same sort of thing with spell checking, this is what we planned for several years for code assistance. And we could tag something where somebody says this thing here. If we could put a squiggly line underneath the foo here, we would be very happy.
Ultimately, I think that boils down to syntactic.
Well, I mean, that putting, right, putting the squiggly there is. Right. That, right. That's a different, I mean, I guess the question is, is this before or after. Is this having, Is this putting the squiggly line in real time or is this, you know, after you've clicked on check code? Because if you click check code, we could absolutely do that. If you want this in real time. Well, now you need the box parser to somehow figure out the second.
Let's assume that there's some check code mechanism.
Okay.
Let's not worry about the implementation. The question is, you know, what we want. There is a soft failure of there's a squiggly, but you could still evaluate it.
Yeah, that seems absolutely plausible.
And that's what we were trying to do with the Code Assistance project. And that's what, you know, various LLM plays that we've tried to do are pushing for the same thing. You know, the LLM is kind of telling you what it thinks is kind of normal and customary, so to speak.
And, but normal, customary comes down eventually to this came up in different mail today. But to BNF for the expression.
Pre.
Evaluation based on the documented usage.
Yes.
So foo is supposed to be a list or, you know, some such. And it's not therefore, so it really does come down to syntactic checking.
In that case, it does. I think there are the cases where it isn't.
I mean, the interesting thing is if you type a correct list of x comma 01 there, it does syntax color it. So it knows about that list. And so it could probably just turn that way if. If it's not.
Well, I know in that particular case, but, you know, okay, here we've got a case. Where the heck is it doing there? Why isn't it.
Because the. The wrong kind of places. Right.
Well, I know, but why isn't that flagged as an error? Why is that. Why does that look like it's just completely harmless, yet? It's.
Wow, it's wet. It's wet on the right.
I know, it's. Yeah, I just did a. I just pressed shift enter. Why on earth does that not indicate. Okay, this is something for our user assistance meeting.
I think this has been brought up in User Assistance before and it just hasn't been implemented.
Okay, well, I'm providing.
And probably the reason this wasn't initially implemented was because. It was a somewhat later concept that some kinds of highlighting should not happen when the cursor is in the right place. So you wouldn't want this highlight to pop up as you're typing. But if you move the cursor away, then, yes, it should pop up.
Okay, fine. So that's just a case that should be covered. Yes, but agreed. You know that thing said. I don't know if this is valid. I think this is valid. I think there is a. A meaning to this, isn't there?
No, it's got a headless expression.
No, no, this one.
Oh, oh, oh, oh.
I don't think plot has.
Discontinuities like. Like an integrate does.
It's possible that it's one of those things that was at one point and then. But it was never documented because we had the exclusions option. And so.
Okay, my point is that this should be tagged as being implausible at best. Implausible, if not just wrong.
I mean, in principle, there's nothing wrong with that. But the problem is that this is. We benefited for a lot of our current syntax highlighting. We benefited from the natural structure of our documentation, and we were able to not have to do a lot of work by basically just processing our documentation. The structure of our documentation does not help us with cases like this, though. If. If we tried to make presumptions from what we saw in the documentation, it would go wrong too many times for it to be having worth doing. In the first place?
Well, John.
John, for it would. It would take the documentation for plot itself, Correct? Yeah. And wouldn't that.
And by which I mean the usage messages.
Right, right, right. And don't they only allow Lists of length 3 or am I wrong about that?
The problem is that there are many cases where.
The.
I mean, for plot, yes.
Well, actually for plot, no, because there's a case for including symbolic wrappers.
Can I make a suggestion here?
Okay, yeah. So even in plot it goes bad, and in other functions it will be worse.
Okay, Right. One possible idea is to have a. I wouldn't call it normal and customary. I would say communal garden bnf, which means, you know. So the question is there are things where it's like, you know, or more to the point, our kind of patterns. Right. There. There's the communal garden pattern, which is like, this is a very common case. This is what it should do. There's the sort of. Well, it doesn't even. There's the kind of. There's allowed patterns and there's maybe something in the middle that's the kind of normal and customary patterns functions. Not a weird case. And, you know, clearly, I think we all have agreed for years that it will be useful to have a pattern. You know, we. We've opposed making a pattern specification for what the argument structures for all the functions should be because there are cases that are still quite valid, but they're more like expert weird cases. Am I making sense? So the question is, is it worth our while to come up with what we could call normal and customary, let's say, patterns that admittedly don't cover the weird cases? What do we do with it? Let's say we had a broad coverage of normal and customary patterns. What would we then do? You know, could we imagine some UX that indicates, oh, there could be a problem here? But you don't, you know, it's not really important. I bet there's a way to do that. I don't think we thought that through. And that will be quite useful because it's kind of like, you see that it's not following the normal and customary, but it's okay. And you have an easy way to kind of type. Okay, let me give an analogy. Okay. If you say F open bracket, wherever I'm typing. I don't know where I'm typing. Yeah, wrong place. If I say F, open bracket. Oh, because we've done. Okay, let's. Let's imagine that we get rid of that bracket. Okay, there. Okay. Now, You know, that's indicated. Oh, there's something fishy with that, that open bracket. But that open bracket goes back to being a, you know, a calm color as soon as I fill something in. So my question would be if you've got something, you know, could we have something where we indicate that it isn't normal and customary, but there's a very easy and natural way that you are continuing to type and thereby saying, well, I actually want to use that anyway, even though you just told me it wasn't normal and customary. So I'm saying because I mean the other case, if you just see it flash up with some weird coloration in this case that's perfectly okay because you just know, oh, that wasn't complete. I'm going to keep going.
Here's an example of such things today. If I look at a module code with a module in it, my normal expectation is that everything inside there is going to be black or module colored. Except oh wait, look, there's a global inside there. Oh, but I did want a global in this particular case. So that's okay.
Sure. Yeah, that, that's right. I mean, so my, my claim is that if we had the coverage to have the patterns for everything, we could do ux, that makes sense. Which suggests that we should try and get those patterns, which we could start off with documentation, maybe use an LLM to get some of it.
And now, and, and, and, and that, and that is my big concern. The, you know, the level of information that we're getting now, as I said, comes straight from the documentation and it's not error free from the documentation. I would estimate that, you know, documentation as it's being added has maybe something like a 2 or 3% error rate and that's manageable. These turn into bug reports and you know, sometimes the people who wrote the documentation don't know what to do. So it comes to somebody like Brian V or myself and we fix it and we can manage that. But so yeah, a 2 or 3% error rate, we can manage a 75% error rate. That's a real problem. Right.
But I mean, we can also reduce that error rate by looking for example at our tests and seeing whether there are ones that are conflictive tests that weren't supposed to generate a message and are they conflictive, so to speak, with what we've said, with the patterns that we give. I'm more worried about the case where some function definition just has a great big dot dot dot in it and you know, where then that converts into, well, anything goes and we don't have any.
Well, and plot falls into that category.
Yeah, we actually already, you know, there are some functions where we have to take the dot dot dot version and. And intentionally exclude it from our current rule set because. Doesn't really mean. It just means, well, look at the above and kind of, you know, make a human presumption about what follows.
Yes. Well, okay, fair enough.
That's not a majority of functions, though, right?
It's not a majority.
It's a larger fraction than you think.
Yeah, it's a lot.
Okay.
I mean, you know, we could even give you a count because those, you know, those exclusion markings, they're in the author notebooks and it would be easy enough to see how many there are, but, I mean, I've added quite a number of them. I've seen many more, so.
Okay. I think it's worth our while to explore further this idea of making pattern specifications for all argument, you know, for the normal and customary argument structures. I think that's useful. I think it's a really good direction. Now, next, let's just loop back to the original question here about message spoofing.
I mean, that. That's fine, and we don't have to answer this here, but my main concern is I don't know how that happens. I don't even know where it happens in the company with what group who manages it and such.
Right.
You just volunteered, John.
No, I think it's. I think it branches off from documentation. I think it's part of that, enhancing that, and that group needs additional help. So, yeah, I think that's where it should go.
But message, if that were done, we could then add more infrastructure to the front end. That infrastructure doesn't exist right now because we didn't need it. But we could add it, it wouldn't be crazy. And then we could support better syntax highlighting as well.
Actually, you know, Michael and Eric Weinstein folks, they who did Wolfram language data, they might be a good place to go for this. Let's explore that. Okay. All right. Spoofing for a second and then we should wrap here very soon.
It might be relevant to mention one of the topics we discussed. There was an error handling work this morning was the question of how do we turn, you know, functions that currently issue messages into failures automatically? Which I think is kind of related to what's happening here because it makes me think that, like, if such a function existed right then instead of doing this, what, to me at least seems somewhat hacky message reissuing idea, where you're kind of catching A message and then, you know, raising it again, just make it a failure.
Have the outer function deal with the failure.
Wait, you've got two different use cases here. These are two, I think, very different use cases. Sometimes you just want to change the header on a message, but otherwise let things continue to evaluate. Sometimes you want check and you catch the message and issue a failure, return a failure instead. These are very different use cases. Both important, but different.
Well, I think my thought was that the relation is if you can catch the message at the lower level, like you mentioned an example of like a function that internally uses solve somewhere, right? If instead you catch that message and transmute it into a failure at the point you call solve, you can just use normal control flow however you want to get it back up to your top level function where you would be using message reissue and instead at that point just process that failure object however you want. Print the same message. Print a new message that uses some of the arguments from the original message, whatever it may be.
The use case for this is things like log plot calls plot and I don't want to have log plot do all of the option processing again.
But.
I want it to come back as log plot messages instead of plot messages. In the case where it doesn't necessarily return unevaluated, it just says, you know, hey, this setting was wrong or you know, that sort of thing.
Yeah, my use case might be, I call solve solve. Throws some message from together but continues on its merry way and gives result. You know, I mean, yes, I might want to just suppress that together message entirely, but if I don't, I don't want to stop everything dead at that point and not get the solve result.
Okay, listen, listen. One of the problems is this. If we were to just re skin a message, spoof its head, it's going to mess up documentation of that message. You know, if you've replaced that message with a, you know, a solve message and it was really a together message that was, you know, reskinned for solve, everything is going to get confused.
We've been doing this for eight long years.
It's not a general message.
Yes, assuming it's not a general message.
I'm afraid we have been doing this.
I know we've been doing, I know we've been doing this, but if we add this to user code, it's going to get much more confused. But what I'm suggesting is maybe what we want is a different way of displaying the message so that the outer. So that you see both of these things so you can see, maybe it's in the dot, dot, dots. You can see the fact that it came from together and it was a together message. But you know, the issue is what is that word there? And then when you look underneath here, where you see the plot, you know, let's say that said together, blah, blah, blah. Even though this was its, you know, you know, what I'm saying was it's, it's.
That would be fine, I think if, if we can arrange, you know, manage that and it doesn't mess up the messaging system and documentation, that, that look and feel would be fine, I think.
Okay, so fine. So the question is, okay, then there's.
The question of which message name do you use in check. And of course also in, in, you know, a standalone kernel where you don't have this repetition.
Well, I think, I think then the answer to that is you get the raw thing. This is a pure decoration. This is a, this is a pure piece of wrapping paper.
That sounds like the right thing.
Yeah.
Can I ask, because I'm less familiar with the visualization system and the, what.
Are you calling the raw thing?
I'm saying the together colon, whatever it is the actual thing of which this message is the thing that's going to give you the content of the message.
Okay.
Right.
So you'll only ever see the, the plot, colon, colon. If you're calling this in the front end, you mean this plot?
Yes. You'd only see the decoration if you're using it in the front end. Probably. I don't know. That's a different issue. That's a different issue. We could imagine yet a different way of displaying it in a RAW kernel.
We could have lock, column, plot, colon, colon, tag.
Yeah, something like that. Except we've used that for something else with message, different languages.
Log, plot, slash, plot, maybe like with diminishing font size, styling. But I wanted to ask, what is the right way for us to think about this? I mean, are we talking is like, to me it feels like it's something like when one part of top level system functionality is implemented using another piece of top level system functionality, we're kind of trying to hide that as like an implementation detail. Is that the motivation?
Yes, that's correct. Right, that's motivation. It's what is the thing that is taking responsibility versus. I mean, it's like, it's like the endless cases where somebody has licensed some technology from some other company and if you look inside, you discover it was from Foo Corporation. But on the outside, all the wrapping says it's Spa Corporation.
Right. So it's, like, white labeled plot redistributed as exactly right?
The. Yes. All right, we should wrap this meeting, but.
Okay, well, we'll think just through and probably bring it back to a future meeting.
Sounds good. All right, thanks a lot, guys. See you all soon.
Bye.
Thanks.
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






