Live CEOing Ep 746: Language Design in the Wolfram Language [Engine Connectivity Engineering]

This content was created by Guy Kawasaki. This content was uploaded by Guy Kawasaki. This is a YouTube video titled "Live CEOing Ep 746: Language Design in the Wolfram Language [Engine Connectivity Engineering]". It features a live stream discussion from September 29, 2023, led by Stephen Wolfram with Connor Gray and another speaker, focusing on error handling and function naming conventions in the Wolfram Language. The conversation explores the design and implementation of new error handling mechanisms, including the use of tags and failure objects.
Chapters
Okay. Hi, everyone. We have slightly different kind of live stream today. We are looking at a different group that hasn't been doing live stream meetings. This is part of our core software engineering effort and we are looking at error handling in Wolfram language. New approach to that. So where do we want to start here?
So I thought we could start with. I mean, it's worth saying all of this functionality is highly experimental. We expect a lot of the parts of the design to change. I thought what we could look at today as a follow up to a live stream from last week is naming for many of these functions. We think we have a good understanding. Yeah. Of the basic functionality, but the names could definitely be improved.
So where's the guide page where I can actually see these functions? It's right here.
Yeah.
Okay, so let's start off. So I'm trying to remember this. Raise and handle are both instant action functions. Right. They break the control flow. Correct.
Correct.
By the way, does anybody know what happened to the fail safe function?
My understanding is that Christopher was working on that.
Okay, all right, fine. But. But its name has not changed. It's. It's. That's its name, right?
That's my knowledge. That's correct.
Current name. I don't. I don't know if that is believed to be the file name. I like that name. But the reason I'm bringing that up is because I think that's a naming convention that. I mean, what failsafe does is it evaluates EXPA and what happens if that. What is the deal here if that fails? Remind me how this works. Somebody remind me how this works.
Yeah, I have to go. And.
Yeah, look, Christopher's not here. Christopher's. The. This is. This is actually, you know, it's always on the potential agenda for these ECE meetings, but Christopher's not here, so. Okay, well, fine. We have to do it the time when Christopher is here. But I just. It's roughly this. Right. It's trying to evaluate something, and if it fails, it's going to the failure case and cleaning itself up, as I recall.
Yeah, here, I'm gonna. Christopher. Christopher. Sorry, Stephen, I'm sending you an email right now with Christopher's examples notebook.
Okay, let me just.
Oh, something is some reason I can't. All right, give me just a sec. Okay, Momentarily. All right, copy that to the email. All right, I just sent that to you and Dec.
Okay. All right. I just. I just want to understand this. But then what are things like a prize? Is that a real thing or is that something that's I mean, it's not a.
It's a placeholder name for the concept of kind of the repl. Like a structured replacement for messages or alternative to messages.
I see.
So a prize was. I mean, we had some other things like advise, emit, note, inform, things along those lines.
Okay, okay, okay, so. Oh, I see what this is doing. Yeah, this is a good function, piece of functionality. Right. Okay, so I understand this functionality. I think. Okay, this is the key example. I think an interesting function, like, just don't do anything if you don't see the food. If. If the thing you're being fed is poisonous, don't eat it would be one summary. Okay, let's start taking a look at these things. So where do we want to start here? What is the.
So in that same email I sent you, I also sent the kind of the basic examples notebook from our last meeting. So I think the place that we ended up in that meeting was a discussion of this set fallthrough error function, which even for its current behavior, is not a great name. Okay, I think that's about halfway down.
All right. So thing I don't like about rays as a name is that, you know, it breaks the control flow and raise just seems like, oh, you're putting up a flag, you know, oh, you know, hello, I'm, you know, whatever thr, for example, indicates clearly something is happening now, here and now.
Yeah, I. I'm partial to the name. And actually this exists in that you'll notice if in that output from the question mark, the information command you did, there's the symbol fail is defined and it's currently just an alias for raise. I guess it was failed 2. It's actually fail 2 because fail is a system symbol already, though it's used in an extremely esoteric way.
How is it used?
My understanding is it's a magic sentinel value that's part of the rule condition implementation in C code in the kernel.
Oh, yeah, yeah, right. It's from version point 8. Part of the thing that never got finished.
Yeah.
Part of the mechanism for backing out of a rule.
Yeah. So it's. I mean, it's never been documented in its form, and it's.
Okay, I don't think. I don't think we have to preserve that. Yeah, I don't think it will be in. It's not in code, it's not in a notebook anywhere. It's just an internal thing. Yeah, well, I mean, given that failure is being. What's being. I don't know. What's the argument to it. If it's fail, what is its argument?
Well, if its arguments were the same as raise, they would be essentially the same as the argument structure for failure. A tag, an association of no properties and some kind of error message, optionally. Yeah, I mean really the only required argument is the tag and all the other arguments kind of have default values of no message, no extra properties.
Do you need the tag? Can we have a generic tag like. Well, that's the disaster of throw, that it has a generic tag.
I'm sorry, when I say tag, I'm not talking about the tag that's used for throwing and catching. I'm talking about the tag of the failure object. Our design for raise is that it has. It's not a user controllable tag, it's a fixed value. Every invocation of raise has the same tag.
I'm totally confused. What's the error about?
So that's the tag. I'm referring to the error tag. And this is an existing thing you were talking about.
The throw tag is fixed. Yes, I know.
Yes, the throw tag is. I'm sorry, okay, yes, yeah, throw tag is fixed. This tag is variable. It's the same notion of, you know, it's kind of a machine readable string or symbol that is meant to impart some semantic information about the failure that was thrown, what type of failure it is. Currently we don't have a lot of infrastructure for handling these things based on these tags, so the tags are in some sense arbitrary. But building that infrastructure is something we'd like to see happen.
Also, in a way, tags are the whole reason why how this is different from catch and throw because tags could be organized in hierarchies and basically if you are building your own module, you can define a root tag for that module and all the sub errors of that module could be caught within a single handle statement with that tag.
Okay, well, I don't understand. How is the tag hierarchical by your choice or.
Yeah, correct. You can. When you define your error type, you can define what the parents of that error type are, which tags are apparent tags for that.
Okay, so it's not okay.
If you want to see an example of that, copy that. Create error type of foo error. Yeah, why don't we put this all in the right notebook, I guess, and go ahead and evaluate that and then duplicate it. New input, same idea. But change foo error to bar error and then put foo error as an element of that list and then do raise of bar error. And I think you'll need to put it in just. Just to put in some, you know, an error occurred kind of String as the second argument. Yeah.
Okay.
And go ahead and evaluate that. Evaluate that so you can see what came out as a failure that has two tags. We're doing tag expansion is what we call it, to get the fully elaborated set of tags that annotate this failure.
Okay, Okay, but, but okay, let's just understand. All right, so raise and handle are the main functions. Raise is breaking the control flow and with better tagging than throw is going to the nearest enclosing handle or the nearest catching enclosing handle. Is that correct?
Yes. Yeah. The nearest handle that has a pattern that matches the thrown failure and the tags should match.
So if your handle basically catches different tags, it may still pass this race through or, you know, up until the handle that has that tag called.
Have you guys been actually trying to write code with these mechanisms?
Yeah.
Okay. All right, so the primary functions here. What the heck is this?
Create failure that is added mostly as a worker function for rays. So raise, you'll notice it has this argument structure where it can take a string as an argument and then a sequence of format parameters after it. Create failure is. Is just how that failure gets created. That raise then throws. So if you want to create a.
Failure, I mean, create in our world is. Is creating something which is a. A, you know, like a resource global thing.
Yeah, it is the wrong name.
So what is it again?
Well, go ahead and just where you have rays below in. In five, just change that to Create failure. It's. It's just constructing the failure that raise throws.
Okay. What really is this? This is a tagged failure. Is that right? Or is it failure? I mean, what is it? It's taking this which would otherwise in its natural form be just failure of bar error comma, Hello? Well, no, it's. It's okay.
It's entirely. Sorry. Yeah, well, it's entirely. I mean, Create failure does two things that we think are useful. It does the tag expansion and it has this more convenient syntax for setting the message of the failure the second one. Certainly. I think there's an argument that that might eventually just be part of what failure does. That if you have a multi argument failure where the second argument is not an association.
Yeah, I think so.
And also, also, Connor, what I think we missed mentioning here is that Create failure creates those failure objects that are specialized for this error handling mechanism. So while we still use failure objects rather than special error objects or something like that, they will have some special fields that only are that belong to this error handling mechanism, the new one that we're suggesting. And so create failure will take care of properly creating these failure objects or these additional fields.
What additional fields? I don't see any additional fields.
One thing we've talked about is stack traces. So having some flag you can set to insert a stack trace at the original origin point of a failure or.
Caused by field which will basically contain some internal failure that is causing this one, which will appear in some cases.
Well, yeah, I mean, caused by is certainly field, but I don't, I mean, I don't think it would be create failure that adds caused by in and of itself.
Where are we storing this, please, Aubrey, where are we storing this?
I don't know that we. I don't think that we have existing notes on the error handling working group in your hierarchy.
Okay, all right.
Because most of our previous discussions.
Can we please remember from a project management point of view that we kind of need to know the answer to that every time we do one of these design meetings. Okay, go ahead. So you're saying this might be something where. Where this has to pull in current. You know, this is pulling in current state from. You know, it's a version of failure, version of failure that auto populates current state. Is that correct?
Yeah, roughly. I mean, auto populates current state. It also, it does again, it does the tag expansion and it has that more convenient syntax for error message.
The thing that's really real here is that it's pulling in a stack trace. It's doing, caused by. It's doing all those kinds of things which depend on the current place where it is in the code. It's a sort of code execution context dependent thing. That's its main reasons to exist. I mean, saying, oh well, it's just modifying some syntax here and there is really not a very convincing reason to exist and probably should be handled elsewhere.
There is one more reason, Stephen, and that is that we eventually want to unify, confirm and close and the exception mechanisms, at least so that they could still operate on the same failure objects or similarly typed failure objects. So in that sense, having the create failure or whatever name we choose for this as a separate function might, Might allow us to also propagate similarly formed failures through confirms and close. If we, if we decide so, so if we.
See, I don't understand. I mean, yes, it's a failure object. That's what we want. We want this thing, whatever this thing is, it returns a failure object that then does what it does. Yeah, this is a way of building A failure object that contains current state information that would not otherwise be. If you just constructed a failure object by typing it in, you would not put that in there, but you could put it in there, but you would not typically put it in there. Right?
Yeah, sure.
And I mean, it's. None of these names are good, but it is essentially a code. It is a. It represents a, you know, a failure state or something. None of these are good names, but it represents. The main thing we're getting at here is that this is capturing the current state.
I mean, capture failure, construct failure. Because I think it's, it's, it's what you want to emphasize. It's like. Yeah, it is what's happening right now. This is not a failure that was created a while ago. It's. There's something special that's happening based on this place.
I'm not sure. I'm not sure. But, but I think we've got the general sense of this here. That. So let's keep going. Okay.
Yeah.
All right. The next big function is raise.
Yeah.
Correct. I mean, let's just take it, Take a little look here. I mean, I don't know why we're not. Do we think that arrays is always an error? I mean, it's throwing a failure object. So if you're kind of using it as an el. Cheapo control flow, you know, modifier, you know, you're going through the marsh of failure, so to speak. That makes sense.
Yeah.
So I don't think, you know, having the word error in the name doesn't seem obviously wrong.
Yeah, I don't definitely, don't disagree. I mean, I personally like the name fail because it's. I mean, it almost couldn't be any more obvious. It's the verb form of the noun that it's creating, like it's a failure.
It's doing more than that. I mean, I think it's fail doesn't seem quite right because it's like, well, you're saying I have a piece of code and saying if X is greater than zero, fail. Yeah, it's not terrible. What are some other code fragments that it could appear in?
I mean, it's often going to be something conditional like that.
Well, or is it going to be. What about a confirm, like thing? I mean, confirm has various ways that it, you know, in, in other words, if it says. I mean, let's just understand this thing. Let's say you say confirm quiet. Remind me what confirm is going to do here? So confirm quiet. If it isn't quiet, it Throws a failure to the enclosing and close, Correct?
Yeah.
Okay, so what's the difference between it doing that and a raise and handle? You get what I'm saying?
Yeah, non locality.
What do you mean by non locality?
I mean that the most the dominant way to use confirm and close is without tags when they're lexical. While what raise and handle do is non local in the sense that the raised failure will propagate up until it finds on up the stack the first handle that catches it.
So why isn't confirm with a tag the same as raise?
It's almost the same. But the problem is now we face the problem of identity of an error. What this failure that we are currently propagating does is that it embeds its own identity, that it can be caught by handle in a self contained way. While when you do confirm and enclose with the tag, you essentially face almost the same issue as the catch and throw with the tag. The tags exist separately from the actual thing that you're propagating and they have to be externally added to the picture.
Okay, let's walk through this again. Okay. What would happen? I still want to understand. This sounds crazy to me. I mean, it seems to me that we should make somehow confirm with a tag B raise and handle. Walk me through how we would do that. Okay, so confirm without a tag has all this lexical stuff, which is very nice locally. Right. But now confirm with a tag looks like what?
Well, so if you want to, I mean, if you want to look at the open example of confirm, what I actually did, like before this effort really got underway, what I've done a lot of projects is I use confirm to initiate my failures. But it's kind of verbose because what you have to do is I essentially would do, you know, confirm at a failure object because that was the easiest way to kind of initiate a failure using confirm.
Okay, well then let's see whether we can capture that here. I mean, if, if we've already got the confirming close mechanism, which is a pretty nice mechanism, and you know, teaching people 75 other different ways to say the same thing. Throw, catch, raise, handle, you know, confirming close, you know, it doesn't seem right, but the problem that you're saying is that there's an el cheapo version of confirming close, which is the local lexical thing, and then there's the non local version which you say has to be, has to enclose a bunch of state. And right now the syntax for doing that is messy.
Yeah, let me see if.
So, how do we make it less messy? What does it have to. Yeah, can you give me some code that will do this?
Yeah, so. Well, I'm sorry, I'm trying to find an example of what, you know, it looks like to translate a. You know, what I was doing previously to this. This is going to be a little messy, but. So this is not exactly right, but I'm going to put this example in the Zoom chat. There we go, pasting it. Now, this is an error from the Packlet Tools project. Now, it's for various reasons. It's using Failure Message, which is a different utility I wrote. But for the moment, let's pretend that this is a failure object. So this is inside of. Actually, I guess you probably want the context for this as well. I'll give you actually a better example, kind of what this looks like in code, where you might initiate this. All right, just put another example in the Zoom Chat, perhaps easier. So formatting is a bit odd, but what's happening here is I'm testing some condition. I need to make sure that the thing that the user has passed is a list, a valid list. And if it's not, I'm initiating an error condition. So the function the snippet is from is wrapped in enclose, and this is where I'm initiating a new error. So I think our design questions here is, could we simplify what's written there into a syntax that works with confirm but has the same outcome? And I'm sure the answer is yes.
I mean, by exactly doing. I mean, I'm confused because I thought confirm usually just had an expression in it and that it only does that if the expression. I see what you're doing here is you're pre wiring the fact that it's an error.
Yes. Which is, I think, quite important. You know, you want it to be as low effort as possible for. For the developer to initiate an error because people are lazy. And if it's. If there's a lot of ceremony involved in doing that, people will try to do it as little as possible.
Yeah, of course. But I mean, I think that. Okay, so what you're saying is that it's a guaranteed failing. Confirm is one approach.
Yeah.
Because what's happening here is, whereas Confirm says, let me check this, and if it fails, blow up.
Okay.
What this is, is a blow up, you know, definitively blow up.
Yeah.
Which just raised. Just completely, utterly does not get that idea across. Now, I mean, one question is, could we have enclose catch whatever it is that is the semantics of enclose, right. For catching the thing, let's say you say, you know, fail now, whatever it is. That's the thing. I mean, confirm blows up if it sees a failure, right. So sort of the natural thing to do would be to say essentially fail now. Yeah, your version of fail. But I think it might be clearer to just say fail now.
Yeah.
And then the question is, could that now be caught just like you have Confirm says if it. If it is a failure, then fail. But fail now is just a definitive failure. I thought Christopher and I like a couple of years ago, we should arrange this meeting at a time when Christopher can come the. Had a. Had a version of this and when we were talking about the confirmed design, we should ask about that. But okay, let's assume it's called fail now for now and that that does what raise does. Basically now the question is do we need handle or can enclose be the thing that catches a fail now?
Yeah. So if you look at the syntax for enclose, it is. I mean, it's one argument form is not an operator, which is one of the things that we. You'll mention you liked about handle in the last meeting is that it's an operator. You can see an example on the left there. The notebook on the far left of your screen. The ability to have, you know, an operator form where the rules, the pattern that's being matched is something you can prefix before your function. Definition is very, very useful for readability. Enclosed doesn't really have that property because it's one argument form is already defined. It's possible that it's two argument form. You know, it's currently. Its two argument form is a function that gets applied to object generated. Presumably we could define that so that if that second argument is a pattern, you know, a rule or a list of rules.
Then this is still not the operator form. By the way. I don't know why there's a space at the beginning of that. I mean, just a bug. Oh my God. Don't. You can't be serious. That this stupid raft is broken again in this prototype build. It better not be the case. We've been through that like 18 times and making sure this actually comes up. See that space? That's a bug. Aubrey, please make sure that supported. I don't understand why this raft went away at that time. It shouldn't go away when I just mouse down there. It shouldn't go away when I mouse into that. That region there. Okay. I mean, I don't know how Many times I have to, you know, define this. Can we please take that to the user assistance group? Tell them to fix that.
Yep, we'll.
Do you understand the issue? Do you understand the issue? If I'm over that thing, there it stays. But if I go there, which is what I would. Where I would go to start typing the arguments to the function, which is precisely when I need the raft up, it goes away.
Yep, I understand.
Okay, all right, so look, the thing that. No, no, that's not. But what is it really? It's really. Handle is the totally the wrong name for this because it's, it's. Okay, what does it exactly do now?
So if that F is a pattern or a set of rules and a fail now within experiments is. Is thrown and the thing that's thrown matches that pattern, then it will be caught and that will be the evaluation result of that whole sub value form.
Okay, well we got to have a name that says that which is not handle.
Yeah.
Okay, so. I mean it's closer to something like Catch failure.
Yeah. Actually one of the things I have in my notes is this idea of a name like Try Catch, which at the very. I mean, it's. It. That name has other problems, but it, at least it has catch in it and it's consistent with what this form is most similar to in other systems, which is literal. You know, there's a block that you're trying and if something goes wrong, those rules you're using to catch.
I don't particularly like that naming.
Yeah.
Okay, so this operator form, we have all these applied family like, you know, reverse. It's a little different, isn't it? Reverse supplied F X, Y. This is a little different because this is not. This is a decorator of EXPA. That catches a problem inside expa.
Yeah, I think the thing that's very unusual about this is that it's a sub value thing that holds the subvalue arguments. I don't know that there's a lot like that in the system at the moment. I mean, I think there can't be because it's kind of a hack how it works. It returns a function with hold first attribute.
It's a little weird because. Okay, let me, let me try and say it some more. This is. Okay, let's just understand. We got these things, okay, You've got this notion of an error type. Let's try and try and boil down. Okay, we've got fail now, which should be catchable by an enclose, I think. But then we've got this alternative form, which is like a confirm, is it not.
Steven? It's not. Because confirm actually tests and then it blows up. While this has a opposite nature, it actually catches and returns. It doesn't propagate through just returns.
Returns. What if.
So it stops the. It stops the bubbling of this failure object up the stack.
What do you mean it stops it? It generates a failure object. If expert. I don't understand.
If expert throws a fail. Right. If expert throws a failure, failure monitor stops that failure. It catches it and returns it what Returns the. It returns a failure.
Okay, what does enclosed do relative to that?
Enclosed does a similar thing.
Sorry, that's no good. We're not going to have two functions with completely different naming conventions that do more or less the same thing. I mean, enclosed.
Yeah, I don't disagree. Then it had to be different for us to explore the behavior, though. That's why we're having a discussion about naming.
Okay, but I mean, so explain to me what's different between the enclose of expert, okay, which if it's a failure object. If Expo is a failure object, then enclose catches that failure, which has been bubbling up right from a confirm. It bubbled through a throw. It was caught by the enclosed, which is extremely similar to the behavior of fail now bubbling up. And it's caught by the. The only difference is fail now, which I'm pretty sure we had a name for when we were designing Confirming Close. Is the imperative form of confirm. Or something is the just fail form of confirm. Okay. Which can be dressed in different ways, but that's basically what it is. Okay, so then. Okay, so that would naturally be caught. That is producing a failure object, which is dressed in some complicated way, but that would be naturally caught by an enclose. But generically the one argument in close. Well, the one argument in close has this lexicalism, but maybe. I don't know whether. Does one argument in close only catch things lexically? Or could one argument enclose if it does not find a confirm that matches it, that it can go to a dynamic, you know, tag handling?
I think it would be a bad idea.
I mean, it's a question of what.
Christopher, to discuss this. Okay.
Yeah.
I mean, when he couldn't come. Okay. Anyway, go on.
Yeah, well, it's, it's. I mean, there's. There's a question of. I mean, is it technically possible for enclosed to do that? Probably. And that might be worth doing. But then there's also. Does it. Does it. Is it in violation of people's expectations. Existing users of confirm and close, like is it too weird that this thing is trying to do it has already pretty subtle lexical behavior. You know, confirm and closer. There's not a lot of like them in the system. So their, their behavior, their existing behavior is already very subtle. If there was this additional subtlety that enclose also has non lex.
So long as it does the right thing for people. I think subtlety can be overlooked.
Yeah.
You know, because nobody would notice it. It's just it does the right thing. I mean there are plenty of situations in the system with all kinds of complicated scoping where nobody ever noticed, you know, it just does the right thing.
Yeah. So I think, I mean it'd be worth, I mean if we think of a slightly larger example. Right. I mean suppose enclose. I mean it could be as simple as export is a call to a function foo. Right. And foo inside of it has a fail now. Yeah, if enclose. I mean one of the other odd things about this is that we're very intentionally designing the system for it to be relatively easy for you to provide the pattern that says what you do and don't want to catch. I think it would work. I mean, let me propose something. So suppose enclose works non lexically and it's single argument form and we'll worry about the operator form thing later. But you know, enclose of expert will catch fail nows as well as confirms and fail now is from anywhere. The second question is how do we specify that the patterns we want to catch right now in close.
Yeah, sorry, go ahead.
No, no, well, I'm just, I'm just describing. So. So in close right now I think it would be helpful if you could do question mark and close just so this is on the screen. Yeah. Or have the docs so encloses second usage message. It's two argument form right now is essentially any expression. It's something that's going to get applied to the clot failure, the lexically caught failure. It would probably be possible for us without breaking back.
No, I know, I know, I know. To have to have some hack where that can be a pattern. I don't think that's useful. I think we should have another function that is called something like enclosed pattern which is a conditional enclose.
Yeah. Okay. Well if we're okay with having a different symbol just along with.
Enclose match or something enclose. Because then this, if we gave this the right name, then this could potentially have an operator form which would be exactly your current handle.
Yeah. So I will, I will have a.
Non operator form if you know, let's say we have enclosed pattern and it's not the right name.
Yeah.
I mean and you want a pattern here. It's not a test, it's a pattern.
Right, It's a pattern. Pattern or rules. Yeah.
Yeah. Let's say something like enclose matching.
Actually a good name.
I don't, I don't think it's quite right, but it's closer. Okay, so then now this takes a, I mean in its full form it could take, could be like this and then have an operator form that's enclosed matching. Pattern expert.
Yeah, exactly.
Now I do want to say the only thing I mean what I don't like about this name is that if this is explicitly, I mean it may also have the lexical behavior of enclose but it's. We're introducing this explicitly for much expanded non lexical usage. The word enclose to me doesn't say, it doesn't evoke any feelings of. This is about failures, this is about error handling, etc. It's meant to evoke the lexical behavior of confirm and close. That's I think why the name close was chosen.
No, it was, it was enclosed. The reason the name enclosed was, was chosen was because it. All kinds of muddiness happen inside the enclosure but the goats never get out where the goats in this case are failure objects.
Right.
Yeah, that was the idea. The idea was outside of the, of the enclose, it's all clean. You don't have to worry about propagating failures through the enclose. The enclose is going to enclose it. So I don't think this is. What's that?
Yeah, I just wanted to say that in that sense, since we catch only selective things with the. Where the tags match in certain way, then certain things will propagate through enclosed matching or whatever we name it which will not match the tags. So if your pattern is goat but.
Not human, humans can escape the enclosure but not the goats.
Indeed, that's the idea. It's like one of those cow, one of those things for cows on the, you know, the grills on the road type thing.
Yeah, it was true for the older enclosed as well. Of course if you use the tanks. So it's not new here.
Right. I mean the enclosure is imperfect. Now the question would be could confirm itself, end up sending through these stack trace type things and so on. I don't see why it Shouldn't.
Well, it's a question of the syntax it supports. I mean, right now, like, let's say we were to use the exact same syntax. I mean, that would not work directly because confirm, with the first argument of let's say a string that has existing meaning, it's like it should just return the string because it's not a failure.
Right, exactly. But, but I mean, I, I think that when. Okay, so I'm claiming, okay, let's imagine that we have a thing called failure structure, okay, which is your dressed, complicated failure thing. Okay. And that confirm is extended, so coughs up failure structures just like it coughs up failures, if you get what I'm saying.
But Stephen, let me ask then, how would we distinguish between confirms, which lexical and confirms that propagate these failure structures with tags which are non lexical? Should we just base that on presence of the tags in this failure, in this failure that we form?
Well, I was thinking, I mean, right now, confirm has a lexical form.
Yeah, but confirm's lexical form is not up to confirm. It's a property of enclose. Enclose does a rule replace on the body of the experts, enclosing to replace lexically placed confirms with like unique symbols that are how it actually accomplishes that. So it's. I think we should not think of this as a property of the enclose. You know, enclose. It depends on what's outside of it. So we don't have to change per se, what confirmed does to decide whether it's going to be lexical or not. We can just say any confirm that hasn't been replaced with one of these special confirms knows that it's not inside of an enclose and therefore is non lexical. So it's. We don't need special syntax to distinguish it. A non lexical versus lexical confirm.
The issue is, okay, let's take a fail now inside and enclose. Is there a sense in which the fail now should be paired with its enclosing enclose? I think yes. I think it's the same deal as with confirm. I think it's convenient to have this local lexical form as well as this. If there isn't, okay, if there is a confirm without a tag, it's going to be lexical, because what else could it do? What else is going to do? It's going to. Otherwise it's going to just. I don't know what it does. It's like throw. Then you might as well use throw.
Well, but the whole, the whole point of what we're trying to achieve here is a much more. I mean, not the whole point, but a big part of what we're trying to achieve here is the convenience of a, you know, a very short syntax for raising, you know, for throwing failures. It's not merely that.
Yeah, I understand, I understand, but I'm saying. You're saying a tagless, you have a tagless raise, but you don't have a tagless raise. You insist on having a tag in your raise.
Well, that's just so it doesn't, it doesn't conflict with people who are using tagless throw and catch in other places for control flow.
But wait a minute. Do you want a tagless raise or not?
We definitely don't want it.
Okay, fine. Then, then you have, then your minimal syntax involves some kind of tag. You've managed to make the tag simpler by using a create, what are you calling it? Create error type thing. Right? That's your way of defining, of aliasing, sort of assigning a name to an error type so that you don't have to write out a whole big thing.
Yeah, but it does a little bit more than that because now the tags get embedded into the object that we are propagating. They are not external to it.
Right. I mean, the point is that, yeah, it's a property of the thing that's thrown how it's tagged.
Okay, that's fine, but, but my point that I'm making is there's no conflict here. I mean, confirm with two arguments. You're going to have to have two arguments for this thing. Fail now. Well, actually, I don't understand. Fail now needs only one argument. It doesn't need an expert, it just needs the failure str. It just needs the tag, doesn't it?
Yes.
Okay, so that's fine. So then confirm. If it has a tag, it can have the same kind of tag that Fail now has. So in other words, if you've declared a tag, let's say you use confirm with. Of expert with what I could call a declared tag. Okay. Because I don't think the tags management right now is that wonderful. So having some notion of a declared tag, and this is also, if it is used in this form, it's either a declared tag or it's a Fail now with something which is essentially a failure structure. Right. With all that stuff explicitly pulled in. Am I right?
Yeah. I mean, just what is expert in this? In this and what duality? Well, yeah, even if, if, if we're trying to Say that fail now is. I think what you're trying to say, but correct me if I'm wrong, is that there's a fail now is equivalent to some more elaborate form of invoking confirm.
No, I'm not saying that. I'm not saying that.
Okay, then I'm confused what you're saying.
Okay, Confirm tests exper. Okay, so this might be a fail now. Might be equivalent to if failure queue expert, fail now.
Actually, it's confirmed. That's going to be equivalent to this.
Yeah, that's equivalent to confirm of exper, whatever, fail now of tag. That's what I'm saying.
Right.
And that's pretty nice, in my opinion.
Yeah, I agree. And actually, one of the syntaxes that I. You could imagine this doing, right. And I'm not sure we'd want to overload this behavior, but you could think of this as like. Yeah, it's. It's. It's just a convenient way to say this expert. And this is the same thing goes for Confirm Quiet and Confirm Match too. Right. Where you might want to say, if you don't provide a custom tag, then it's one kind of confirm. It's like this is a. You know, it's a default confirm with the default tag, which is the existing behavior of confirm. If you provide a custom tag and possibly also, you know, a seat, like a format string is a third argument and then a sequence of arguments after that. It's just a convenient way of saying if this is wrong, you know, if the confirm fails, then raise a failure with this custom tag and custom error message. Yeah, very.
To me. Yeah.
Yeah.
Right. And including the other things like confirm quiet and so on, which we don't want to have to have a raise if quiet type thing. And, you know, the whole point is we don't want to have to have an if, blah, blah, blah, raise. Yeah, sometimes you do want that. That's why we want fail now.
Exactly.
Yeah.
Yeah.
Okay, so then the question here is enclose, in its usual form, can take a tag, right? No, it doesn't. It takes. Takes a form.
I see, it takes a tag, Right.
As a last tag, As a third argument. Yeah, it takes a tag, but not very pleasantly. So the more common case would be that you say enclose matching.
Also in the enclosed matching, we could have several alternatives shown as rules, so that it can handle different exceptions at the same time, producing different outputs.
Definitely.
And that's a powerful capability.
Yeah. All right, but what is the right name for this? The right name for this is if it doesn't match pattern, Then it just blows right through. Right. It's a charging giraffe and it just goes right through the enclosure. Is that correct?
Yep.
Yeah. It's not enclosed.
Yeah.
Or formally enclose is also this way if it, if it's used with the tag and.
I understand. Third argument. Yes.
Yeah.
Yeah. I mean, this is, this is a good mechanism. I. It's close. Enclosed matching is close. I'm not sure it's, you know, I keep on thinking of enclose if. But it isn't. Right. Because it's not. That's a pattern. So I'm saying.
Yeah, I mean, is it like. I mean, enclose where it's kind of a condition that. That's not right either?
No, I mean, and. And the other thing which we also can't use is enclosed 4. Enclose for.
Yeah.
Okay. We're. We're close, but we're not quite there. But I think this, this mechanism. I think this is the right mechanism and close matching for this case. This is a good second. I mean, I. I think this is the right argument order for this. Now I think we want. Either register failure tag or set failure tag, depending on the syntax.
Yeah.
So what is that? What is the create error type syntax?
Its current syntax is the first argument is always a symbol. The second argument is always a list of symbols. But I think that this is like. I mean, I don't feel comfortable with the syntax, at least in sense of, like knowing that it's the final syntax. Because there's a number of things that we think we want to do but haven't done yet. For example, the ability to associate some kind of validation function with a tag. So you can say, you know, make sure that every tag and every failure raised with that tag has a particular property. Like, like, let's say that every, you know, file IO error has a file property and it's failures, and we don't have a syntax for that.
So we've got something like this. But then failure structure would be the thing that.
I mean, I don't like structure because it sounds like it's too much like data structure, which is kind of an inert thing. It's an object, it's not a verb. I mean, maybe construct failure.
Right. Because we basically want some special constructor.
Yeah, but we want. How about current failure? Because in a sense. Well, that isn't quite right, but the idea there is that it is. It is packaging up something about the current state.
Yeah, I mean, I think we're Imagining. Use stack, presumably. I don't. Failure stacks. Not a good name either. It's too specific.
Stacked failure. That's not the right. Either. Something.
I mean, maybe, maybe, I mean, begin failure. But that's not right. I mean, it's right in the sense that if, you know, it's something that's going to be thrown. It's like I, I want to know where this started. You know, I, I know. I'm just, I'm trying to.
I'm trying to explore just capturing the current state.
Maybe failure with state.
Yeah, but, but, but that suggests that it is. We want it to know that it's making a failure. I, I think having a prefix word to failure is okay.
I'm just throwing out some ideas, but make failure. Emit failure, Textual failure, Contextual failure. Yeah, that's not terrible.
Not quite. It's not quite right. But it's close.
It's close because we really want to capture that we are assembling the context to that failure of the error.
Exactly.
Yeah.
It also sounds like something that's parallel to failure. It creates a failure, it evaluates to failure.
It's not contextualized failure. We really want to make it long.
Yeah, but I mean, unfortunately we. Our notion of context is a different thing.
Yeah.
This is close. The concept is contextualized failure, where you.
Just need to be.
Sorry, go ahead.
Well, if it just needs to be a verb, I mean, contextualize failure.
Why is it a verb?
Because it's, It's. I want it. Because I think we want to get across the fact that it's doing something. It's capturing a stack trace. It's, you know, I don't know, looking at.
I think that's okay because it's also a failure that. I mean, what are its arguments?
A tag, an association, a string format, parameters, and then possibly options if you want to. Like at the call site. Explicitly disabled.
When you give a failure, you're also giving a tag and other things. Right. So this is a failure that has been contextualized.
Yes, exactly.
I don't think you're. By saying contextualize, I don't think you're saying that the context is something you have to feed in.
Mm.
Yeah. Conceptual. Contextualized already kind of implies that certain work has been done to create it.
Yeah, well, okay, these aren't quite right, but we're getting there. Okay. I think we've got contextualized failure. We've got enclosed matching, and we've got fail now. And then we've got some kind of set failure tag.
Yeah.
Or. Or even perhaps define failure tag.
Yeah, define is probably better.
Yeah, I think so, too, because set implies that some.
Something already existed. Well, define implies that we are making it up.
Yep. And, I mean, I think we've got a bunch of things in the compiler space that define whatever.
Yeah. I mean, I think one advantage of register is that naturally suggests the notion. It begs the question of unregistered failure tags, which I think we probably want to support, like that this. This machinery works even for tags that haven't been registered. But you can opt into additional behavior by registering.
Well, but the fact that you define a failure tag means just like you can use the symbol X without giving it.
Fair enough. Yeah.
All right, we should wrap, and we've got to go to another live stream meeting here. I think we make making good progress. Let's pick this up again before we've all forgotten how this works. Let's try to make sure Christopher can join the next time, and let's show him what we've got so far. So maybe somebody can summarize for him.
Sure. Can somebody. I mean, Stephen or somebody else here, who knows, figure out how to send me this notebook that Stephen's been taking notes into?
I assume Aubrey can.
Yeah, I can send it to you. Okay. Thank you, Aubrey.
Okay, see you all soon.
Thank you, everybody.
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






