 Do you have a? OK, so thanks for being here for the first steps in wiki function session. And what we want to take a look at is how to create a function, how to go about it, how to use this. So a good place is usually to go to the Suggest a Function page and just like add something and add an idea what you have to do. Today we'll just start with a simple function ourselves. So the function I would like to suggest is to it takes a string and it doubles it. It just doubles the string. That should be pretty simple to implement. It should be done in enough time over here. So we want to create a function. That is fine. So I entered the name for it, which could be something like double string. Anyone have better names for that? Duplicate. Duplicate is nice. It's probably better than double. Duplicate string. I entered double as an alias. OK, and this description could be something like takes a string and returns it duplicated. So the input is a string. The output is a string. Yeah, thanks. Just don't remember it all. It added another language to enter the unspecified English too. I can. I can. I can. I was going in the wrong direction. And it was input. So that's actually everything you need to do in order to create the function. So you need to know the types, how many arguments you have, what types the argument should be, and give it a name. The name is even optional technically, but you probably should always give a name. And then we get to the function page. It asks for input, but you can actually run it because you don't have any implementations or anything yet. So we can go to details here. So we have no tests. We have no implementation. And the first thing I would always suggest is after you've created the function, create the tests first. Don't go immediately for the implementation. It makes it easier to always do the tests first. So we go down here, click on Add Test. And adding tests is a little bit uncool. So we need to improve this a little bit. So basically you say my function call is duplicate string. And it takes an input like, for example, I don't know, wiki. And now the question, and we need to check whether the output equals to what we expect. So it's not inequality, equality. Here we go. And here we have to make the decision, actually. Did we mean something like this? Or did we mean to have a space in between that? So depending on those are two different functions, obviously. And both of them might be useful. And this is why it's good to have those tests basically. The tests tell you what were you really thinking. They help you to specify what you actually meant. And then as a community, you can decide. There's also nice things about it is that the tests are not automatically approved. So you can say, here's just a test. And this is what I would expect on this input. And then as a community, you can start discussing, oh, no, I actually was expecting on this one, this. And we rather here. And then the approving of the test cases basically tells you what is the semantics of the function that we're expecting. What does the function really mean that we are trying to build here? So should we before without space for the duplicate? What? Without. Without? We. We have one, one. Without. Without? Without. Without, OK. We're getting to without. The good thing is you can afterwards create one with. That's right. So this is our first test. We have to duplicate string. I should have given it a label. Duplicate wiki equals wiki wiki. This makes it a bit easier when we then see them. We don't have yet good naming conventions on those things. But I guess the community will work on it. We, in the inclusive we. You all can start. Yes. So shall we do another test? What other test could make sense? Blank. Blank, yeah. So duplicate, those will look terrible. So I leave this blank. And here, string equality. And leave this also blank. So the duplicate blank equals blank. So now we have two test cases. So you make it for a test case. Anyone have something interesting? So this is a bug here. I shouldn't say enter string. This is basically when we have the empty string here. No more test cases are suggested. OK, in that case, now we can go. Since we have to function here rights. And in the beginning, everyone who can edit the objects will have function here rights. You can actually just approve the tests yourself. So here I'm connecting those tests. So those tests are now part of the test suite. And they will actually run against the things. It's connecting the function with the test. I think we want to rename this into a proof. I'm not exactly sure. Just think it from proof. So connect is the last. OK, good. I always forget the. So basically this means those tests are connected. And this would mean it's it's not connected. It's disconnected. So this one is not being run when we actually use it. Trying to figure out the naming still. I mean, we only have control about the English name in any way. So and even David don't really have control. So yeah, we can make another function afterwards with this. Oh, yeah. Oh, right. Sorry. A test where we have. OK, yeah, uh-huh. This will look terrible. I'm not sure. We'll see. Duplicate string. That's a good. Ah, because this is a bridge. OK, so I use again. In the magical future, you won't have to choose the function here. It will be automatic. You just enter the input and the output. We're not there yet. No, that's right. So I pressed two spaces here. I pressed one space here. You have to believe me because it's actually invisible. Our name. We can rename that. I'm actually not sure that we keep the, ah, that's a bug. Yeah, yeah, but we probably have to turn this into NBSPs here. I'm not sure. Yeah, something like this. Need to figure out there might be so many edge cases on both of them. There's so much things to work on. My job is safe for a while. Let's also approve that one. Connect this one. Sorry. And add an implementation. What should we do our first implementation in Python, JavaScript, or in the beautiful composition? All three. We will do all three. But which one first? Composition first. I love composition. That's my favorite. OK. So in composition, we basically take existing functions and try to make it happen what we want to do. So in this case, we already have a useful function, which is a join strings function, which we will take as our stat. And the first string is the input argument reference that we have. This should be automatically displayed here. It's not, as you can tell. And oh, man. I need now the ZID of the just created. It doesn't show it here. Oh, sure. You can come closer. I can't just add the K1 here, right? I need the actual set. It might work, because I can't figure out what the ZID is of our idea. OK. This is evil, and this should also be fixed. We have a task for that. So basically, here, we select the first argument. We only have one argument. And then I repeat the argument here. And basically, now what I did is I join string on the two arguments. So if I close this, there's a little trick. It should show you a little bit readable what we're actually doing here. So it joins strings on the input with the input. So we double the input here. And what we can do now is because we connected the tests already, I can run the tests now and see if they actually pass. And for a bit of luck, this will turn green in a while. So we know that all the tests that we have written pass actually for this composition that we just created. So we can give it a name. I can call this join strings, input, input, and publish it. So our first implementation for this is done. Now if we go back to the function, connected, we will be able to actually call the function on the page. So if I now enter something like ABC, run the function, it should return me ABC, ABC, and it does. So now let's do implementations in Python and in JavaScript. And then we will switch gears. And you can actually go ahead and try implementation. And James and I and maybe Nick will help us to figure out how to do this. OK, so let's make an implementation. Python or JavaScript first? Python. In this case, we helpfully display you the set ID that I needed earlier. It is. So I can copy it easily by clicking on that. It's a neat little trick in the interface. And then just paste it here. Sorry? It's also in the depth. In the depth? OK. And this implementation in Python. And if we run out of tests, they all pass. And so, and we can publish this. Let's go ahead and do the one in JavaScript. Obviously, in order to use wiki function, you don't need to understand all the programming languages. In fact, you don't have to understand any of the programming languages. It's not if you can read the composition. Just it can't be sometimes helpful, for example, if a composition is slow or something like that, to write an implementation. But this also can be done by someone else. It doesn't have to be happened by you, you might ask. Folks, they have this very slow composition here. Can someone help me write something faster, maybe JavaScript? So, here, is it also plus in JavaScript? Yep. OK. The should be strings. We are, I think, you can't. Oh, yeah, yes. Oh, that's a good idea. OK, let's do it immediately. So we give it a name. Can it be the same name again? Yeah. Yes, OK. Let's see. Now, we need to rethink a few things here. So, let's now go and make a test with numbers and see what happens. OK, I don't know what I was thinking there. So now, in this case, we can actually also approve those two, connect also those two implementations, and go and now create another test with numbers. So we say that, for example, with one, duplicate string on one. This is the string one, not the number one. The result should be exactly one, one. And now we can actually go ahead and immediately test against the implementations, not the other way around. So since we already have implementations, we can now test them and see if this will all work. They all pass. JavaScript doesn't do something weird, like type coercion this moment. I mean, we want to break it, so let's try out. Does it work? Yeah, because we're wrapping it in. Exactly. Do we want to keep the one put one or just the one? One put one. This one. OK. I mean, you can also just create both of them and just want to move on here. But this is basically the process that we're going here. So we can write testers, we make sure that they work, that all the implementations work with that, that the implementations are consistent against each other. We can then discuss things like, no, actually, those test cases would make this result and so on. All of these things should be working in a big issue way, which is the new part, which is not exactly programming. OK. So let's connect that test to. This will be interesting if it will manage to get the whole matrix done by taking a moment. A lot of it should be partially running in caches. Yes, very good. So here we have created the function. We have created four tests now, three implementations in different ways. So we have questions. Yes. No, it does not yet. It's a good point. We should think about that. Yeah, in theory, you can redirect the tests, for example, to a new function. But I'm not sure that this is more confusing or not. So we currently don't have the feature. It's not a bad idea. I think we should think about it, yes. Yeah, it's a good idea, a good proposal. OK, any more questions at this point? So the question was, when we enter the parameters, it seems to automatically save. Oh, yeah, you can run the tests without having saved the function. So just running the test doesn't mean that I actually saved it and tested it out. I run the test implementation. I just wrote live, basically, without having it stored first. So yeah, this is in order so that you don't have to publish every time you try it out. Yeah. Did you repeat the question for the recording? Yeah, so the question was, when I'm creating an implementation or a test while entering those things and then run the little circle that makes it run against the tests or against the implementations, does it save every time when I do that or not? And the answer is no, it doesn't publish at this point. It basically runs it live. And it only publishes when you click on Publish. So this allows you actually to start writing and implementations and until it finally passes against everything. More questions? OK. Who here has already functioned near writes? So who here now wants function near writes to play things out? You need to have logged into wikifunctions these once, which means if you have. Well, we don't want to create. Everyone who wants an account, do you have a Wikipedia account? Yes, OK. I expected it to wikimania. So just go to wikifunctions while you're logged in in Wikipedia or whatever. And it should automatically log you in on wikifunctions. Even better. And give me your names and I will give you the rights. For this, I will go to the other computer. And James, you can have your computer back. OK. Sorry for the recording. Now it comes apart. And it's not so interesting for recording because we're going around in the workshop. All right.