 So let's just get right into it. I will say, I guess you love it as well, because it's so useful and convenient with LISP. But it's really the same thing with a little bit more bells. And function program, compare, LISP and write, people have gone from LISP to HESP. You know it. But I want to run through a small example in order to pick out a few things. This is like your standard setup. This is where I switch to demo mode. You see how that does. Now you have my head. I'm sure we'll figure it out. I'm going to switch this over to mirroring, so I can actually see what's happening here. So I've got an editor. You may have a different editor, but come on. And I've got a shell. I use bash. You may use something else. But really, this is not that different. So now I could, oh, let's start writing a small program. But let's just load that up into CLCI. I should save it. So the first thing, I have to save it. I wanted to put plus plus here. So this time, I'm going to remember to save. Going to go over here again. I'm going to reload it. Yeah, we are going now. OK, so let's test this thing. So there's a tree, like a binary tree. And I've got a size function. If I give it a leaf, it's size zero. That makes a lot of sense. Let's do something a little bit bigger. I'll bind that to a variable so I can reuse it. And let's just do a small tree there with me while I am typing. So let's do the size of this thing. So you should have told me that a binary tree. OK, size of that zero. Can you read this? Zero. That tree isn't zero. OK, let's see. Who can see the problem? I'm stupid. I can't write programs. Of course, I shouldn't just add the size of the two half. For the node, I get one node. So I reload this again. And I just scroll this up so everyone can see. Oh, no more tree. But we've got history. That one improvement since this. Thank you. So let's try two. Now we're done. I can write code after all. And then I can try to convert that tree to a list. And I get a list. OK, not too bad after all. Haskell is awesome. But you knew that. So let's do this setup, which is like every Haskell programmer set up. Only use VI or Emacs, and you may use GHC ID or GHC mod or whatever your favorite add-on is. And maybe that fits you a little bit more. First of all, I mean, it was quite annoying I had to define this tree again. I mean, I was lucky because I didn't quit. Or I didn't log the different 200 back in my history. Because then I didn't know how it goes. I mean, really, it's not consistent. As you said, it saves a little bit of typing, but the system is something else. And test out of VX, which in turn is the pretty test out of VI. And why is it called VI? So basically, those editors wear the same thing for editors as GHCI is to what? So what's VI for the rest of the memory to save? Or it's depending on your consecrate media. Reload again. And for this small example, of course, was easy. But for anything more serious, kind of. And then, well, the thing spits out text, which is kind of cute. But this machine can do more. Can we do better? I mean, let's just run with this idea. What's the VI equivalent of a raffle, what VI or Emacs was to add? So let's actually do this. So we have a module trees. And our data definition was three of a equals leave. Or what I want to show you is that in this environment, that's my data definition. So and instead of trying to write any definitions, any functions on that, let's just think about how we want to use it. So I had this example tree, right? What was that, node five or another leaf? Now, this kind of run, if I forget the leaf, actually it does tell me. So I know immediately something's gone wrong here. I didn't actually plan to do this tree. Of course, nothing is available here, because I haven't defined size yet. So if I look at this error message, not very surprising. But that's OK. We are just thinking about what kind of code we want to execute. And so we've got all this. So now let's write the code. So our definition of size, that was a tree turned into int. So base case, well, a leaf is size 0. Size of leaf returns to the site already. The other one doesn't work yet, because it gets a pessimistic failure, but who cares? So we do the recursive call. And if I make the same mistake again, I forget the plus one, I immediately see something's wrong. Well, obviously I forgot to count the node, and I continue. There's no back and forth reloading. Why is there an error? Because I really see what's happening. And then I've got the second definition, tree of a flatten into a list. And if I make the mistake from before, right? So same example, but the workflow is slightly different here. So let's go back to two-dimensional raffle. Because why not? Because why can't the computer is done? When I type, whenever a problem changes, we evaluate. Because, well, maybe we evaluate in vain. But most of the time, if you are editing, your computer just sits there doing nothing. So let it do something which might be useful, because if you look to the right and see that's wrong, why do you write in the code? Should I start here to see and try this definition already? Or should I write a few more definitions and then test them? It brings us to the next thing, because testing. I'm new with this. So I've got a few quick, I need a quick check. Everybody knows quick check, right? Specification based testing. So I need the definition, arbitrary definition for this tree so I can generate the test. And I will not make you sit through me trying to define that. You said I'm just going to define it here for you. But I will have to be, I could write a property. Something like the, what do I know about size? The size always has to be positive, right? So one possible check would be to say, the size always has to be positive. So size of t is going to be greater or equal to zero, right? And then we can use quick check. We know that. John Hughes and Kim Klaas and Toyota stuff. So let's do another one, something more interesting. So what's the correlation between the size of the tree and the size of the tree must be the same as turning the tree into a list. Check that as well. So that's fine. So all right, let's look at how we would use that in development. So in these cases, we had these functions already and we added the tests. Let's do it the other way around. As I said, usually we are going to start with the tests. So I want to have another definition which takes a list and makes it in a tree, like the inverse of two lists. So I want a test for that. And the obvious test here is to say, well, if I start from a list, I turn it into a list again, I want to get the same thing. The list, the same and turning L from list. From list, I haven't defined it yet. So let's do from list. So from list, obviously a cute idea to define it instead of writing out recursion here would be to use forward, right? We followed over the list to construct the tree. I don't know about you, but when I use forward, so we do know that we want to start with the leaf, right? But the combined function, I never know which other argument. It basically says, well, what's the type of thing which I have to put in here? And it tells me, okay, it's got to be tree first, then an element and then gives me the tree. So it said tree first. So let's do a lambda. I want a tree first and then the value and then I have to come up with a new node because we extend the tree, we have a leaf and that subtree, which we got as the first argument. And it says, okay, now what I forgot to do here, of course, is which I should have done right away before we do, it's quick check. So let's just see what the, so it says zero one. The list zero one is a counter example. Well, we are here in a pretty playground. So let's play, so from list of that counter example is a tree, that's fine. And if I two-list this thing, then I want the same list, except, but that's okay. I mean, the specification here was we wanted to turn one to the other. We didn't say anything about order. So it's actually our quick check property which is not right because we want to ignore the order. So let's just sort those lists and then we don't care about the order. And to do this, we have to import the list to get sorting function and voila, we'll test pass. So that's how we use quick check in that scenario. So you see, we're here again, okay? So idea of starting this test and queries and then slowly kind of crafting the code is interesting. And secondly, the really rapid feedback. It's really like you just have plug-in so that you can kind of run the code through your type checker when taking this to the next level, not only do we get type errors all the time, constantly, whenever we make mistakes but we also get our tests run at that same small green level on a multi-bimodal basis. And that's, and there's a result of all that. Yeah, I mean, even more, the Ripple is great. Why is the Ripple so great? It's great for beginners because you can get people to do something right away. You don't even have to write a program. You can just show them if you just play around with it. So you can use it as a glorified calculator. It's also great for developers who want to quickly experiment with some code and during debugging, you just want to call a few functions with a gparometer to see what's happening. So all this is great about the Ripple. And the idea here is really taking that greatness to the next level. It's not a professional placing. It's about taking it to the next level. And it's just illustrating the same things using PhDs and so on. So, for example, we recently started and screencasts, so videos. But the idea is quite simple. You start with the baseline. That's the red line for those who, and then you draw a square on top of that red line. That's where Pritaparas comes in. You, so if that's the draw a circle on top of that and then on that circle, you pick a spot. Then I say you pick a point is the same angle or that square, giving you something like that. This gives you the, and the other two sides of the triangle are the baselines for the next square. The first thing that people start. Let's write a program. And we have to go now, which eventually is going to go be recursive. It's not recursive yet. And it's not important or the difference is accepted to summary. Basically, the first argument is recursion depth. That's clear. And the other ones are really only about color, altering the angle, kind of making this a bit more interesting than the standard factor will be. So, forget about it. We've got recursion, which isn't really, but we don't call it T here. So, it's not recursive yet, which won't square here. That was the base we started with, right? And that's why it's not recursive. So, the next thing we have to do, we have to get the triangle on top. To get the triangle on top, what I need to do is I, these points here, these four points, those are the corners of that square. And I need to add a fifth point to add the triangle at the overall shape. So, where do I get this fifth point? Well, I have to do to calculate the triangle. And I'm going to do this by a recursive call here, which gives me P5. What this is doing, it's basically taking the baseline, rotating it and scaling it. And that gives me the corner of the triangle. We don't have to go into the definition of the rotations and so on. That's where the pitagoras theorem comes in. But that's the point here. So, we put P5 in here. And so, the thing got a little bit of a notch now, including that triangle. And so, the next thing that we're going to do is we want recursion. So, we want to, this is one polygon, right? We want more polygons. Let's do one recursive call, where the recursion depth is one less than it was in the initial call. And then, what's our new baseline? Well, the new baseline is going to be the sides of the triangle, which is, this was the top of the triangle, right? So, these two pairs of points, those are going to be the new baselines. So, in the recursive call, we pass the line from P5, which is the top corner, to P3. That's the danger with life coding. So, if T is all to be defined as a list of picture objects, I tell you that. And if I, okay, so, and now, suddenly, oh, this is the recursion depth here. If I add one corner, where we added one more of these things, the base and the triangle, right? And that's one side, but we want binary recursion. So, we have a second call, also one less P, but with the other side of the triangle. So now, we've got the first bit, right? So, now we can, well, we could add recursion, increase the recursion depth, five. But, let's add some color. As you can see, we already have some setup for this. And, all I've done here, I've just called this helper function with just the color white. But, I, the function gets, as it's third argument at an argument called color fun, which is function which, depending on the iteration depth, computes the color for that depth. Then, the color changes as the iteration begins. So, we will just call this function, color fun with the current iteration depth. And look at that, much nicer than the white. And, another thing I want to change is to already to the triangle, where I'm trying to start this square. But, it turns out, what we are going to do, we are, and that's the comment that I've heard here, we are going to extend scale, the, what's initially the two vertical lines. And then, now we have to be careful, we have to change all occurrences of P3 and P4. The scale is higher. Okay, so that's great. What else are we missing? Let me see, most of it. So, if we go to recursion depth of 18, now that takes a moment to compute. So, what's the point here, taking a pretty picture, is if the list, I change things, I see what's happening. I can see, ah, the stuff, like when I made this mistake with P4, using P4 instead of, we saw there was this kind of notch at the side, but not the real thing we wanted. And somebody in the video said, ah, here's the wrong number. So, you immediately see what's happening, same as with this, right? So, that's one thing. So, we can do something similar, HTML, or let me skip that, because I think the idea was 40 minutes, so I don't want to keep people for too long. So, I'm not going to do the web thing. Basically, the idea is, we can do the same with HTML, okay? The HTML previews work in the same view as graphics. You, as you edit them, you get the HTML render, and you like, if you change something, we can, this was static graphics, right? But we can do more, we can do animations as well. And it's the same deal. Here, there's certain starting velocity and so on. If I change that in the code, and I run it again, then immediately we see the effect animation changes. The final one, that can even be interactive. So, we are not just limited to animation, not limited to text, we are not limited to graphics, we are not limited to animation. We can even do, so here I can use. So, it's really all about being, having a more interactive setup. It's the same setup, and we get the HTML. The idea really, the core concept is liberating us from the one-dimension nature of the raffle, making it two-dimensional into a text buffer, and then having this immediate feedback, and having that for not just text, but also graphical objects, structure, media, like HTML. That's me. So, thank you very much for having me. This is Song. So, previously I'm doing some data in machine learning product development, it seems very, so I just want to ask. So, let's say we want to build up a data product. If I want to use Haska to write some functions, what would be the challenge? Probably I'll give you a more specific scenario. So, let's say, okay, now in this data product, we are facing a high-volume traffic, then we have already built a Kafka to take the data and store in some distributed database like Cassandra or Hive. So, now, let's say we want to write some Haska code to execute some function, right? So, we let this code to call and query the data from the distributed database. Over there. Yeah, so, what would be the challenge? For example, like, what is the latency, let's say, compared to other JVM-based language? So, that's a very general question. Yeah, that's a very high-level, kind of. So, I mean, there are quite high-performance library, Haska libraries these days for network application. And there are also companies out there who use Haska for data science. What they, so, because this is really the first generation of people who use Haska in that environment, a lot of what they are doing is homegrown. So, one company is, for example, I don't know if you've heard of it, probably not a small startup in Sydney, it's called Ambiyata. Some of our students work there. And they are doing a real-time analysis of data coming in from sales channels, for example, and so on. And they've really built up their own infrastructure. They do use some established libraries and frameworks, but they've also done a lot of implementing their own. And basically, fundamentally, there are two different things that you can do and that people do do. You can either build a Haska layer on something existing quite recently, then allows you to, so that's one scenario that you layer Haska on top of some existing JVM-based, for example, infrastructure. Or if you need something which isn't addressed by these existing tools in the way you wanted to, infrastructure, which is what Ambiyata is doing. But I think these projects, which are like commercial projects, the tool chain, the compiler runtime system, the threading system, and so on, is fully capable of working at that scale. But there's less ready-made software out there Okay, so, which in itself is actually, it's like this from one version to the next version, they compute the difference of the virtual DOM and then apply that difference to the actual browser DOM. And I'm doing something similar. I'm computing the difference between the Haska data structure you've got and the Haska data structure, your transformation, updating function produced, and apply that difference to the underlying object with that. I mean, that code is horrible. What do you think the main difficulty to like for this playground to use the browser environment? Because I'm thinking maybe like, for example, in the Haska or like website, now it comes with a very text, simple text report. If we put a sandbox there and simplifying for implementation there, then we can let the newcomer to play with it. And also that it could like, if I use the HTML with JavaScript slide, I can maybe put embedded playground while I'm presenting something. Yeah, yeah, it would be like L, that's it. Yeah, so, on one hand, the take underneath this isn't rocket science, but I am directly going to GLC API. So I'm not using GLC mode, because they don't, in this case, I mean, most of this application actually would be GLC JavaScript. Yeah, but then in GLC JS, you would have to talk to GLC API. Yeah, GLC JS, the idea is to compile everything include JavaScript, but I really have to talk to GLC and you can't compile GLC to JavaScript. So you need a bridge between JavaScript land and the actual binary GLC implementation. And to get this rapid feedback, you really don't want to go through. That's good. We welcome you, come on. Okay, thank you. So the grapefruit is grapefruit. The first one, I... Grapefruit or grapefruit? Grapefruit, okay, sorry, yeah, that's my mistake. So grapefruit, I haven't personally used it, I have to say. So it's an FRP based, I believe, system, which tries to do graphics from the ground up. And so basically the idea in grapefruit, as far as I know, correct me if I'm wrong, is to do everything from scratch. We start from pixels and then we build everything up, which there's this temptation, especially in Haskell circles, to do the best, purest, optimal solution and just start from bits and bytes. Problem is, if you start from bits and bytes instead of using work, other people has already done for the last 100 years, and then it takes a very long time to get to something a bit more interesting. So the idea here is to leverage an existing industry standard widely used library and just put a thin layer on top because then we leverage this existing work. It requires some compromise, it may be it's not the nicest solution, but it requires a fraction of the work. So the capabilities of something like SpriteKit are vague. So it's this difference between do you do everything yourself or do you build on other people's work? Just, there are two things you show that. The first one was this thing called context free art. I think it's contextfreeart.org. I'm not interested in being so, this is like this thing. So that's a very interesting point, very, very, very good point. So what's the pros over here? I haven't talked about it. There's a long tradition of people, who knows, in a way, and he in turn has been very strong. You can see as an attempt to recreate like 1% of the vision of Pratvita, maybe 0.5% so we can do it. So what's the underlying structure? That's easy to answer, I can just show it to you.