Monadic Parsers: Implementing a micro Parsec

okay great hi guys behind you guys yeah this is Marie Wow oh yeah that he was lecturing about Hasker on us long before love before I actually seen him so there was this unknown man of color that was somewhere beyond the horizon then I actually talked hask√≥ and actually theoretical so I know it was supposed to be talking about you know Coco Jaya and more like Jackie but since nearly every second sentence was if it’s good it’s almost like house you know I understand a very different way I recommend his talk on YouTube from the Lasky camp that was just and yeah okay okay so before I begin like how many if I just want to get an idea of the crowd so that how many of you guys are intermediate Haskell programmers or understand like fully understand good question less is it not this is how many fewer beginners that’s cool oh okay that’s good forget this talk so originally I give this talk to a more beginner friendly audience so for more experienced people this some of this stuff might be facepalm or some of the 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 okay all right so let’s get on with it so this type of them is about monadic parsers I’m aware that’s my twitter handle my day job is I work as an iOS developer at garena once again might be surprising what’s in what the hell’s an iOS developer talking about this I’ll get to that as I see surprisingly relevant okay so let’s get to it ah for those of you who don’t know what a monad is or probably first time saw saw Mona or probably wondering why is a parser a – Mona your reaction is probably something like this and it’s understandable to get to that but before we get to that we’re first going to discuss parcels or and we’re going to try to define parcel and define the problems problem that we’re trying to solve here so a long time ago and I’m gonna stop with the story a long time ago in a galaxy far far away or that Twitter wants to barse JSON data sets of rebels starships all right typical use case problem is he can’t download his favourite JSON library because internet access to those candy these days on the Death Star so he says damn it I’ll make my own so he wants to implement his own JSON parsing library from scratch and this whole thing like he thinks okay it should be quite straightforward it should be quite easy to do ah we got reg X right I mean it’s a great part you do everyone is parsed anything of some anyone who sparse like some simple user validation stuff anyone sparse like some simple stuff if it’s of these things like no complexing the CoffeeScript compiler for example these things will use reg X 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 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 reg X right this is great tool but you shouldn’t use it for parsing non regular languages and I’m not gonna go to the mathematical definition exactly a what a regular language or a non regular language exactly is but just to give you guys an intuitive idea of other regular languages you can think of it in a way that a regular language is a finite language in the sense that the permutation that Yahoo but can have is in a finite manner or just so like something like a date is a regular language but something like a programming language or something like JSON it’s not a regular it’s not a regular language I have a very small

proof here like why do you on HTML and most programming languages are not regular languages but the basic idea here is that just like this give the basic idea why it’s not why it’s not a regular language shoes but those of you who are who used like better programming environments don’t like don’t judge I’m using sublime because my Emacs setup crapped out on me so okay the can you see this okay so one like simple proof on why it’s not a regular language is any language of this form sorry I’m using this a and B n where where n is greater than equal to 0 and Busan infinite is not a regular language a where a and B are or your alphabet basically also any language of this form it is a proof behind this is not a regular language and we think about it a simple proof by case this is a J’s file JSON and you could have infinitely many brackets here right it was could 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 lamp hence the proving that this one is not a regular language simple proof right ah there’s more complex proofs more complex papers out there and 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 okay so we’re gonna help peter out of here we’re gonna help it around a bit and I’m gonna start with a simple bar so what and the way we’re gonna help Vader out first is first we’re gonna define a very simple grammar for JSON alright and it’s not gonna be an accurate grammar so here’s a very very simple grammar for JSON oh like this is actually wrong but hey it’s a it’s it’s okay that star for that suffer position so this is a JSON give me a bull a string literal and non-literal an awl or a object will give you true or false string the truck am in this stuff a number let’s say you order define what a number is not give me this an array becomes recursive an area can be JSON followed by more JSON and comma as a pair can be string the troll followed by colon followed by more JSON in there object is just 0 or more pairs right it’s a very simple grammar for JSON and I’m gonna implement an order or other I’ve already implemented parser using which I’ll show you guys which looks something like this so the basic gist of it is oh this is by the way this is a this is not using power stick or anything this is like something I developed myself and I’ll show you guys how to develop something like this is 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 parts either parse bool or bar string or parse number etc my parts bool I parts for this literal otherwise that parts for this and I’m returning stuff that belongs to this type which is basically a type of my ast this is the return type of over this parser will return to me after parsing and like the basic gist of the idea here is that this person looks a lot like the grammar I specified on this side and if you use something like parsec this will probably not at all be very impressive side note how many of you have used parsec 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 that just to prove that this thing works just gonna run it with some stuff for example so let’s do this it returns a now if we give it an array it returns this thing our bear in mind this grammar is faulty because it doesn’t deal with floating points but that’s okay I think that starters in inflowing points for now so given that sort of thing this we just go through like how we came up with that sort of simple parsing libraries and build from scratch and and the way we’re going to go there is you’re first gonna define what a parser is so in simple

word instead of if you think what is simply a parser is just a function that takes a string and don’t use something of type a which is your return type or the value you want from that parser and the remaining string so it’s gonna return to you a couple of these two things are very simple by then I think that’s a very simple thing about a parser like what would do right and that’s it ah however the there’s a problem is definition and that problem is that one I may not be able to successfully parse everything from from a string so let’s say I give an invalid input in which case I can’t find anything my first definition can encapsulate that in the type system right 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 type system instead what I’ll do is I’ll return a list of tuples of type a and top typing and strings so I can have multiple results and using this clever technique basically my empty wrist list would mean that my parser failed and if I multiple that means I have like it’s ambiguous grammar and I have multiple results after parsing okay so we’re gonna do here is we’re gonna define a new type called parser this and this takes generate 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 and capturing this encapsulate in 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 that’s it we’re done defining a parser so what can we do with it yeah as I mention about the poor case okay so let’s define our using this type definition let’s define our first parser and let’s what the parser is gonna do is it’s gonna consume the first character in a given an interview list of input can return just that character okay so it’ll consume by consume I mean that ill it’ll in the remaining string it’ll give you everything but that first character and the value it returns is gonna be the first character so and here’s how implement it’s quite simple it’s just its type is a parser of type car because there’s a return type of car and it’s just and here’s a parsing function it just does a case could case this is a pattern a pattern match with the string if the string is empty empty list because and remember empty this is failure so it means if you give it an empty let empty string this parser would fail otherwise it’ll just return to you the first element of that list first first corrector of the string so quite a simple parser that’s quite useless too let’s see what more we can do with it also wanna if I just want to apply this parser on some input I’ll just unwrap the parsing function and a planner in a string like this I can define a parse function to unwrap my parsley function and apply it so quite straightforward okay so ah now here’s where the fun stuff begins in isolation this is not very interesting but let’s see we want the ability to bind two parsers together and what I mean by that is Ramona I want oh what is that oh okay all right okay so let’s say I want the ability to bind do parsers together so I want to chain the parser such that the result of my first parser is fed into a function that takes the 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 like how would I or how let’s let’s say I let’s say I have this need and the way I implemented it is and if you’re the type definition of bind it’s gonna is gonna take a parser it’s gonna 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 or so we basically created previously create a parser this parsing function remember we return to you a parser of type B as the type definition says so this is this party will return to be something of type B and this function will take your string what it does is it first applies the

first parser parser P our first parser it will apply that parser on the original string then it will it and this thing will give you a result of applying so this thing will be a result this thing will be a list of a and string right they’ll give you a list of a and list of and and your remaining string the next thing what I’m gonna do is I’m gonna apply masses to a map and a and parse visible my function f remember this is the function f this function returns to me a new parser after I give it to mentor sorry guys okay this function gives me a new parser after I give it so give it some input of type a right so I will apply that new parser I get fit the remainings with the remaining string I got from from the blank the first parser so I and this and this stuff will basically give me a list of type B and string right because I’m applying the second parser and and the second parser is result type is this so I get a list of in a list of a and B of B and also you know B and string and then I just flatten the result out to get this nice result so that’s what buying is doing and in isolation it might not seem very useful for why I’m doing this but we’ll get predictive how this is useful one more thing you need to bear in mind here is how the failure is just handled so if at any step so let’s say my first parser fails that my first parser fails the list I pass through the map is gonna be an empty list right and if you apply a map on an empty list is you’re still gonna get an empty list so my empty list is getting a propagated throughout so in case my parser B fails to consume anything and gives me nothing the whole thing will end up being an empty list which is fine which means and I’m I’m passing the failure case throughout yeah so the bank robbery is a flip composition good point out I prefer I professionally I prefer training or composing operate function using this operator because it shows you the steps in order yeah correct okay thanks thank you that I define this myself usually so but thanks oh yeah okay so so far so good yeah as I said in case of failure empty lists propagate it down which is great so I define bind and now I did now I’ll define another function called unit and what unit will do is you will take any value and it’ll just produce a parser from that value that consumes nothing and this returns that value and this may seem useful but it’s actually useful to make it 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 in putting it inside the parser that parser type which I mean and it’s in the implementation we look at it’s quite simple it’s just it just takes something type a and just return to you a parsing function just just return some that’s something of type 8 in a let in a list and the same string so does it it doesn’t actually consume anything and that’s it so using these two functions right or we can actually do a bunch of interesting things and some of you who aren’t familiar or haven’t figure out what I’m going towards or why am I talking about we doing this right now which is just a justifiable so which begins the next part parser dominators which is really barely gonna apply this concept so let’s diff with parts of Combinator’s or gonna try doing is we’re gonna track combining simple parses together to form more complex parsers using pine and unit as our two fundamental operations and let’s define the first computer that we’re gonna implement it’s called satisfies and satisfies we’ll just take a predicate and it will return a parser that will consume the first character if that predicate succeeds it will fail otherwise and the way we’re gonna implement this using our nice by non unit is just like this right it satisfies it takes a predicate function and we bind it to item which we defined previously so I think we’ll take your first character from your string which VME defined this earlier since the return type of item is a character in my binding function over here this C this type of the type of C is gonna be a car it’s gonna be a car it’s gonna be a character I apply I apply the predicate on character so if this predicate succeeds then I will return units SI unit c as we defined earlier this term

is just gonna return to you a parser that does nothing but contains returns this value right otherwise we you fail so this is just a failure case of parser there’s a parser that just returns an empty list for any given input so what this thing is doing is simply you it’ll consume first character in loop and it’ll check into predicate if the predicate succeeds it will carry on parsing so and here’s where we entered the monette oh and here’s where things get interesting so and it turns out buying an unit surprise surprise or some are common abstractions we have in haskell and if you look at the type definition of of bind or so in in the Haskell type Mona type pass we have two functions right and if you do it as long as you implement these two functions you are technically a monnet right big and that’s how I Brothers work I mean there are taught there’s obviously more that rules but we’re not going to get into that but what I want you to look at is in these two in these two functions that were supposed to implement to be called a monad if just look at their type definitions and compare them to the tire definition of buying and unit that we defined earlier say we let a return just swap a with parser this swaps a just swap em with parser and it’s the same thing right similarly for this funny arrow operator that is called bind if you just swap em with parser we get the same thing as we’ve already implemented and bind right so turns out this sort of this sort of operations or combine doing this one higher-order operations is quite a common thing and has an aspir the type class for Mona to encapsulate or 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 if you’re from the object or if you’re from not you’re probably in pit world wait a second let me just close slack winglet supposing this sorry sorry guys okay if you if you’re from an object-oriented world if you think your tag class as sort of like a protocol that or a constraint on your type and as long as you implement these two these two as long as implement the functions that you’re supposed to or you will be someone implementing that protocol if you want to think of it as an object in an object-oriented way so simplement ation of so do you implement parser and make it a mona it’s quite simple we just make return equal to unit which will work and this funny-looking operator is equal to bun and we’re down here so our parser is now omona quite simply which means that instead of using pi in the unit we can just use these two functions hooray we’ve done a lot and some and once again like this is nothing special by itself right so here’s where the fun part comes you know here’s why the University at one edge of making it a monad comes in really uh 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 do you continue on end times and then you probably have some function review where you a function where you construct some semantic value using the results of the parsing that you did earlier right 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 some tasks Oh has nice syntactic sugar for this so I mean we can add some new syntax and in the but the new syntax does is it’s quite simple just flip the operations so instead of a one so basically what this is what this says is that it’ll bind in the apply parts of p1 and bind it to this value a 1 so basically just in your mind in this think of it as effective sugar and you just flip this around you don’t need that arrow arrow arrow anymore it’s just some nice and active sugar to write the same thing but the flow off your parser becomes quite clear because of this so I applied parser one I get this while you apply parser to get this value that I apply my semantic action same thing but the syntactic sugar makes writing parsers a lot simpler and that’s all that’s doing so just to clarify this a bit I’m going to define a new parser this sponsor will take three characters and throw the second character and just return to us a couple of the other two

characters the first in the third director so this is define this parser and we’re first gonna define it using our binding 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 this to me them feel this feel and propagate phineus right and I get my first character of the string out from it so and this and I bind it to this function then I apply another bind where I apply item again and get the second character out I applied a third time get a pair director out and finally because this in this in this parser I want to return a parser of type car car I will just apply unit operation you can work my result or do or to wrap my result in a parser time and and I wrap it with the first Network character ignoring my second second character so that’s how it will write write the simple parser using my 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 to swap bind with this funny operator and just ignore we don’t we don’t care about second so just don’t do any boolean lastly you can write write it like this we do syntax so we take the first guy first character out apply it to be apply item again is the third director out hola simple right just apply new syntax to write our second part through second parts of so that done we can use this sort of thing to define more Combinator’s and write me and use those to construct a more powerful parser for some to parse something capable of parsing JSON for example so we’re going to define a new parts new Combinator it’s called M plus alright 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 from the two parts of circular the implementation all it’s doing is it’s concatenating the list of results we get from a blank parser B and applying parser Q so it’s nothing short of just concatenate in the two results in a sense adding or plussing 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 parts with you because once again if either of my parser fails it’s an empty list right so NFI it 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 aural sort of like 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 is this particular operator is useful is because it says give me results from P exclusively or Q exclusively so which is what use which is quite useful in a part if you think about it if you’re doing if you’re making parser in your and you want to have and you wanna branch out and your different branches in your pasta then this sort of operator is quite useful so once again what this will so even though M plus will actually parse apply both P and Q if P fail if P fails and Q has result you as a result you still get the cubistic excuse result but the skews result will be the first element of this list if P fair P succeeds you fails same logic if they both fail we get an emptiness so that’s how option works what’s simple right similarly let’s define an operator that just takes a car and this will consume it will basically continue parsing if it sees that character otherwise it will fail and we just used we just use our satisfies operator we defined earlier and we just apply the satisfied operator with equal width with this with this predicate function so so we have now we now have a function that we can we can use to parce partial particularly the trocar similarly if you want to take a stray you want to parse a particularly trip literal string we can define a new parser something something like this which when parsing an empty list will return an empty list with a return meaning it will return to your parser with this emptiness otherwise otherwise what it will do is it will use the car parts that we defined earlier it will apply the car and then it will recursively call string this this this parser again on there on the other on

the remaining part of the string right so in the base so at the end of it when the when we have the last character will this will get this case and which will return to as an empty empty string so on the whole this whole thing will return to you the string itself that you know that you were checking against so the nice thing over here to note is we can define parses recursively which is quite powerful similarly we’re gonna define two more parsers called many and many one so what many will do as many will apply a parser p0 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 ok many P is basically many one P so apply part should be at least one at least once or more times or return an empty list which is bear in mind this is not failure this is just this is just a parser with data 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 menu was applied 0 times which is fine for us many one on the other hand what it does is it will apply parser P first it will take the result in a then will apply many and put the result in a in ears and just there is return the result by a biker captained by making this a list of the two stuff that of the two things if you got so basic point here is we can define this parser which in a nice mutually recursive manner and these parts suits are pretty powerful because they allow us to apply a parser more than once so I like when I and when I read this in the paper so this is a lot of this most of this stuff is not mine mention 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 a link to the thing but when I came across this in the paper I might this was literally my reaction because I realized ok this sexy quite simple the bill meant this anyways so let’s so lastly let’s say I want to parse write a parser for a simple language that basically is composed of mathematical expressions like this like 7 plus 5 or this sort expression right let’s say I want to write a simple parcel that parses this kind of stuff from scratch how would I get around doing it I’ll show you that so like the way how so the way I would get on doing it is we will first define some simple parcels and let’s define the grammar for this sort of this for this kind of language first thing we’re gonna define is something that can parse white space for us because white space is quite annoying this 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 is just a parcel with return type string and it’ll just consume many instances of this predicate is space and I define in space simply as something that is something they’ll take a space a newline character or tag character otherwise it always return false so basically zero or more applications of this space or satisfy the space will return will basically be your space space parser which is great next thing I’m going to define are my tokens for this particular grammar in this case a token I define it so I define a token as a part as a parser that takes another parser and applies and basically parses the space around that around that around that thing and this returned to me something that something before a space right that’s a token in this simple language so in this particular case I apply my partial 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 of way and I return to you this thing interesting 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 sparser for a symbol and a symbol all it does is it’s a token with this string the two parts that parses this string similarly I can define a parser for digit and a digit is just something that applies Haskell’s is digit function feeling here a bit and a number is just one or more digits and and I just apply use Haskell’s weak function to parse this because did this digit returns to me a character if you

know this so I just use Haskell’s and this thing will return to me an array of cards in a string so use Haskell three to convert that into an int so this this number will parse 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 this that takes another operator it’s a binary operator in int and returns int and a multiplication operation same actual nature and the way this parser is implemented is I have this operator I will get to the implementation this operator soon but basically anything in my expression give me a term or it can mean add operation a term is a factor for followed by multiple 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 return so if you think about it it looks a lot this this code looks a lot like the grammar that you actually would write for this kind of language right and if I might add operation simply as something can something that can be either surrounded by a plus or starts around by a minus and my mother occasional operation is either a multiplication or division and the reason I deal with them do these two things separately is because I want to follow the precedence rules that multiplication is applied first an addition is applied later on what happens in this operator is well I’ll just show you guys the source code for this sorry I’ll show you that it’s sure doing a bit ah here we are so in my chain l1 operator all I’m doing is I take a parser of type aid I think another parser that takes a function that map that takes two things a type a and returns to you a phenotype a so it’s basically as a binary operator if some in our case this will be plus minus multiplication division and we’ll return to you something of as a parser 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 a intuitive idea of how it works it’s just parsing stuff that is around my operator so with these two with this 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 so there we go that’s how it works complex thing there so you can see like this sort of grammar it can parse the sort of grammar quite easily and that’s that’s all the Monaco that you have to write from demanding this kind of simple parser right and that’s so that’s it for partial combinators now for those of you wondering well for those of you write parser is like this is not obviously the only way to parse things we have parser generators which are you can say more with which and the way those works are what is quite is quite different you provide them a grammar and they will generate a parser implementation for you and Haskell has a parser generators 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 make him be used to make a pretty powerful powerful parsers at the end of the day side note parsec is in the way parsec works is pretty similar to the implementation of the simple parts a permanent library you guys are here parsec works similarly but it’s a lot more it is 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 so it’s really powerful and that’s more or less yeah that that’s that’s actually it lastly like 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 in our at work we faced this problem where we needed to generate Objective C classes and from parsing protobuf product buff specification files so we needed to write a parser for profiles and I wrote this I wrote a parser front of proto thoughts using 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 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 fighting kind of relevant in a way yeah that’s the end any questions example need anything so why would you I think and they will the expression parser and the json parser you can see if you good that they only use the pickety structure off of your bar is there yes so why would in these kids okay i guess my real point is it needs to be a conscious choice to go with melodic parsing is that an applicative one that’s because of course if you make an applicative parser you can exploit all that static knowledge that you get there to make much more performant implementation of applying it right because you can compute like starting sands like which are the characters which can possibly be accepted as first so so don’t jump into monadic parsing just because parsec is one that’s the point of needs to be a conscious decision if you really need more addict power or if applicant it is enough that’s very good poetry and and a good example of this actually is there’s a apricot a regular expression parser library enacted which allows you to parse regular languages that we need to work for your examples but if you want me to portray other languages in the same you’re saying objective interface so you don’t get you know some string it’s not like you know but in most programming languages that you apply reg ex or something either get like a single bit of either it match or you get you know like a dictionary of what are they called these captured values right but but we duplicate the regular expression parsers you can you can have some kind of structure inside your forester so just like how your parser doesn’t return a tree you right it just does something while it builds up that three implicit the same can be done with regular expressions and what you get is something which you know which parses in linear time like you would expect of a regular expression quarter but still allows you to do meaningful component combinations or meaningful composition of subpar Surrency actually the reason why this thing uses monads is actually the reverse the tutorial I wrote the paper I read was more of how to apply monads in a particular problem domain so how do how we can apply monads in parsers so the reason why monads came into this is more of example this is how you use a monad so that’s that’s the main reason not the only reason actually for why one has a broad into this in the first place it’s not a I agree Astana is from like to use for my usability point of you have to get it makes more sense I think right but this one is more of a kind of a more editorial ish thing so it’s like oh if you can use monads to build parts together and that’s okay that’s what monads are the example that we use maps for that all the Combinator is you use only used to get a structure I need ice cream okay because that we saw here didn’t

take care of that that’s true in the language then becomes context right if some hand we prove that you’re not going to be able to for instead giving efficacy for using a finite acidity forager simply because the camera is I mean at this point I which I’m actually passes how many chase libraries out there well actually if you pass air all it’ll be kept here not just a second