 So here's my first slide, right? So here's what we have. So my current work so far, so I've been here for like 30 months now, right? And I've been mostly focused on synthesis up until now. So this was my first paper, it was made from the, it was part of my kind of, so I took my master's thesis project and then I did a little more extra work and then I kind of wrote it up as this paper and published it at the Haskell Symposium, right? And let me just show you what that involved. So it's embedded in Haskell, functional programming language, right? And so Haskell used to have this nice thing called typed homes, right? So you give an underscore and it says that it gives you some context information about the home, right? Usually what you do is that you do this in live code, right? And it would kind of figure out from the context the exact type of the code, but we can also use it here to give, you know, just give it a specific type, right? So, but what I did is that I extended this mechanism, right? And added this thing called valid homefits. So what happens now is that when you enter a typed home, it actually kind of searches the context and searches the scope and gives you everything in scope that has that type, right? So here's everything in scope by default from the payload that actually has the type bool. So we have, you know, otherwise false and true, but also because bool is bounded, we can do maxbound and minbound. And it's kind of showing how, you know, we're using the type checker to find everything in scope. And of course, this is not a very interesting type. So let's look at, you know, into int. There's like a list to int. And then we get more kind of general types, right? We could head and last. And it kind of figures out that, yeah, if you put the first type variable to be int, then this type matches. And another one here is like also length, right? And it says, well, if we match the two type variables, so the container is a list and the element is an int, then this would actually type check. And then I sent it a little bit further and I added these refinement level homefits. So here, so what happens now is that, so you can see here that if I search for a function from a list of ints to int, I just get kind of exact matches. But I added these refinement level homefits, right? So and then we search for the same home and we get the same fits as before, but we also get kind of fits with additional homes in them, right? So if I apply the function of fold L1 to something, through a function of type int to int to int, then the entire type of the function would match. So we kind of recursively structure the programs, right? And of course, like if I apply fold L with through a function and an initial value, then the function would match, right? So here we get the kind of the full, and we can go deeper and deeper, right? So and that was my, what I did in this paper, right? So then I extended that. So the trick with this thing is that, you know, the synthesis is very hard-coded. It's very much like kind of what I thought would work. And I wanted to extend it and also wanted to be able to play around with these homefits without having to fork the compiler, right? So this was a poster at ICFP and a talk at the Haskell Implemeters Workshop. And I actually got a second place in the student research competition for this poster. So and it was well received at ICFP. So that was in 2019. And so what you can do with this functionality is so Haskell as a language has this concept of plugins, right? So you can kind of extend the compiler by writing some code and then at certain phases of the compiler run that runs the plugins, right? So I forked GHD and I added this whole fit plugin thing to kind of give you options for how to deal with whole fits. And this is what a whole fit plugin looks like. So it takes in the typed home, which has some information about the scope and the kind of the values that, you know, the givens and kind of the things that we know about this context. And it takes a list of candidates and it allows you to kind of modify the list of candidates. And then it also allows you to modify list of fits. So you can actually do different kind of synthesis based on what you need, right? So this is a simple plugin, right? And so you kind of inject it into this plugin architecture. And then we can load this plugin and then we enable the plugin plugin. And now we still get a... So what this plugin does is that it actually, it kind of looks at the name of the whole. Let me, this is a little bit much, if it's also refinement whole fits. So it looks at the name of the whole and it kind of filters things based on the name. So here for underscore it doesn't do anything. But if I tell it, look in data dot data foldable, right? And I can't write dots. I had to kind of shimmy it a bit. So it doesn't find anything in data foldable that matches this type. But if I import from data foldable length, then of course it finds the length function. So it kind of allows you to change the candidates. And of course it allows you to change the fits and stuff like that. So I'll show you how I use this later to actually do kind of interesting synthesis using the plugins, right? So that was that though. Yes. No, you can actually inject whatever candidate you want, right? And then it goes through the fit checker. And then so the candidates here is everything in scope. And then it actually then runs the synthesis and it checks does the candidate match the type, right? So you don't actually have to guarantee that the candidate fits the type. But you would like to guarantee that the fit satisfies the type. But there's no actual check there. Yeah, exactly. Exactly. And there's a couple of different kind of candidates based on where they come from or from the scope. And I'll actually show kind of interesting candidates that I had to write. Okay, so that is this talk slash poster, right? And then we have Henprog and that is kind of the kind of work, current working progress I'm doing. And this is based on the Genprog program that was in, I think it's in from 2009. It's not quite state-of-the-art automated programming pair but it's kind of, I wanted to see, what can we do with things that are already, what can we do in Haskell and then kind of add on things to make it more state-of-the-art later, right? So let's look at how that works. So here we have a simple Haskell program, right? And it has a couple of QuickCheck properties. So you can actually, these are just unit tests kind of disguised as QuickCheck properties. And then here's another interesting property saying, okay, so the idea here is I have a GCD program that I wrote, this is like the example from the Genprog paper. And it actually, it has a bug in it, right? This list line here will loop indefinitely. Because if it hits this case, it will just go right into this case again. So it hasn't, we have an infinite loop here. But I would like the program to satisfy these properties and well, I would also like to terminate, right? So then I can run this Genprog program, right? And so it kicks off, you know, it picks up the properties. You know, it knows the type of the home. Okay, this is actually, yeah. So it knows the type of the function and it knows what properties it should satisfy. And then, so it doesn't really do kind of, so there's a thing in Automated Program Repair called fault localization where you kind of figure out where the error is. And that's very naive at the moment. It just kind of figures out that, oh, you're always evaluating this GCD prime thing in this current module. So I'll assume that's where the, I'll assume, you know, I pick targets based on what is being evaluated in the properties. But we will need to improve this heuristic and there's a bunch of kind of good heuristics out there that we just haven't implemented yet. Then it goes off and it kind of runs the program, does some synthesis, and it actually figures out that, you know, if you replace this GCD prime zero B here with just B, then the program will satisfy the properties and it's been repaired, right? And it's kind of cool how we can kind of, you know, so we have with Genprog, we just have unit tests, right? But because we have QuickCheck properties here, we actually get kind of, you know, kind of not an infinite amount of properties, but we get a lot of actual unit tests from the properties. But then now we have to consider so what Genprog does is that it kind of weighs each unit test and tries to kind of figure out or something that matches all of them. But we still have, so there's some research to be done to kind of integrate these properties in, like, you know, how much should we weigh a correct property versus a correct one unit test and stuff like that. And what it does is that it essentially, it goes off and it just tries to, it just pokes holes in this program, like these typed holes, and then it uses a custom type checker plugin to actually, you know, do the synthesis and communicate back and forth what the fits are and then just runs the program with those fits. So, and this is just kind of one fix at once, but then we have a more interesting case here where we have a program with multiple properties, right? So, you know, so it has, sorry. So here we have another program called broken pair. There's actually a broken triple and the issue here is that we need to replace all these values. So essentially what these properties say is that, you know, this triple here should be three for five. So we can fix that as well. And there the actual genetic programming comes in, right? So we kind of try multiple fixes and then we merge them together into something that works. And well, it's not really doing genetic programming at the moment, it's just doing kind of breadth-first search. But yeah, but this is kind of on work in progress. And I'm kind of interested to see where we can take it. And so this has been joint work now with Leonard Apples from Delft. And yeah, he contacted me and said, you know, I think it's an interesting work. Should we try and work together on it? And yeah, sounded good. So I have some help with a genetic programming part in that. And as you see, you know, it takes 12 seconds even with Zoom and everything running. But it actually does figure out, you know, you can have, you can, if you change three parts of this program, you get actually the correct program. Okay, that is kind of my current work on automatic programming pair. So the other part of what I've been doing, and that was this mostly last year, is these type checker plugins. So the original idea here was, so we would like to be able to run programs even if they have type errors in them. If those type errors are of the type, that don't actually affect execution, right? So the go-to example here is actually the Mac library from Russo and I think Stefan, Dan Stefan, right? Okay, yeah, just Russo, right? So Russo allows you to annotate programs with labels, right? And you have these, you know, you kind of wrap values in boxes and those boxes have labels. And then we make sure that, you know, so you have two labels, either public or private. And we make sure that kind of private labels do not flow into public contexts and thus they don't leak, right? And this is kind of, this is called information flow control and has been a big, big, we've done a lot of work on that at Chalmers. And the idea is to kind of, yeah, if we model in the types what can flow where, we can actually know what, you know, that we can actually guarantee that values are not being leaked and there's some kind of interesting cool new stuff coming on out of here. And as we saw, actually at Max's defense the other day, but the issue is that you might have a program that's functionally correct. You know, it actually does the thing correctly, but it might be leaking some values, right? And so my motivation here was that, you know, if I want to automatically repair the program, I still want to be able to run the incorrect program if the only error is actually just kind of a type error that doesn't actually matter for runtime. And the trick is that what the way Mac is implemented is that it's actually, it just kind of wraps the value in this label, but the label is erased at runtime. So these will actually be represented by the same memory at runtime. And so we wrote this plugin to kind of allow you to ignore these kinds of type errors. By using kind of corrections and stuff like that, so they will be safe. And we can actually, so here we have written a program and what it does is that it kind of says, you know, I will, so it allows you to, first of all, allows you to default. So, you know, if we have a label and we can't figure out what it should be, we can just default it and I think it, and it's all configurable and we are these type families. So we actually say, you know, if you can't figure out what the label should be, default to a public label, then we say you're actually allowed to let private flow into public or the other way around, but we kind of give you a warning instead. So we kind of turn all these things that would have been actual type errors into just warnings because we know that they don't actually matter at runtime. And then, you know, it gives you all of these warnings that they are all generated by this plugin and eventually, you know, we come to the program and we can actually, you know, we can actually run the program, right? Even if it has a bunch of these type errors in it because they're not actually relevant to runtime. And it's kind of key for kind of later stuff that I want to do with, you know, I want to be able to automatically fix these labels and then I need to be able to run the programs during synthesis, right? So that was the RIT plugin and then I've been working a bit on that with Augustine as well on something I call the data.dynamic plugin. And it's basically the same idea, except that instead of just saying, you know, this is actually the same value, we state that, you know, it would be the same value like if you apply this one function to it. And Haskell has this support for dynamic types and to use those dynamic types, you actually have to use these two DIN and from DIN functions that, you know, take some value and make it into a dynamic or take a dynamic and make it back into a value. And we implemented a plugin that allows you to, to kind of go back and forth without having to write all this syntactic sugar, right? So here, you know, in regular Haskell, you would actually have to write let F equals, you know, two DIN of A, two DIN of B, two DIN of C. And this is just, you know, for my sake, it's just too much work. I mean, it's just, you know, I just want it to work because the, and that's the trick with the plugin is that we know that they have to be dynamic. So we can actually just do this, right? So we can rewrite this plugin and it's enabled and it just says, well, I'm gonna, I'm gonna marshal this A to dynamic. And that's what we call it. We're gonna just automatically promote it to a dynamic. And then in the generated core, like in the actual generated program, we fix it by adding this two DIN call there. And so, and that's kind of, I think that's cool, but I mean, it's not that much. So what we added now is that we actually support dynamic dispatch. So what that means is that I have a class here, which takes an A and then I have two instances of it for A and for type A and type C. And then what I do is that, you know, I can actually use this function on dynamics by building this dispatch table at a runtime, right? So I can actually just say, you know, if you're trying to run this foo function on a dynamic and it has a A underneath the dynamic, then just call the foo function at the instance for the A function, for type A, right? And then we can do these dynamic dispatch things. And our idea is, you know, can we get like Erlang level dynamic stuff in Haskell directly? So, and we can actually run this and then it kind of, you know, runs it, it generates these tables and, you know, we can even generate it for ORD and EEC. And we actually, you know, we can get one warning, but it actually compiles and we can actually run the programs even though there's dynamic underneath. Yeah, so that's kind of the current work I'm doing with Augustine. And yeah, so that's it, what I've been doing so far.