Are you guys familiar with the most affordable? Can I start? Yeah. OK. Great. Hi, guys. This is weird. I'm standing behind you guys. I'm going to introduce you. Yeah, go ahead, go ahead on this. Yeah, this is Omar Iqbal. I hear that he was lecturing about Haskell on NUS long before I actually seen him. So there was this unknown Haskell there that was somewhere beyond the horizon. Then I actually hear he made a very passionate talk on Haskell and actually theoretical concepts behind it. So I know it was supposed to be talk about Coco JS and more like Jasky, but since nearly every second sentence was, if it's good, it's almost like Haskell. I understood it in a very different way. I recommend his talk on YouTube from the last geek camp. That was just two weeks ago. And yeah, please. OK. OK. So before I begin, I just want to get an idea of the crowd. So how many of you guys are intermediate Haskell programmers or fully understand what Monads are and what they're used for? Intermediate or intermediate? Good question. Let's just say how many of you are beginners in Haskell? That's good. Because this talk so originally, I give this talk to a more beginner-friendly audience. So for more experienced people, some of this stuff might be face palm. Or some of this stuff might be, oh god, goodbye, let me escape. So please bear with it. It's more of a beginner-friendly talk. So I hope that's OK. All right, so let's get on with it. So this talk is about monadic parsers. I'm Umar. That's my Twitter handle. My day job is I work as an iOS developer at Greene. Once again, might be surprising what the hell is an iOS developer talking about this. I'll get to that as I see it's surprisingly relevant. OK, so let's get to it. For those of you who don't know what a monad is or probably first time saw a monad or probably wondering why is a parser a monad? Your reaction is probably something like this. And it's understandable. We'll get to that. But before we get to that, we're first going to discuss parsers. And we're going to try to define the problem that we're trying to solve here. So a long time ago, and we're going to start with the story, a long time ago in a galaxy far, far away, our dot Twitter wants to parse JSON data sets of rebel starships. All right, it's a quite typical use case. Problem is, he can't download his favorite JSON library because internet access is a little scanty these days on the Dead Star.  So he wants to implement his own JSON parsing library from scratch. And this sort of thing, he thinks, OK, it should be quite straightforward. It should be quite easy to do. We got regex, right? I mean, it's a great parsing tool.  So this thing might just work, right? And here's the code I found on the internet, which is kind of true. It says, some people, when confronted with the problem, will think, hey, I'll use regular expressions. And now they have two problems. And this is by this guy, Jimmy Zawinski, the pretty famous hacker. It's not my invention. What's the problem with regex? This is a great tool, but you shouldn't use it for parsing non-regular languages. And I'm not going to go into the mathematical definition exactly of what a regular language or a non-regular language exactly is, but just to give you guys an intuitive idea of what a regular language is, you can think of it in a way that a regular language is a finite language, in the sense that the permutations that your alphabet can have is in a finite manner.  I have a very small proof here, like why JSON, HTML, and most programming languages are not regular languages. Play the second, and that proof is not appearing here. Oh, wait a minute. OK, now we're going to use the pumping lemma. Huh? We're going to use the pumping lemma. No, it's a much simpler proof. But the basic idea here is that I'll just give the basic idea why it's not a regular language. But those of you who use better programming environments don't judge I'm using Sublime because my Emacs setup crapped out on me. So, OK, can you guys see this? OK, so one simple proof on why it's not a regular language is any language of this form. Sorry, I'm using this. a n, b n, where n is greater than or equal to 0 and goes on infinite is not a regular language. a where a and b are your alphabet, basically. So any language of this form, there's a proof behind this, it's not a regular language. And if you think about it, a simple proof by case, this is a JSON, and you could have infinitely many brackets here. It will still be a valid JSON. This is the same form as this because I can make this bracket equal to a, this bracket equal to b. And therefore, proving them, hence, the proving that JSON is not a regular language. Simple proof. There's more complex proofs, more complex papers out there. Feel free to look at them. Anyways, back to my slides. So, point here is JSON HTML, the most programming languages are not regular languages. So we're going to help Vader out of here. We're going to help Vader out a bit. And I'm going to start with a simple parse. So in the way we're going to help Vader out first, is first we're going to define a very simple grammar for JSON, all right?  So here's a very, very simple grammar for JSON. Like, this is actually wrong, but hey, it's OK. That's star, for that's our purposes. So as I said, JSON can be a bool, a string neutral, a num neutral, a null or a object. Booling can be true or false. String neutral can be this stuff. A number, let's say you already define what a number is. Null can be this. An array, here's where it comes recursive. An array can be JSON followed by more JSON and comma. A pair can be string neutral followed by colon, followed by more JSON. And an object is just zero or more pairs, right? So very simple grammar for JSON. And I'm going to implement, or I've already implemented parser using which, I'll show you guys, which looks something like this. So the basic gist of it is, this is, by the way, this is not using parser or anything. This is something I developed myself, and I'll show you guys how to develop something like this. It's quite a simple parsing library. But the basic gist of it is that the grammar rules over here look a lot like my grammar rules I specified over here. So if you look at the code, what's in my, for example, in my parse JSON, what I do is I parse either parse bool or parse string or parse number, et cetera. My parse bool, I parse for this literal. Otherwise, I parse for this. And I'm returning stuff that belongs to this type, which is basically the type of my AST. This is the return type of what this parser would return to me after parsing. And the basic gist of the idea here is that this parser looks a lot like the grammar I specified on this side. And if you use something like parssec, this would probably not at all be very impressive. Side note, how many of you have used parssec before? That's a lot of people. OK, great. Then this will not look impressive at all. But the fun part will be that we can implement this quite easily. OK. So anyway, just to show you guys, just to prove that this thing works, just going to run it with some stuff. For example, so let's do this. It returns a null. If we give it an array, it returns this thing. Bear in mind, this grammar is faulty because it doesn't deal with floating points. But that's OK. I think that star doesn't need floating points for now. So given that sort of thing, let's just go through how we came up with that sort of simple parsing library that we can build from scratch. And the way we're going to go there is we're first going to define what a parser is. So in simple words, if you think about it simply, a parser is just a function that takes a string. And it will return to you something of type A, which is your return type or the value you want from that parser, and the remaining string. So it will return to you a couple of these two things. A very simple part. I think that's a very simple thing what a parser would do. And that's it. However, there's a problem in this definition. And the problem is that, one, I may not be able to successfully parse everything from a string. So let's say I give an invalid input, in which case I can't find anything. My first definition can't encapsulate that in the dive system. Similarly, if I have an ambiguous grammar, I might have multiple results from the same input string. So in order to encapsulate these two cases in my dive system, instead what I'll do is I'll return a list of tuples of type A and top type A and string. So I can have multiple results. And using this clever technique, basically my empty list would mean that my parser failed. And if I multiple, it means I have an ambiguous grammar and I have multiple results after parsing. So the next thing we're going to do here is, oh, sorry. We're going to define a new type called parser. And this takes a generic type A. And we have a type constructor that takes this function, string to basically the same function that we defined earlier. And that's it. So we define it as a type. Encapsulating this function as a type. Where, as I said before, empty list means failure. And this is basically a list of a result of type A and the remaining string. And that's it. We're done defining a parser. So what can we do with it? Yeah, as I mentioned, multiple case. OK, so let's define our, using this type definition, let's define our first parser. And what the parser is going to do is it's going to consume the first character in a given list of input. And it's going to return just that character. So by consume, I mean that in the remaining string, it'll give you everything but that first character. And the value it returns is going to be the first character. So, and here's how I implement it. It's quite simple. It's type is a parser of type car because the return type is car. And here's the parsing function. It just does a case-to-case. This is a pattern match with the string. If that string is empty, empty list. Because, and remember, empty list is failure. So it means if you give it an empty string, this parser would fail. Otherwise, it'll just return to you the first element of that list, the first character of the string. So quite a simple parser. It's quite useless too. Let's see what more we can do with it. Also, if I just want to apply this parser on some input, I'll just unwrap the parsing function and apply it on a string like this. So I can define a parse function to unwrap my parsing function and apply it. So quite straightforward, again. So now here's where the fun stuff begins. In isolation, this is not very interesting. But let's say we want the ability to bind two parsers together.  Oh, OK, lose connection, I think. All right, OK. So let's say I want the ability to bind two parsers together. So I want to chain the parser such that the result of my first parser is fed into a function that takes that result and produces a new parser. And in this way, I can combine multiple parsers together or bind them together, so to speak, right? And let's say I have this need. And the way I implement it is, and if you look at the type definition of bind, it's going to take a parser. It's going to take a function that takes the same return type as the beginning parser. And it's going to return to you a parser b. So we have this binding function. And this whole thing returns to you a parser of type b. And in the implementation of this, we have three steps. So we basically create a parser. This parsing function, remember, will return to you a parser of type b, as the type definition says. So this parsing function will return to you something of type b. And this function will take your string. What it does is it first applies the first parser, parser p, or first parser. It will apply that parser on the original string. Then it will, and this thing will give you a result of applying. So this thing will be a list of a and string, right? It'll give you a list of a and your remaining string. The next thing I'm going to do is I'm going to apply this to a map and parse. This is my function f, remember. This is the function f. This function returns to me a new parser after I give it some input. Sorry, guys. OK. This function gives me a new parser after I give it some input of type a, right? So I will apply that new parser I get with the remaining string I got from the applying the first parser. So I, and this stuff will basically give me a list of type b and string, right? Because I'm applying the second parser. And the second parser's result type is this. So I get a list of and a list of a and b of b and string. And then I just flatten the result out to get this nice result. So that's what bind is doing. And in isolation, it might not seem very useful for why I'm doing this, but we'll get to how this is useful. One more thing you need to bear in mind here is how the failure case is handled. So if at any step, so let's say my first parser fails. If my first parser fails, the list I pass to the map is going to be an empty list, right? And if you apply a map on an empty list, you're still going to get an empty list. So my empty list is going to be propagated throughout. So in case my parser b fails to consume anything, it gives me nothing, the whole thing will end up being an empty list, which is fine. Which means I'm passing the failure case throughout. Yeah. Is that binary operator flip composition or what? Yeah, it's OK. So the binary operator is a flip composition. Good point out. I prefer, visually, I prefer changing or composing functions using this operator, because it shows you the steps in order. In control dot, dot connection. Yeah, correct. OK, thanks. Thanks for that. I define this myself usually, but thanks. Yeah, OK. So far, so good. Yeah, as I said, in case of failure, empty list is propagated down, which is great. So I defined bind, and now I'll define another function called unit. And what unit will do is unit will take any value, and it'll just produce a parser from that value that consumes nothing and just returns that value. And this may seem useful, but it's actually quite useful when we get to why it's actually quite useful. But essentially what it's doing is it's taking something and putting it, just putting it inside the parser type, which, I mean, and the implementation we look at is quite simple. It just takes something of type A and just returns to you a parsing function that just returns something of type A in a list and the same string. So it doesn't actually consume anything. And that's it. So using these two functions, we can actually do a bunch of interesting things. And some of you who aren't familiar or haven't figured out what I'm going towards, why am I talking about a unit properly doing this right now, which is just a justifiable. So which begins the next part, parser combinators, which is where we're going to apply this concept. So with parser combinators, what we're going to try doing is we're going to try combining simple parsers together to form more complex parsers using bind and unit as our two fundamental operations. And let's define the first combinator that we're going to implement. It's called satisfies. And satisfies will just take a predicate and it will return a parser that will consume the first character. If that predicate succeeds, it'll fail otherwise. And the way we're going to implement this, using our nice bind and unit, is just like this, right? It satisfies, it takes a predicate function, and we bind it to item, which we defined previously. So item will take your first character from your string, which we defined this earlier. Since the return type of item is a character, in my binding function over here, this type of C is going to be a character. I apply the predicate on character. So if this predicate succeeds, then I will return unit C. Unit C, as we defined earlier, is just going to return to you a parser that does nothing but returns this value, right? Otherwise, we'll fail. So this is just a failure case, a parser that just returns an empty list for any given input. So what this thing is doing is simply it'll consume first character, and it'll check against a predicate. If the predicate succeeds, it'll carry on parsing. So and here's where we entered the monad. And here's where things get interesting. So as it turns out, bind and unit, surprise, surprise, are common abstractions we have in Haskell. And if you look at the type definition of bind, so in the Haskell monad type class, we have two functions, right? And as long as you implement these two functions, you are technically a monad, right? And that's how type classes work. I mean, there are obviously monad rules, but we're not going to get into that. But what I want you to look at is in these two functions that we're supposed to implement to be called a monad, if just look at their type definitions and compare them to type definition of bind and unit that we defined earlier. So if we look at return, just swap A with parser. Just swap M with parser, and it's the same thing, right? Similarly, for this funny arrow looking operator that is called bind, if you just swap M with parser, we get the same thing as we've already implemented in bind, right? So turns out this sort of operations or combined doing these sort of higher order operations is quite a common thing. And Haskell has a type class called monad to encapsulate this very concept. So let's make our parser an instance of this type class, or let's say it, or in other words, it implements this type class. Or if you're from an object-oriented world, wait a second, let me just close Slack. I think that's what was in this. Sorry, sorry guys. OK, so if you're from an object-oriented world, you can think of type class as sort of like a protocol or a constraint on your type. And as long as you implement these two, as long as you implement the functions that you're supposed to, you will be somewhat implementing that protocol if you want to think of it as an object-oriented way. So our implementation of, so to implement parser and make it a monad is quite simple. We just make return equal to unit, which will work. And this funny looking operator equal to bind. And we're done here. So our parser is now a monad, quite simply, which means that instead of using bind and unit, we can just use these two functions. Hooray, we've done a lot. And once again, this is nothing special by itself. So here's where the fun part comes in, or here's where the advantage of making a monad comes in, really. Typically, when you write parsers using this thing, using this funny looking bind operator, you'll probably have something like this, where you apply your, let's say, you have a parser, and you bind it to this function. This is the result you get from that parser. Then you continue parsing, so you apply a second parser. You get another result. You continue on n times. And then you probably have some function where you construct some semantic value using the results of the parsing that you did earlier. That's what you would typically do in a parser. And this is what your code will generally look like. If you build your parser using this operator. Turns out Haskell has a nice syntactic sugar for this. So we can add some do syntax. And what the do syntax does is it's quite simple. Just flip the operations. So instead of a1, so basically what this says is that it'll apply parser p1 and bind it to this value a1. So basically just in your mind, you just think of it as syntactic sugar and you just flip this around and you don't need that arrow anymore. It's just some nice syntactic sugar to write the same thing. But the flow of your parser becomes quite clear because of this. So I apply parser one, I get this value, apply parser two, get this value, then I apply my semantic action. Same thing. But the syntactic sugar makes writing parsers a lot simpler. And that's all it's doing. So just to clarify this a bit, I'm gonna define a new parser. This parser will take three characters and throw the second character and just return to us a tuple of the other two characters, the first and the third character. So let's just define this parser. And we're first gonna define it using our bind and item. And the way this parser works is I bind, I apply my item parser, which we defined earlier once again, item takes the first character right from a string and if the string is empty, it'll just fail and propagate failure throughout. And I get my first character of the string out from it. So I bind it to this function. Then I apply another bind where I apply item again and get the second character out. I apply the third time and get the third character out. And finally, because in this parser, I want to return a parser of type car, car. I will just apply a unit operation to convert my result or to wrap my result in a parser type and I wrap it with the first and the third character, ignoring my second character. So that's how I will write the simple parser using the constructs that we defined earlier. This is a nicer version of this. I can write using the simple arrow operator. So yeah, the same thing, just swap bind with this funny operator and just ignore it. We don't care about second, so just don't give it a variable name. Lastly, we can write it like this using do syntax. So we take the first character out, we apply item again, get the third character out. Voila, simple, right? Just apply do syntax to write our second parser. So that done, we can use this sort of thing to define more combinators and use those to construct a more powerful parser to parse something capable of parsing JSON, for example. So we're gonna define a new parser, new combinator. It's called M plus, all right? And what M plus does is it takes two parsers that have the same return type and will return to you another parser, basically combining the results from the two parsers. So if you look at the implementation, all it's doing is it's concatenating the list of results we get from applying parser P and applying parser Q. So it's nothing short of just concatenating the two results in a sense, adding or plusing the two parsers together. And in a way, if you think about it, you can think about it also, it's sort of like saying, okay, apply parser P or apply parser Q because once again, if either of my parser fails, it's an empty list, right? So in a fact, and what it's saying is, okay, either apply P or apply Q and just return to me the results of applying them both. So you can think of it sort of like an OR operation as well. Let's make another version of this. Similarly, let's call it option. What option does is it just applies M plus but gives us the first result, which is usually what, and the reason why this particular operator is useful is because it says, give me results from P exclusively or Q exclusively.  So once again, what this will, so even though M plus will actually parse, apply both P and Q, if P fails and Q has a result, you still get the Q, you still get Q's result but this Q's result will be the first element of this list. If P succeeds, Q fails, same logic. If they both fail, we get an empty list. So that's how option works. Quite simple, right? Similarly, let's define an operator that just takes a car and just will consume, will basically continue parsing if it sees that character, otherwise it will fail and we just use our satisfies operator we defined earlier and we just apply the satisfy operator with equal with this predicate function. So we have now a function that we can use to parse a particular literal car. Similarly, if you want to take a string, you want to parse a particular literal string, we can define a new parser, something like this, which when parsing an empty list will return an empty list, will return meaning it will return to your parser with this empty list. Otherwise, what it will do is it will use the car parser we defined earlier, it'll apply the car and then it will recursively call string, this parser again on the remaining part of the string. So in the base, so at the end of it, when we have the last character, we'll get this case and which will return to us an empty string. So this whole thing will return to you the string itself that you were checking against. So the nice thing over here to note is we can define parsers recursively, which is quite powerful. Similarly, we're going to define two more parsers called many and many one. So what many will do is, many will apply a parser p, zero or more times, and many one will apply a parser one or more times. And we can define them in a mutually recursive manner by saying, okay, many p is basically many one p. So apply parser p at least once or more times or return an empty list, which is bear in mind, this is not failure, this is just a parser containing an empty list because if you look at the type definition of this parser, it's a parser that returns to you a list of type A. So empty list here means that your many was applied to your times, which is fine for us. Many one on the other end, what it does is it'll apply parser p first, it'll take the result in A, then it'll apply many and put the result in A, in A's and it'll just find the result, it'll just return the result by a, by concatenating by making this a list of the two, stuff that of the two things that you got. So basic point here is we can define this parser in a nice mutually recursive manner. And these parsers are pretty powerful because they allow us to apply a parser more than once. So, and like when I read this in the paper, so this is a lot of this, most of this stuff is not my invention, this stuff I read in a paper written by Eric Meyer, it's quite a nice paper, I highly recommend you guys read it as well, it's linked to the thing. But when I came across this in the paper, this was literally my reaction because I realized, okay, this is actually quite simple to implement this. Anyways, so lastly, let's say I wanna write a parser for a simple language that basically is composed of mathematical expressions like this, like seven plus five or this sort of expression, right? Let's say I wanna write a simple parser that parses this kind of stuff from scratch. How would I get around doing it? I'll show you that. So like the way I would get around doing it is we will first define some simple parsers and let's define the grammar for this sort of, for this kind of language. First thing I'm gonna define is something that can parse white space for us because white space is quite annoying, and you can have arbitrarily many white spaces in between, right? So our parser for white space, and let's call it space, the way it works is just a parser with return type string and it'll just consume many instances of this predicate, is space, and I define a space simply as something that, something that'll take a space, a new line character or type character, otherwise it'll always have been false. So basically zero or more applications of a space or satisfy this space will return, will basically be your space parser, which is great. Next thing I'm gonna define are my tokens for this particular grammar. In this case, a token, I define it, so I define a token as a parser that takes another parser and applies, and basically parses the space around that thing, and it'll just return to me something before a space, right? That's a token in this simple language. So in this particular case, I apply my parser P, put the result in A, and then I apply a space. I don't care about the results of the space, so I throw the result away, and I return to you this thing, this thing, the result A wrapped in a parser. This thing is token. So similarly, although this particular language I don't have symbols, I can define a parser for a symbol. And a symbol, all it does is it's a token with this string, the two parsers, the string. Similarly, I can define a parser for a digit, and a digit is just something that applies, Haskell's is-digit function, cheating here a bit. And a number is just one or more digits. And I just use Haskell's read function to parse this because this digit returns to me a character, if you notice. So I just use Haskell's, and this thing will return to me an array of cards in the string, so I use Haskell's read to convert that into an int. So this number will parse an int, and that's it. So with these tokens, I can define a complex grammar, like I mentioned earlier, using something like this. I can define my expression to be anything to be a parser of type int. I can define an add operation as a parser that takes another operator, that takes a binary operator int int and returns int, and a multiplication operation, same type signature. And the way this parser is implemented is I have this operator, I'll get to the implementation of this operator soon. But basically anything in my expression can be a term, or it can be an add operation. A term is a factor, followed by a multiplication operation, and a factor is just a number, either a number, or it's something in between, or it's an expression in a bracket, and this expression returned. So if you think about it, it looks a lot, this code looks a lot like the grammar that you actually would write for this kind of language. And I define my add operation simply as something that can be either surrounded by a plus or starts to run by a minus, and my multiplication operation is either a multiplication or a division. And the reason I deal with them, deal with these two things separately is because I want to follow the precedence rules that multiplication is applied first and addition is applied later on. What happens in this operator is, well, I'll just show you guys the source code for this. Oh, sorry. Yeah, I'll show you guys, show it to you in a bit. Ah, here we go. In my chain L1 operator, all I'm doing is I take a parser of type A, I take another parser that takes a function that takes two things of type A and returns to you something of type A. So it's basically, it's a binary operative. In our case, this will be plus minus multiplication division and return to you something of a parser of type A. And the basic gist of this is that this function will parse things around my operator. That's all it's doing to get an intuitive idea of how it works. It's just parsing stuff that is around my operator. So with these two, with this thing, I can construct this simple-looking grammar. And I'll just show you guys whether this thing works. So I call it, so here's the parser that I wrote. This module, there we go. That's how it works. So I do a more complex thing there. So you can see this sort of grammar, it can parse this sort of grammar quite easily. And that's all the monocode that you have to write for implementing this kind of simple parser. And that's it for parser combinators. Now for those of you wondering, for those of you who write parsers, this is not obviously the only way to parse things. We have parser generators, which are, you can say more, and the way those work is quite different. You provide them a grammar and they will generate a parser implementation for you. And Haskell has some parser generators. So it's not the only way to parse stuff. But it's an interesting way of thinking about parsers. And it's an interesting way of thinking about how parsers combined with monads can be used to make a pretty powerful parsers at the end of the day. Side note, Parsec, the way Parsec works is pretty similar to the implementation of the simple parser combiner library I showed you guys earlier. Parsec works similarly, but it's a lot more, it means a lot more things like error handling, it's a lot more performance. So for real-world projects, obviously, please use Parsec. It's a lot better, it's really powerful. And that's more or less, yeah, that's actually it. Lastly, the reason why this is kind of relevant to me as an iOS developer originally. So I'm an iOS developer, but I have a lot of enthusiasm for Haskell. So at work, we face this problem where we needed to generate object to see classes and from parsing proto-buff specification files. So we needed to write a parser for proto-files and I wrote a parser for the proto-files using Parsec and it was a pretty nice experience. And I read this paper around the same time, so I was pretty impressed by what we could do with parsers in Haskell and how simple they were to implement using Monads. So this is just a project I did and it was quite useful and that's how the iOS thing is slightly kind of relevant in a way, yeah. That's the end, any questions? Yeah. Just for noting that the one thing that you didn't touch on is that your example doesn't need monadic parsing, so why would you use a monadic parser combinator? I mean, both the expression parser and the JSON parser, you can see if you can go that they only use the applicative structure of your parser type. Correct, yeah, that's true. So why would, in this case, okay I guess my real point is it needs to be a conscious choice to go with monadic parsing instead of an applicative one because of course if you make an applicative parser you can exploit all that static knowledge that you get there to make a much more performant implementation of applying it, right? Because you can compute like starting sets like which are the characters which can possibly be accepted as first characters. Second thing, so don't jump into monadic parsing just because parsing is one. That's a good point actually. It needs to be a conscious decision if you really need monadic power or if applicative is enough. That's a very good point actually. And the good example of this actually is there's a applicative regular expression parser library on AKG which allows you to parse regular languages. So it wouldn't work for your examples but it allows you to parse regular languages in the same applicative interface. So you don't get some string or it's not like, in most programming languages, when you apply a regex or something you either get like a single bit of every match or you get like a dictionary of what are they called these captured values, right? But with the applicative regular expression parsers you can have some kind of structure inside your parser. So just like how your parser doesn't return a tree to you, it just does something while it builds up that tree. The tree is implicit. So the same can be done with regular expressions and what you get is something which parses in linear time like you would expect of a regular expression parser but still allows you to do meaningful combinations or meaningful composition of sub parser. I see, I see, I see. That's a very good point actually. The reason why this thing uses monads is actually the reverse. The tutorial or the paper I already read was more of how to apply monads in a particular problem domain. So how do we can apply monads in parsers? So the reason why monads came into this is more of an example, this is how you use a monad. So that's the main reason, not that's the only reason actually for why monads are brought into this in the first place. It's not a, I agree it's not a, it's from a usability point of view, applicator makes more sense I think, right? But this one is more of a kind of a monad tutorial-ish thing. So it's like, oh, we can use monads to build parsers together and that's okay, that's what monads are. This is basically what monads are. Yeah, the point I want to make is that none of the examples actually use monads for that. All the combinators you use only use the applicator structure because that's too important for- That's true actually. The newbies to recognize instead of- That's actually a good point. That's a good point actually, yeah. In the case of JSON, don't you actually need a monadic parser because when you have an object in JSON, the keys of your dictionaries need to be distinct and so you need to know what you've already parsed. That's actually very fine. Okay, the code that we saw here didn't take care of that. That's true. So I am talking strictly about the implementation we saw here. I didn't read the JSON parser, right? I read the given the motivating problem. But that's just an example of also because the language then becomes context sensitive, right? So with some hand-waving, if you prove that you're not going to be able to parse that using a finite attribute parser, because the grammar is too complicated for that. Yes. I mean, at this point, I've actually parsed how many JSON libraries out there will actually give you a parse error on it that we can't here not just take a second second occurrence. What is ace on jim? What almost assume maybe take a second occurrence, but I would really be interested to try that, right? Is it even in value? That's definitely a right, right? I would assume JavaScript would have to accept that because JSON comes from JavaScript, maybe that's it. The JSON is well-specified.


What is scoliosis and what causes it? Scoliosis is a term that's used to describe a curvature of the spine. The word itself is from an old Greek word that meant bent or crooked. It's describing a curvature of the spine that is three-dimensional in nature and it's usually found in kids who have some level of asymmetry or abnormal curvature of their back that is noticed by either the pediatrician or the parent early on in their early adolescence around the age of eight, nine or ten. And as we examine them and as we look a little further into it we find that their x-rays reveal a curvature of the spine. And the degree of a curvature is really what defines the challenges that scoliosis has in the medical community. What are the different types of scoliosis? Well, scoliosis itself is a definition that has been refined over time. There is the typical asymmetry in the spine that is found in many patients in the population. So for us the cut-off has always been ten degrees. Now that was an arbitrary decision made several decades ago but it has become a very helpful tool in examining the patient who is referred for scoliosis. Most patients with curvatures less than ten degrees aren't really considered to be at risk for worsening or progression of the scoliosis and don't really need any further work up. There are indeed several types of scoliosis. Most of them are defined by the age of onset or the cause of onset. So juvenile scoliosis or adolescent idiopathic scoliosis is pretty much determined by the age of onset of the scoliosis. Congenital scoliosis on the other hand is referring to an abnormality within the formation of the bone or the vertebra and that might be found or picked up on an exam earlier in presentation of the patient. And then there is adult scoliosis and then there is neuromuscular scoliosis often associated with either cerebral palsy or some of the other neuromuscular conditions. What causes scoliosis? The true cause of scoliosis is really unclear. What we know for sure is that certain medical conditions such as cerebral palsy and other neuromuscular conditions have a neurological scoliosis associated with them. But a great majority, more than 80% of scoliosis, don't have a really defined etiology or cause for that. What we've been able to determine is that there are multiple factors associated with scoliosis. Some of them are genetic, others are hormonal and we know that it's the interplay of all these different reasons that cause the curvature of the spine. If I have scoliosis, will my child get it? Very good question. What we know is that scoliosis has a multifactorial reason or factor and interplay that causes the curvature in the spine. That includes a genetic predisposition as well as some hormonal imbalances. And so while we are unable at this time to tell you what the percentage of descendants will get scoliosis, what we do know is that there is a close association usually within a first degree relative, meaning a parent or a sibling or so will have scoliosis. What in house scoliosis typically diagnosed? Scoliosis is usually picked up on routine surveillance or annual visit by the pediatrician. There are also other systems and mechanisms in play in our communities including school screening programs to pick up on these curvatures. What we've learned is that any time the occasion arises, whether it's a parent that has noticed an abnormal curvature or whether it's a pediatrician that is picked up on some asymmetry, we ought to take a look. And that means at least getting an x-ray, at least doing a good physical exam from top to bottom, examining the patient for any other associations that are also related to scoliosis including neuromuscular diseases and other syndromes that are associated with scoliosis. A good physical exam oftentimes can help you cone in on the etiology and what kind of expectations you may have from the x-ray findings and maybe the true cause of the scoliosis. Why is early intervention so important with patients with scoliosis? The challenge with taking care of patients with scoliosis is to be able to prevent the progression of the curvature of the spine. And usually this happens during the growth spurt. As the patient grows in height, there's a higher likelihood of the curvature getting worse. With that, we try to observe and follow the degree of curvature over time and if they meet the criteria for bracing, which is usually between 25 degrees to 40 degrees, we try to jump early on to that and brace them so that we can stop the progression to more severe angles that require further treatment. What changes should be made to lifestyle when someone is diagnosed with scoliosis? Very good question. That really depends on how much pain the patient has. Oftentimes when the patient and the family is diagnosed with scoliosis, they like to know what type of exercises or activities they should avoid or potentially do to help reduce the extent of the curvature of the spine. And the truth is, no activity or no sleeping pattern has been shown to worsen the curvature of the spine. It all comes back to whether the patient has pain or not. If the patient has pain, we do often look a little further because most scoliosis doesn't cause pain. It may warrant a further workup such as an MRI or maybe genetic testing or other types of workups. However, if the patient isn't having any pain, they can sleep and participate in any activities in any form that they want as long as they are comfortable. It hasn't been shown to worsen the extent of the curvature of the spine at all. What treatments are available for scoliosis? Will everyone diagnosed with scoliosis require surgery? There are various treatment options for scoliosis and it really depends on what kind of scoliosis you are dealing with. If it is congenital scoliosis, it oftentimes does need an intervention over many years to make sure there is symmetrical growth in the spine and that there aren't any long-term effects such as respiratory complications that may affect the patient. If we're dealing with adolescent idiopathic scoliosis, what we'd like to do is to be able to jump on early so that we can diagnose the patient and if the patient needs bracing, we start early. So bracing is one of the more preferable, non-invasive forms of treatment for scoliosis. A majority of our patients are observed and that's all they really need just to make sure that there's no progressive changes to the scoliosis. However, there is a certain percentage that requires surgical treatment. Most of the current studies do show that curvature over 45 degrees do need to be attended to and usually that means spinal fusion. Now, the purpose of spinal fusion is usually not to completely correct the spinal curvature but rather to stop the progression. So we can usually expect somewhere close to 50% correction of the curvature but what we'd like to do is stop the progression as the patient grows older. Are people able to return to normal activity after scoliosis treatment? That depends on the treatment. If the patient is currently being braced for their scoliosis, all that really means is that they need to meet a criteria of hours per day in the brace. Studies show now that 18 hours a day is sufficient to stop the progression of this curvature. So if they can get 18 hours per day and that includes time spent sleeping in the brace overnight, they can take off their brace as they need to for their different activities ranging from gymnastics to swimming to football. Now, for those that undergo spinal fusion, the goal of surgery would be to get them back to their activities. However, it will take some time. The surgeon does indeed need to do some interval follow-up to make sure that spinal fusion actually has been achieved but eventually the goal would be to get them back to all the activities that they're used to doing and that could take up to six months of follow-up. What are the goals and expectations of scoliosis surgery? How much correction would you expect to achieve? While the goals of bracing really are to stop the progression of the curvature of the spine, the goals of surgical spinal fusion can include not only stopping the progression of the curvature but to correct some of the deformity. And that really depends on the degree of the curvature to begin with because unfortunately some of these curvatures can impact the development of the lungs and the heart. So some of the correction that you can achieve during surgery may help the development of these very important organs. As far as the degree of correction, it really depends on the severity of the curvature but what we tell our patients is that they can expect at least a 50% correction and the magnitude of the curvature. For more information about scoliosis cure here at NYU Winthrop Hospital please call us at 866 Winthrop or visit us online at nyuwinthrop.org


My name is Matteo Sandi and I work at the Centre for Economic Performance at the London School of Economics. My research is about school discipline and youth crime and so broadly what leads a young individual into a crime career and what school can do to tackle that. I'm trying to communicate my research as widely as possible to government agencies, to the media, to social networks.  In one research project that I've been working on over the last couple of years I use data from the National Pupil Database, which is accessible by the UK Data Service to investigate whether granting autonomy to schools that have become academies have led these schools into using exclusion to manipulate their aggregate results. Being a UK Data Service Impact Fellow has opened many opportunities for me. Being an early career researcher allows you to have a new voice, have a fresh voice and so I believe there's a genuine advantage to be in a new voice in the political arena.


So to kind of end the more structured part of the conference, we wanted to have a panel discussion around media wiki best practices. And we've invited up here Cindy Cilice, Brian Hildebrand, Darren Welsh, and Ben Fletcher, whom you all, I think, have heard of and met over the course of the week, if not before. And my name's Chris, and I'm the moderator. And so I've presented a few questions in, again, another etherpad that you can get to on the program. So I'm just going to start the conversation off with kind of a light question. So again, these are best practices for using media wiki or adapting media wiki. So I'm going to start here with one of the questions. Cindy actually put in the document here. How do you get a new wiki project off the ground? What's your best practices for starting, assuming you're starting from nothing? Well, so I mean, we've already got several going. So if some new group comes to us, actually our first question is usually, well, why do you think you need a wiki? Why do you deserve one? And that goes back to the emerging conversation we had earlier was, at first we were handing out wikis to everyone, but then we started realizing that probably wasn't the best approach. So maybe this isn't the answer you were looking for, but really think about the structure of all of them together and how you really want your whole knowledge corpus to be organized and split. Back when I used to create new wikis for people other than myself, one of the first questions, obviously what would be the access to the information who will be using it, what their domain is, and probably everybody in this room has heard me say this several times, we would never start giving somebody just an empty wiki and say go forth and wiki, because that's just not going to work, you don't get the traction, you don't get people contributing with the blank piece of paper problem. So we would always talk about their domain and do essentially an object-oriented decomposition and what are the first class objects, what are their attributes, and then based upon that, create namespaces and forms and templates using page forms, using either semantic, media wiki or cargo, set up categories, and give them a framework to hang their data off of as a starting point, and then what you find is people are able to contribute and the more contributions you have, the more it builds steam. But you can't just give somebody an empty wiki and expect, but it's a little unfair since I wrote the question, so I already had an answer. Sorry, no. I think I absolutely agree with what Cindy said there in terms of when you've decided what route you're taking, absolutely hold the hand. I think, but initially, make sure it is the right content management system for you. So absolutely understand, break down what their requirements are, what the use cases are, and from there, it might not be the right content management system for what they want to achieve, work out what their highest priorities are, and then base it from there, and hopefully there'll be that convergence towards whichever content management system it is. Yeah, I think I'd agree with everything I already said, and then just add maybe try to set up a organizational structure, some people that you think might be champions and will be really interested in training others and get them started as early as possible, and then have content ready for the masses once everybody comes in. I wanted to add that there are an opportunity to ask questions in the audience as well. That was just kind of a starter question. I have some, we have a lull in questions, I have some here listed, but I do see a question of hand raised in the back there already. Yes, which role does the IT department play in this? I think that's a really, really good point because information is the lifeblood of any organization and no longer, no longer IT departments seen as resource burdens, they're actually your way of gaining competitive edge. So more and more CIOs are sitting up there with the chief executive officers offering them that ability to exploit the information and sit there, and I think that trickles down. So the IT department need to be off, giving the chief information officer, they need to be the knowledge, understanding the business. So they're now turning into business analysts as well as the technical knowledge. So I absolutely see it's only gonna grow the importance of the IT team and their responsibilities and you want to be in that space where you are offering solutions to the organization for them to go further. I have an opinion. I agree completely the IT department is absolutely critical and that can be both a good thing and it can also be a real stumbling block. I have had issues in the past where probably a lot of these people have had the same issue, but we've already got a share point. We've already got confluence. We pay for something, we've got people supporting it. You want us to install this piece of open source software and make us maintain it. So that's one of the reasons why I frequently talk about the need to make it easy to install, upgrade and maintain MediaWiki, that that needs to be something that is provided to the third party community, that the third party community develops and provides to itself. Until you can say to an IT department, hey, here's this thing, install it, don't worry, it'll work, you're gonna get pushback from IT and so yeah, the IT department is absolutely critical and you can either have them as your ally or your, I don't wanna say enemy, but well, you know. Aaron, going on with that, we had some experience in NASA maybe you can touch on on finding the right person to talk to an IT. If you come and present a presentation to IT, it's more likely to get shut down or I think we had cases where we tried once with one person, they shut down and we just had to find the right champion in the IT department. I don't know if you can talk to how we got started there. Yeah, not to get way back into the details of our history, but we're in a kind of a unique case where we created the wiki kind of underground and so we were our own IT department in hiding. We're like a guerrilla wiki team but eventually we became public and let people know what we were doing and we've actually grown, we've built a good relationship with our IT department because we want it to succeed so we've taken special effort to work with them to make sure we're meeting all of their requirements and in some ways, so like for example, the way that we are required to audit users when they request access and how their usership is maintained, we do a way better job than SharePoint. Like SharePoint somehow has this like rule where they're an exception and they don't have to do it and we're like, well that's lame but we go ahead and work with them to meet those requirements and so now we're kind of like the golden standard. People look at us and say, oh, you've done really well with the wiki and so now we've built cloud, I think, by working with our IT department. Any other questions? I'm gonna take one from the list here really quick and Cindy and I think all of you have kind of mentioned this when I asked the first question about how do you get off the project with the ground. So wikis are different than I think what a lot of people maybe experience in their careers, SharePoint and other things kind of are ubiquitous and other between companies, between positions and so on and so forth. So they can be a little foreign and a little different. How do you make it something they're comfortable with? How do you get those, find those, as you mentioned, Brian, those champions? What are some of your best practices to encouraging folks to take the wiki approach as it were? So I'll just kick things off. I think one of the strengths of a wiki is it allows each person to contribute in the way in which they're comfortable. So like some people are very technical detail oriented. Some people would rather work on the structure and the organization of things. Some people are more kind of collaborative and wanna, you know, I mean, it kind of goes back a little bit to the gamification motives that I've talked about before. But so you don't have to tell people this is your role and you have to do this with the wiki. You can just kind of let them gravitate to where they're gonna be most useful. I think it's a, the key thing is the critical mass. So once you get enough people who find the value in the wiki, so rather than having to ask someone, they can find that information. I'm not saying don't communicate, but you know, there are the times where you want to find some information, that wiki finds it. That, you've then convinced that person the value of the wiki. And when you get to a certain stage, this critical mass happens and they all start contributing because they want to be part of this and they see the value of it. And getting to that stage is the challenge. So there's, you've either got mass support from a lot of people or you've got high level direction in terms of people being directed to, you know, what did you call it, wiki time or something? I can't remember, in your presentation. Didn't you, wiki, I can't remember anyway. In your presentation you took wiki, wiki, you know. So, you know, I think implementing a wiki, wiki of everybody spend 20 minutes, you know, every day or so on, just to, just to contribute. Sometimes unfortunately, because people are busy, they need to almost have that direction to start with. But once you hit that critical mass, you're in a far better position. Yeah, I just say try to find, know the users, try to figure out what everybody's individual pain points are and then address it. So it might be, I think a lot of the champions should be kind of servant leaders where they just spend a lot of time talking, figuring out what's wrong and then maybe constructing everything for that first user and then, you know, getting that one user to start doing it and then that person will be the new champion for that department or area of the company. Just gonna also mention that critical mass is important but it can also just be a critical mass of documents that have all been added. You can only have one real contributor and editor but for all the lurkers just having the critical mass of documents to start is another way of, I think there's two critical masses. One is the critical mass of documents or pages for the lurkers and the other is the critical mass of contributors. Just to add to that really quick, I think there's, I call them hooks but something in the wiki that is only in the wiki that many users have to go to and eventually after enough exposure of always getting this content out of the same place, you know, they start to realize they can actually edit and add and contribute as well. Yeah, and to echo, you know, having a strong champion for the wiki is absolutely critical. The first wiki that I worked on called Robopedia at MITRE was the robotics wiki that we used to document everything within the robotics program I was working on and the lead of that program said it didn't happen if it's not in the wiki and so absolutely every meeting, every interaction between any people, any piece of hardware equipment, any software had to get documented in the wiki and if you tried to tell him something, his first question was is it in the wiki and if it wasn't in the wiki he didn't want to hear about it until after it was and that was absolutely critical to getting adoption. Yeah, that kind of made me think of another thing. So in traditional documentation you might have one or two people that are each assigned as owners of a document and so as that person you end up getting all this input from people saying here can you add this to the document or this needs to be changed but with a wiki you can just say no, you can change it yourself and you know that's, at first people are like oh no, I'm not the expert but you have to push that, you have to say no really, I want you to go change it and if you get it wrong I'll follow up and help you clean it up. Just one thing too is to talk to the users about fault tolerance and just say mess up, do whatever and watch how quickly it gets cleaned up. So a lot of people are afraid to kind of edit the space where everybody else is looking but if you show them how easy it is to revert and edit or that other people are watching it becomes really powerful. I have a question going to a different topic now and for the entire room but more so for the panel for you guys up there. Do you guys have any suggestions on how to approach management when starting a wiki the question I've been seeing coming a lot is like okay, from a cost, how much do I have to dedicate to start up this wiki, right? It's like I need X amount of employees to do nothing but the wiki which is not quite how many of us started and so it's hard to convince them that no you can do this as a part time thing to some of your employees you just need those champions but they still struggle that no I need to dedicate one year of six employees just to upload all the content or get all the structure right I have a struggle with how to approach that. So I think in many cases you can bootstrap your wiki especially if you have word files but I mean we talked a little bit yesterday or the day before about using Pandoc and there's ways to import material to get you started more quickly but then I think probably the first step is rather than adding additional workload which I think is what management is usually concerned about is finding a way to say instead of doing it here now we're doing it in the wiki and I keep going back to meeting minutes I think that was a really good way to get started where instead of just emailing out to the group some notes and then those notes just get lost forever in your email now they're forever in the wiki and they're searchable and they're linked to articles and so just replacing that one basic function right there will get you committed. One other contribution to make towards that when it comes to using a sustaining operation as a way of moving to wiki is that when it comes to new hires who are forced to read all the training documentation in the org they can convert it into wiki markup as they're reading through that so that's one way of hey those hours we're gonna be building the material anyway. Likewise if your organization has proficiency training the same thing's happening if you're re-reviewing all those documents or if there's the yearly requirement to review the documents that's another time where if you're going through it anyway the extra time it takes to convert it to media wiki markup is minimal. I think it's a really difficult question in terms of you're absolutely right I was very fortunate that I had supportive leadership that understood what the end game was but it did mean I was gonna be out of action in terms of focusing on this so I think as a community it's very difficult to because you don't know which direction you're gonna go in the wiki is gonna evolve as you're developing it and so on and how do you demonstrate business benefit early on so I think as a community we need to help with that and what we're talking about before how can we just show basic scenarios that people could absolutely get and work off and say look this is what is achievable just give me some time off in terms of let me focus on this and I'll show you some benefit in this time. Okay, go ahead. I hesitate to give this example and I did not do this so well first of all I'll say Wikipedia obviously is a great use case to point to folks when they are skeptical of the ability of a wiki to be useful you know and so granted it is a completely different scale so I heard a story of somebody that was within the organization I was with who was trying to get a bunch of four star generals on board with the idea of using a wiki and the example that they did and I do not advocate this and I actually you should not do this at home but they in order to get these folks to understand that this is not, that this is, that this will work they actually went out and edited a page on Wikipedia and changed the birth date of some famous person and within moments it was reverted and fixed and you know which is wonderful and self healing don't do it but you know in a positive way if you can use Wikipedia to show the utility of the wiki as a model I think that's a great way to convince management and even four star generals I think going back to kind of a point there about selling it and you know getting approval a lot, there seems to be generally two different and this is very large generalization some wikis are started as a computer under somebody's desk and they grow organically and slowly and another team, another team in another department and other ones are more hey we got this plan we got a structure in place you know we have an ontology or schema and we're going to start off with a whole big initiative and the wiki hits the ground running so two different ways to get started but eventually it always seems to be at least in my experiences and hearing the experiences of others at some point management wants to know how are you measuring this how are you saying this is successful how are you able to come back and say after organically the time or six months after the project started or whatever did we do a good job did we do what we wanted to do talk a little bit about that how do you measure the success of a wiki maybe not the wiki itself but like the stuff we're trying to do with it I guess I mean I think you just heard me ramped for the better part of an hour this morning there are a lot of metrics that we can use and it you know it kind of puzzles I'm kind of curious actually I'd like to pull the whole room like do your organizations care if all of your employees are contributing or are they okay if only 10% of your employees are contributing like is that, do they even factor that in we tackled it from a slightly different point of view we actually run media wiki, semantic media wiki internal to our organization it's our knowledge base it covers all our IT infrastructure knowledge covers up project knowledge and so forth the contributors we target we say that's the person who knows this stuff we want them to submit it's not a well who knows who knows about so we know who where the knowledge is and we want them to contribute to the corporate knowledge base so that it's there and it's shareable and we don't need to look go to them every time we need that information so we look at the contributors as basically targeted contributors that we need them to contribute it's different from the voluntary model we haven't found the voluntary model works terribly well the people that you want how do you encourage if you know who they are you just go and ask them to do it if they haven't volunteered to do it put it in what's the issue and part of it was what I presented well it's job security and all sorts of things that actually prevents them sharing you know one thing I noticed is it was brought up earlier with I believe the folks from GE and Ben it ties into some of what you were saying of we need some of these answers we do a good job Darren of showing the analytics but it's not speaking to management I think I think what speaks is money and I do think that's the missing point there is we haven't converted these analytics to what is the cost saving and maybe that's what speaks to management it's like okay this is worth the time because of X amount of money we're saving and so that might be useful for some of us to figure out ways to convert those analytics into direct cost saving I'll just throw out a random thought since this is sort of related also is I kind of see I see wikis a different way than a lot of people see them I think in that I get excited when I see conflicts I feel proud when the wiki raises to the surface disagreements because I think that's what it's for I think collaboration is not about we all come together and we have the same opinion immediately like that never rarely happens but you know a wiki is working when it has identified disconnects and disagreements and then you use it to communicate and come to a consensus and so I think that might be another way of measuring success but then going back to Costa how do you convert that to manager speak I'm not really sure One glass half full kind of analogy but I read a paper that stated that 0.03% of the population that goes to Wikipedia has contributed to it but that means that percentage of content consumers that are getting something out of it is huge so even though there's a small percentage doing something the percentage of people that are getting value is disproportionate We run a couple of wikis and the involvement of the user community varies dramatically with the purpose for which we build a wiki and we have one that we use for a very large interoperability testing event and all the participants in that event need to enter the data of their crew and their systems and the tests and the test results and everything in the wiki so it's more like a process flow that is enabled in the wiki and that means that you have a lot of user interaction in that one we have other ones that may be a little bit similar to what a lot of the NASA wikis are are more encyclopedic in nature and there you will find a couple of champions who contribute most of the data and the rest is consuming the data and in that respect if you want to draw more people to your wikis you have to give them the feeling that they're not contributing for your interest but they have to get something positive out of it themselves so the benefit that they get from using the wiki must be bigger than the burden they have to contribute to the wiki so you have to be smart in defining the products that make them tick and that is one of the other wikis that we have is completely the dullest of subjects that you can imagine is enterprise architecture but we have created a mechanism to automatically create overnight reports that give them data that would otherwise take weeks to compile in a word process or in a spreadsheet and that guarantees user involvement very much so my point in short is it depends on the purpose of the wiki but yeah and it depends on what actions you are able to take to commit the user community to that wiki so I'm not gonna directly challenge that but I kind of maybe take a different slant on what you had said that a user needs to feel that they're getting enough out of a wiki to compel them to contribute to it but I would also say if I know that something I contributed helped someone that I'm gonna be way more likely to continue to contribute I really like the thanks extension and I wish there were more ways to make it useful I try to thank people when I see it coming through my pending reviews or if I happen to go on the recent changes page but if someone does something that's like hey that's gonna help me down the road I try to remember to thank them because unfortunately that's the only moment that I can do it later on if I go and I'm like I need this information and I go search the wiki and then I find it in order for me to thank the person I have to go into the history and figure out which commit it was that added that and that's just a lot of work but so if anybody wants to give me an awesome birthday present it would be get blame or media wiki blame I guess it would be so I mean imagine being able to like acknowledge the people that gave you the info that you needed in that moment and just to click on it and say thank you so much that's awesome and then it figured out how to send that person an acknowledgement and then they would be encouraged to continue to contribute I think. So I guess I'm trying to remember what the original question was but I haven't thought. So one of the things I think we were talking about selling to management and how do you convince them and I'd say one of the things that we noticed quite often was knowing who you're trying to sell to and taking a salesman's-ish approach. And often the things that are necessary are changing a little bit like skinning making it look maybe sometimes less wiki-ish for the people who are the decision makers. We found often that a lot of the accoutrements a lot of the window dressing of a wiki could be distracting to a higher level person who's trying to visualize how this could be useful in their organization or in their solving their problem. And sometimes it was something as simple as changing the skin to something that had less, the edit was less prominent or that there weren't as many links or there was no sidebar. Maybe you have a very pretty, some of the other skins like chameleon that have a nice menu bar up at the top with dropdowns to make things look less busy unless you're looking for them. And just doing something as simple as changing the skinning sometimes made it look more like an application that they were used to seeing in their domain and they could sort of more. And so I'm not saying to hide, sometimes we had to actually not say wiki, which I'm not saying to completely hide the wickiness, but sometimes if you're trying to sell from a business perspective, you need to think of those things. A real brief follow-up, but when we first started our wiki, we actually had to call it, we chose to call it something besides wiki, we actually called it the EVA library, just because we figured people would associate wiki with the Wild West of information and I don't know. I was gonna add one thing to what Darren was saying earlier. One thing that the merge that we're trying to do now is showing is how many different cross wiki conflicts we had. So one of the diffs was showing up 750 different page conflicts. And so the two things that that shows you, one is that across just three mail codes in the org, and of course there's more than three wikis, but just across three wikis, they were literally duplicating 750 wiki pages worth of information across those three orgs. And there are differences between them. Not all of them were significantly technical indifference, some of them were just editorial, but they were still duplicating it three times for those editorial differences to appear. But then there are the subset of those 750 dupes that actually were technically significant, and that's where two different mail codes aren't talking to each other and they're not hashing out their technical differences. Now, the question being how do you monetize that or how do you attach it to the bottom line? I mean, I don't know how you can put a dollar sign on that, but just saying that these three different mail codes had all this duplication, somehow that has to transfer into lost work hours. We've also talked about the contribution and to me a far more valuable metric is the hits on the page. You know, I can show straight away which are the most popular pages and as we're transitioning, because we've still got the PDFs on the website and as we're transitioning across, we can see all this extra traffic. Now, yes, it can't be necessarily turned into monetary value, but it's showing the importance, the number of people we're having visiting each day. And it starts to focus the minds of our bosses when you say, don't forget, this is representing your organization. So you want to make sure you want to put enough resources behind this that it doesn't embarrass us. Okay, to kind of shake things up a little bit, I have a fun question to ask you. You're on a remote island. There's no hope of being rescued. You can only have one meaty wiki extension. Which one is it? I've got a question, we've got to answer back here. Okay. Push. Push. The extension push. Okay. Is that an answer? So you can get help that way. You can say send help and push it to some other wiki and then maybe something. Mine's a lot less practical. I'm not even sure if this was an extension. I don't know if you extensionified it, James, or if you just hacked it that one year, but for April Fool's, James set it up one year where when you go to the wiki and you clicked in a certain spot, a velociraptor ate your face. And I mean, keep me in good spirits while I'm deserted, so. Do you know what I'd generally expect, I'd actually go for the semantic media wiki extension just because I really enjoy building all those relationships between it. So I've got a lot of time to kill, so, you know, something to do. But you can't use semantic media wiki without page forms. You need a bundle. And I would also advocate for display title. What was that again, said again? Display title. Display title, okay. I guess maybe practically just the maps extension. All right. For best practices, again, for I think a lot of us come to these sort of conferences and try to get involved in the community to kind of get a leg up on the time it takes to get things spun up or to avoid certain pitfalls and things like that. What are some common pitfalls to avoid? What are some common things that maybe you've learned in the time you've spent with media wiki that you could bestow upon new folks or folks who are maybe not as deep into something like semantic media wiki or page forms that you're gonna like, okay, here's what you need to not do or here's how you should do it because I learned how to do it the wrong way. I think it's the most important thing is the quality of the content. And it's so easy to get distracted with all the different extensions and all these sort of pretty things. Sadly, the devil's in the detail and it is getting the content right first and then adding on the extra bits. You really wanna jump into, the temptation is to get there and start drawing maps and drawing all sorts of different relationships but the biggest focus has to be on the content because without that the wiki is not serving its purpose. Don't experiment with your users. So don't let them be the way to trial out a new extension or something else. Make sure you figure it out and then add it to the help pages and then release it on the masses. So I think we started off diving into the deep end and seeing how complex the things we could create and so I just cautioned to start simple and try to keep things as simple as possible and sort of along the same lines if you do get into semantic media wiki, try to name your properties as broadly applicable as possible. So property title, just keep it at that. Don't make it procedure title because then it's constrained to only procedures and not to books or whatever. So for example, I copied over a set of rules into the wiki and I created different properties for like applicable location, applicable hardware, applicable category, I mean I made several of them and then later on it was like, well that was dumb, why didn't I just say related article? I mean, the one property we probably have used the most and has been the most effective is related article and that's a fancy way of just saying this is related to that and it's so powerful. Yeah, that, definitely. I would also say and you're absolutely right, we need to definitely think about, well when you say content, I think data model, think of how you're gonna represent your data within your wiki and absolutely you wanna think of that up front and get it good but not necessarily get it perfect because the other thing that you need to recognize is that you can change that data model within the wiki, you can be agile but there's certain things that you need to do in order to make it easier to evolve your data model later and one of the things that I found that was always most helpful with that is the separation in your templates between the presentation bits and the data bits. The, you know, so the way that, the style that you often see for creating a template where you're setting the values of semantic properties has embedded with the, where you declare the display of those values, you put bracket, bracket, property, colon, colon, value, bracket, bracket, or square, bracket, square, bracket and that makes it very hard if you wanna later on change something to have all of that presentation and the setting the data value actually mixed together and I find that it's a good practice to do your presentation in one part in your template and then have all of your variables or your data set somewhere else. You actually reminded me of something and the idea of Wiki is, of course, you're creating this knowledge base but the other thing you really need to focus on is a knowledge base for those, the administrators, the curators of the Wiki. So a lot of the forms we created, we had no documentation, you know, and I'd actually quite like a standardized way that we should all document so I could, you know, I could go onto somebody else's Wiki and see what they've done. That'd be really useful because most forms are built the same way so it'd be really useful if we just all agreed this is how you create a page, you know, these are the properties you create, these are templates, this is how it all works. So literally you go in and you can say, right, I get it, I need to add that extra. Sometimes you're having to reverse engineer and if you can record that upfront it's really, really helpful. And that actually ties in perfectly with a question or comment I had was exactly what you said, Cindy, when I first tried to learn how to do a form and a template I picked up one of James or Darren's templates and I had no idea what it did because a lot of it was masked in, okay in this one template I was trying to copy they set a property on the top and then I don't see where they set it on this other template and it was because they were doing it in line and I, this was my first introduction into templates. Part of that is also I don't know how you guys feel about I guess there's two ways of documenting but some folks know the first few templates I made I loaded it up with comments and so it's a little bit ugly to read but it explained every line of code, okay this next line is gonna start the info box and this next line is gonna be your first line of display on the info box just because it helped me kind of be my tutorial. So the question I guess is more of what is the best practice on how to onboard people is it sending them to a tutorial? Is it sitting down with them and working on it one on one? Any suggestions on how we can onboard people? Can I ask a question about your question first? So you said loading your template up with documentation which from a computer science perspective is absolutely the right way to go if you've got something especially when you've got such a dense representation as a template could be but one of those things I often struggled with with adding things like documentation is the fact that you have to be very careful that you're not winding up adding additional blank space but programming in templates can be a real challenge and one way I've begun to start dealing with that is putting more and more things that are behavioral than that you would want to document into Lua using Scribando if only even for being able to separate the fact that the template is executable and that it mixes very much presentation in with that. So anyways, but that doesn't answer your other question but if you have any comments on how you were able to document templates without affecting presentation? It was difficult, I mean it was trial and error or I would hit save and something went and look right and it turns out that I did have an extra space before starting the comment brackets or ending the comment brackets so that was absolutely difficult and tying in is also just the standardization where when I saw some of the comments that James would make he would leave a few empty lines and put some pound marks or hashtag marks to signify hey this is a comment visually when others wouldn't and so I was confused on which way should I do it myself and so we've actually created a standardization committee we haven't met in a year but the idea was to try to come up with some standards at least on the NASA side of hey these are how we're gonna build templates this is how we're gonna document this is how we're gonna make our fields in all capitals or just different standards we can do to help be consistent but yeah. The other way often is to also to have a sub page of the template that's the documentation and not actually document in the template. That's actually exactly what we're moving to now with the merge we're trying to move our documentation into a sub page so. I like sub pages as well but also I like help pages so I think Wiki should be self-referential like there's no reason why you can't have information about how to do stuff in your Wiki in your Wiki or about your Wiki in your Wiki so I don't think a function or a new feature is kind of released until there's a help page describing how a new user can do it themselves. So I think that's actually an interesting point that we've been trying to figure out so as far as help pages and how to onboard people to using Wiki so there's a lot of stuff that we all use because we use the same software that would be useful for everyone to collaborate on and how to, I know Media Wiki has some of that information and then there's stuff that's, you know, there's tools that we use at NASA that are only applicable to us and wouldn't make any sense for anyone else to maintain and figuring out how to structure tutorials to combine those two because I don't want to redo what's already done on Media Wiki or done by some other resource because it is nice to have it within your own Wiki but it's also duplication of information and it's stuff that we have to maintain and it's just not worth our time and I'd rather focus on the NASA specific information but has anyone else worked on structuring like a tutorial for your users that goes in between external resources and then your internal stuff as well? Just curious about that. So just to kind of answer the beginning part of that question, I'm trying to get a lot of the help pages I built in my last company so I can use it on this company that I'm at but yeah, I mean, I think, you know, me and Darren actually were talking about this a little bit last night because it does feel weird to go out to mediawiki.org and grab help pages and then bring it into your Wiki but I think there's maybe an argument for it when there's some difference that we're doing that they're not doing. So maybe I'm on a different version of visual editor and the help looks different but also just the fact that it's in our Wiki and someone can just do a search in our Wiki and get that content is pretty powerful and so you can leave yourself a little reminder by going to mediawiki.org and just watching that page and then kind of trying to stay current. It's redundant, I wish there was a better way. If someone finds it out, I'm on board. Just the way we did it, we absolutely stipulated if the information was out there, we're not to repeat it. We'd only have user manuals that were specific to the way we'd use it. Doesn't mean we wouldn't have a page so we split up the user manual in terms of all the way from readers. I've never heard of lurkers before. I quite like that, I'll probably change it. Authors, owners, then we'd have advanced and then we'd have the curators and obviously you get progressively more complex as you go further down and we would have pages that would just point out to other pages and ones that we had specifically write. But what it also did is creates a syllabus so you have that page pointing out which seems a bit of a waste of space in terms but the point is you're saying you need to understand this. We're not telling you, it already exists there but you need to understand this to then move on to the next phase. Move on to the next phase. Was there a question? Sorry. No, I was just gonna comment on the training. It's pretty much exactly what you said. We actually have our training articles in our Wiki just because sometimes the Wikipedia ones are not basic enough or too complex so we kinda redo them and make them very simple so our users who are not familiar with the Wiki at all can follow it but most of the time it's our screen, it's a little bit different. Our screenshots are different so we specialize it to our Wiki and have a whole curriculum. We use the semantics so they can search, we have the keywords so they can search through it and things like that and we also use really quick videos to show them how to do things. We have a whole training course for them to come on board with that. Just on the skin point, I wanted to change it but the reason that stopped me was because all the tutorials are in vector. I didn't want to then have to recreate all of those so it means I'm stuck on that skin. I was just wondering if I don't think help pages are probably proprietary or confidential so would it be possible that as a community we could share any help pages we've created? Yeah, so if I can lead into a question. So you mentioned help pages and how do you keep up with what changes to software and things like that. How do you all keep in track of all this crazy stuff that goes on? Are you on the mailing lists? Is it once a year when you come to BMWCon? Is it Slack channels I don't know about? How do you all stay involved and stay fresh? What's IRC? Yeah, you just hang on IRC all day. What is it you do? How do you keep involved and if you can give a critique on where you want to see improvements, I'd love to hear that too. That's a totally selfish question because I'm a community liaison. The only one I do is a semantic media with a source forge but I would love to see an area where suggested channels and so on that'd be really useful. I think I'm pretty stunted because in a couple months all have been tinkering with MediaWiki for 10 years but I didn't know about this community until just a little bit more than a year ago but since then I'm trying to join any kind of forum or group or mailing list that I've found and there's just a lot. So maybe one idea would just be a collection trying to figure out where everything is. Is there an enterprise MediaWiki mailing list? Did we create one? We do? Yes, no, I'm seeing nods and sheds shaking. Okay. On Wikimedia there is one. So maybe we need to start using that. Maybe prop it up a little bit and see if we can get some adoption there and maybe would people be interested? Maybe they all should leave their name with Ginger and that way we can start the mailing list with some announcements and stuff. I don't want to opt you in. I don't want to automatically opt you in but if you're interested, talk to Ginger, get your name down in your email address. I'm putting it all on Ginger now. And I just want to say like the foundation I started a discourse instance over a year ago so and I've been trying to get MediaWiki developers to join it because it's specifically for Enterprise MediaWiki and so if there's interest in that I've got the space for it. I think that there's a tension between so they're all of these places that we've identified that the conversation goes on and so the one thing we could do is come up with a place that lists all of the different places this conversation could happen. Okay, however, another alternative would be for us to standardize on a few what are the types of communication we want to have? You know, a Q and A like discourse and there is this new discourse that was also set up for the foundation for as a test the Enterprise Hub on MediaWiki.org things could be listed there. But yeah, I would also like to see us decide what types of communication because there are different mediums of communication like Q and A, like chat, like mailing lists but rather than having a proliferation of different maybe we should try and decide which ones are really the most useful and then identify, you know, direct people there rather than having proliferation of even more. I just wanted to mention that at least in Wikimedia I've noticed a pattern where some sort of communication problem occurs and the immediate response is we need a new venue and it never works out right in the I'm not even sure how long in the like last 10 years, I don't think I've ever once seen it work. It's like the XKCD comic of there are 11 standards. Clearly this is bad. We should make a standard to unify them all. Okay, now there's 12 standards. So yeah, so I very much encourage trying to unify things like for example a lot of Enterprise MediaWiki stuff is just general MediaWiki stuff. Let's put it on the MediaWiki dash L list. Maybe some people decide Enterprise are interesting. Now like use common sense, not all the time that's appropriate but try and go to the broadest places possible until they're just too busy. I think we should use our own best practices in this. This is a wiki development. This is exactly what people face. You've got all this information and it's scattered around and yeah, we'll have another wiki or we're gonna have another distribution channel or whatever it is and the chaos just grows and we've got to find a way to converge. I've had to develop my own indexes to documentation because I rely on that on top and it's all over the place. It's all over the place and how do you establish the links? So I develop a page which is my own index to the documentation and then I've got all my hot links and I can go out and find it but it's bad. So organizationally, we're not actually converging into some sort of ordered structure. Sounds like there might be a start of a CIGA group, a special interest group within our community to maybe figure out how we create a place we can at least point to what's out there and better do better organization around that. And the search engine doesn't really work. I do want to just say, I've thought about this long and hard and I can tell you that IRC doesn't work for a communication channel for most enterprise users or businesses or whatever. But discourse works really well. I don't know if the WMF is gonna turn theirs into official anytime soon but I strongly hope they do. Anyway, between discourse, the ability to search, the ability to categorize things, the ability to filter because general list is too much information and be able to take those conversations over to a wiki which I also have and we have discrete wikis that are for different purposes so you just inevitably have to kind of put content in different buckets depending on where it should be. But that in my mind is like really the best solution. From my personal perspective and maybe I'm looking the wrong way, when I try and find information particularly on semantic media wiki, there's all these talk pages and actually it's, they need to be organized and grouped so in different areas. So when you're trying to narrow down what you're trying to work out, it just seems like a massive long conversation and you can try and find key words but trying to put those together into categories and sorting them out would make a hell of a difference. We were having this discussion earlier in the week about the documentation and really you wanna think about the documentation. Is it designed for the learning purpose? In which case it's narrative based and it tells you how to do the things or is it a fact, recall, where you say, I've gotta find the parameters for a ray map and I've gotta know all of them and I've gotta know what the allowed values are for all the parameters of the parser function and I need to see all the parser functions because I may be missing one that I need to use. So the reference index type of thing which is around with media wiki documentation, there's some good parser functions for about, well, 60% of the parser functions probably because all the extensions aren't in that list, they're somewhere else. So you look for a parser function in semantic media wiki, it's not in that, it's not in that list, it's somewhere else, you gotta go and look for it. And all of the extensions are documented slightly differently. Well that's part of what I'm saying is the more extensions you put in, the more diverse your documentation appears. Well we are getting close to time, I actually think we're a little over time, so I think at this point, I think we'll wind down and we'll thank our panel members for participating and thank you all for asking questions and listening, following along, thank you.