Coding in Go while Google is Spying on Me

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
looks like we're live hello everyone and welcome to yet another Asus installation let's make a little bit of an announcement and officially start at the stream hello hello everyone welcome welcome welcome I'm really glad to see you all today so let's do the usual red circle and say live on Twitch and what are we doing today on Twitch dot at television so today we are coding and go uh while Google is spying on us in that case I suppose uh right so let me give the link to 3D TV starting uh right and I'm gonna ping also everyone who's interested in being Pink There we go the stream has officially started and today we are developing something unusual something that I don't usually develop on the streams but I need to do the the chores so I decided to stream that anyway so today we're developing GateKeeper right gatekeeper is the chatbot that sitting in the twitch chat and also Discord chat and answers the commands and some stuff like that right so there is a there's a special command in here uh literally called gatekeeper right so as you can see somebody will reuse it and uh basically it's the chatbot that answers that specific command so that's what it is uh right so and the you can find the source code in here if you're interested I'm going to copy paste it in the chat of course and uh also for people who watch on YouTube I'm gonna also post uh put that in the description and today's topic today the feature that I want to implement today is actually related to the commands let's take a look at how we uh handle commands within the bot right so let's actually go to GateKeeper all right and I have two executables within the chatbot actually right I have two executables uh the first executable is called gatekeeper it's the main boat a boat it's the main process that connects to Twitch and Discord and listens to your messages and then responds back uh and there is also gaslighter right so on top of uh connecting to like different services like twitch or Discord uh gatekeeper also connects to the database it uses the uh postgres database it stores all the data there right so and essentially if I want to modify something within a database but I don't want uh to use a postgresql directly I have a special command line too right that has predefined commands of usual things that I want to do right and it basically connects to the database directly by passing the bot and modifies the database and adjust the exits like it's a command line tool for configuring the boat right so the bot itself is called gatekeeper the command line for configuring the bot in connection to the database by passing the bot is called Gaslight cool right so we handle commands within the gatekeeper right so we're not going to do anything with gaslighter right now maybe a little bit later we'll see uh so we've got some stuff uh from enumer 8 underscore thank you for 100 bits for the message twitch isn't letting me subscribe no matter what so we'll just cheer beats until I can have membership of all your epic clubs that's kind of weird right so uh let me know what if you want to have an access to Discord like just let me know your unique name and I'm gonna trust you manually if that's what you what you need um oh yeah and the chat says we also need to have a girl boister at some point yeah I don't know what it's going to be what's going to be the girl poster right if the gatekeeper is the bot itself and the gas slider is the configuration tool what is it uh girl buzzer um a library maybe maybe it should be Library yeah so and as you can see um go where reason go right and isn't go in 2023 is unethical but not really I don't know right it's just like depends on the opinion uh right because everyone is outraged how Google is planning to add Telemetry to go right so they literally plan to add telemage to the language like if you Google the dev to go Telemetry uh right so this is like a you know hotly debated topic uh and uh so we yeah we can't really find anything about that so can I do go Lang Telemetry GitHub can we find the open time to go a okay so Telemetry and go to chain yeah this one right so essentially and justification is so weak right I'm not really sure like it's gonna go through right so but I actually strongly oppose this kind of thing right so I really against Telemetry to be fair but that's like a topic for another time so I can talk about that for for like an entire stream but yeah so and I do plan eventually to rewrite my project in something else right but since it takes uh time and effort I just don't do that right and here's an interesting thing I'm pretty sure the reason why they decided to even suggest it right now is because they know that everyone already depends on go and nobody is going to rewrite their huge projects in anything else and so those everyone just gonna suck it up they know that they calculated the precise time when to start slowly pushing that because they know you can't do about that it's just like that's such a Google thing it's just like oh my God uh anyway so but by the way um you may say there's not that many alternative to go uh maybe for you but I have a pretty cool alternative to go I have an access to jai Bata and usually I don't like to write my project projects enjoy better because I don't like to um I don't like the fact that I can't share the code because other people can't uh run the code on their machine but this project it doesn't really meant to run on your machine it's meant to run on my machine it's my project it and there is a lot of like hard-coded things specifically for my channel you literally can't reuse this bot for your channel unfortunately I'm sorry I just like don't have time to make a general purpose build I'm making like a very specialized bot for my channel and it has a lot of things that are literally hard coded for my channel because it's just easier for me so I'm doing that only for myself not because I'm an I am an but I'm doing that not because of that right I'm doing that because it's just like doesn't take too much resources right so um so making a general purpose boat is not my goal right and Jai seems to be like a perfect language for this right I don't need to make sure that it works on other people's machine I do it for myself and I yes it's just like perfect and Jay is very good alternative to go like it implements a lot of things from go as well right so but that's the topic for another time that's a topic for another time uh okay so I'm gonna put that in the description as well all right so just for the people who are watching on YouTube uh potentially right so because I think I want the software development community be aware of that right so everyone can make their own decision whether they want to be spied by Google or they don't want to be spiked on Google you're going to be spied by Google Anyway by the way because you're using Chrome chromium but I mean do we want to give Google even more power than it already has I don't know maybe do we have Choice maybe not anyways so um yeah we'll get another slip we'll get another sub thank you so much uh disappears one two three thank you thank you thank you um and two to just a second I need to double check some stuff um [Music] all right okay so and speaking of uh hard coding things right speaking of hard coding things uh that's precisely what I want to work on today right if we go to the gatekeeper thank you and we go to the module that handles specifically commands right so there is a function that evaluates the commands there we go right so eval Command right it accepts the connection to the database of course because it recommends May uh wanna modify the database it accepts the definition of the command the command is usually like a structure or something like that right so it is a structure which is basically a name and arguments right an argument you can only have one argument right now it's just like a string that you put after the command right so that's a very simple thing to name an argument and a command environment this one is a little bit more interesting because it's an interface right it's an interface so let's take a look at this thing uh it's an interface with several methods Right add admin at author is outer admin as Discord environment and send message so essentially the purpose of this thing is to describe an environment within which the command is running and right now we have only two environments within which the command can be can run to which environment and Discord environment right so when essentially if you call send message it will send message to the environment where the command was issued right so the command itself doesn't really care much about the environment it's running in right so if if it wants to just send a response it doesn't need to know where it's sent in the response right it whether it's twitch with its Discord it doesn't care you just want to send it and that's what it is it just abstracts that away and add admin basically an ad author also depending on the environment is going to return different thing because on different environments onto which you add people one way on Discord you add people the other way right and because of the difference in the environment it's also abstracted away and at our admin is needed in case of for example an error has happened and I need to Ping the admin so to check logs or something like that so this is how it's usually used I think and we can even check it out yeah so for example if an error has happened I just say something went wrong with the database commands that require it won't work please ask at admin to check the logs right so it is needed to send this kind of messages in case something failed right so um and uh here when we handle the command we have a huge switch case speaking of hard coding things right so for instance for I just had coded two commands for two different projects that I'm working on write that which is the text editor dramatic text editor that we worked on on the previous stream right and also for the gatekeeper I just added it right here and it's literally hardcoded in the code it is literally hardcoded in a code and like different commands may do different things and stuff like that so what I want to do I wanna unheard code that right I just want to add code like every time I want to add a new command that describes one of my projects I don't want to go and modify the goddamn source code right I don't want to go and modify the source code so essentially what I can do I can just create a new table in a database where it's going to be command and two columns like a name of the command and a response right so and instead of like doing this I would just like a query okay the user send these commands tell me the response for this command and I just grab it from a database and I just put it there and every time I want to add a new command I will just modify the database and don't have to even restart the boat don't even have to recompile anything it will just work right but here realize the problem it works well for the commands that just respond with the text right so essentially because you have a mapping name of the command text response like a static text response name of the command static text response but what but that means that my all of my commands all of a sudden split into two different categories the custom commands static custom commands that are in the database and dynamic commands that are built in for example I have commands that check the weather right and to check the weather I literally have to make an HTTP query all right so and that cannot be stored in a database right so that like effectively splits all of your commands into two categories static commands and dynamic commands and you cannot have you cannot store Dynamic commands commands in a database and that's a huge problem right so the way it's usually solved it's usually solved in Dynamic languages right so if you're writing your boat in something like JavaScript uh right so essentially what you can do instead of storing the text of the response of the command you literally store the JavaScript that you can evaluate and as far as no supinic does like that right for his board so essentially in his database he has like mapping of the name of the command and literally JavaScript that is evaluated every time you run this command and that is very flexible and that works but at the same time it's just like a little bit scary at least for me right because you like literally have the whole power of the JavaScript and what if that specific JavaScript is gonna do something that it's not supposed to do in a like a global environment or something like that right so that's kind of a little bit scary but I mean Sylvania is a professional JavaScript developer he probably knows what he's doing maybe in JavaScript there's something like that something that actually like sort of sandbox the environment and stuff like that but I'm not a professional JavaScript developer and I'm also not using uh JavaScript right so what kind of solution um can fit our case where we're using statically typed compiled language but also want to have this Dynamic um you know benefits there's Dynamic benefits of actually storing this script uh in the in the database we can use the secondary scription language actually something like Lua right something like Lua where like we store the Lua quote in the database and then we evaluate this uh this entire thing but Lua is like a huge separate dependency right so we don't really need the entire lure uh just to you know just evaluate some commands and even like compose some effects of the bot um and here comes the uh solution um in chess is huge I mean it's a relatively huge it's a relatively uh huge to the problem I'm trying to solve right so everything is relative I thought about this problem for quite some time right and uh some time ago I came up with plausible solution basically make your own simple scripting language right I can and then you can say oh making your languages so hard blah blah blah but no no no no no no so if you analyze precisely what do you need right and Implement exactly what you need it's not going to be that hard and it's not going to be that big and it's going to be smaller than lower right so the scripting language I came up with I actually streamed the development of that language I think it's located on gitlab somewhere GitHub sorry Yeah so basically the main specific language it already exists I already made it in goal by the way uh it's called Bix what this stands for it's a it's like oh it's about expression here what it cool two picks uh right so let me give you the link to the to the source code of text is wrong with me when I developed that I developed it like yeah I developed it a year ago right so it was a year ago a year ago I was actually thinking uh how to how to solve this uh this kind of stuff all right decks so and this is the both expression and the language consists of only four things only four things strings integers variables and function calls that's it that's literally that's the entire language you want to see the size of the language like how how much code do you need to write to implement this language so let's actually go down uh 433 lines of code and the thing is essentially what you do right you can write these kind of Expressions right you can write this kind of expressions and then in the environment in the scope of the evaluation of that language you can bind your own custom variables and your own custom functions and when you call this all in custom functions they will call the go functions right so you basically provide a table like here is the name and here's what this function does and a while while evaluating the script it will literally call that function and essentially if you have uh commands that performs some side effects you can basically put all of these side effects into separate functions for instance uh you can Define function say which accepts a string and every time this function is evaluated the bot will say something say that text within the environment right it will say that text within the environment so for example we have a command weather which I need to perform HTTP query to get the weather and then it prints that weather right so to get HTTP query you can create literally create a separate command called HTTP right and for instance you want to Now define a weather command how would you define a weather command well you define it as an expression that takes HTTP query of so let's actually find the check weather off uh right check whether off something like that uh right this then uh you would provide the location of the weather through the argument so you would put ARG in here and then you would also add this thing in here right and this command or this function will perform uh the HTTP query and just return as a result the the text that was written by this thing so this thing needs to be URL Escape let's also have a separate function URL Escape uh right which basically just URL escapes this desktop URL Escape right and then what you want to do you want to say to the user uh whatever we got from from this entire thing so we will do say HTTP but we also want to add the user the the author of the message so we can say something like add author uh right and maybe we we're going to separate all of that with the space uh like so all right and this is a single string this is a single string that we can save in a database right so we can have a name a table name and then uh Behavior behavior and this is what we can store in the databases so and every time you like issue a by the command right every time you issue a weather command within a query uh these specific behavior and we're going to evaluate it within an interpreter uh right and for these kind of functions it will go back to go code which will perform HTTP queries URL encoding and then saying it and then it will just behave as this description right so as you can see for these kind of simple things you don't need an entire lure you just like I need a simple expression language and then we can say basic building we can take all the building blocks of the bot Behavior like uh send a message making HTTP query maybe extracting something from a database and we can expose that to the admins of the bot to basically compose different commands so we basically instead of having commands we have building blocks out of which you can build your own commands right so does this make sense uh does Bex have Telemetry yes it it does have Telemetry I'm joking it doesn't and all of that uh this entire thing is in fact like only requires you to add 400 lines of code right so it only requires you to wait forehand in lines of code and 33. as far as you know the huge part of it is an example right that demonstrates how to use all of that in reality I think the language itself is actually 231 lines of code right so because the rest of it is just like a main function that just demonstrate how to use the synthetic thing so in here we have eval expression which just recursively evaluates the synthetic and here is just like a scope management right so this is some sort of a scope management I wrote it like a long time ago but I don't remember everything so here we can parse the expression and this is I suppose the expression parcel it's it's very simple it doesn't support string escaping but it's really easy to add in future all right and uh yeah so this is the the definition of the structures and stuff like that so that's the entire language it's not cool so you you get the like advantage of skirting language uh for Just Two Handed lines of code it's that simple it's probably not super fast in a sense that every time you execute the command you parse the command pause the the source code and then evaluate it and the evaluator is not even like uh it compiles to a virtual machine it's literally just traverses the AST and overlays that but for simple things I think it's actually sufficient enough in case you're the memory yeah maybe it would be kind of cool to even like invent a virtual machine for this entire thing and compile this stuff to bytecode and actually store the byte code in a database so every time you query the command you don't parse that what you got from the database you just start evaluating byte code directly without parsing right and maybe so if your boat is like working with millions of users we can jit compile this command to native code that's actually very cool that's a very interesting project like compile like a jit compiler for Dex jute compiler for decks right so it takes the byte code for its virtual machine and Maps it to the actual native instructions and every time you execute the code you jump to this sequence of native instructions it yeah it does sound like over engineering and we're probably not going to do it today or probably in the near future but if I was developing like a production bot like a heavy load production bot and I want you to implement feature like that for that heavy load production bot with like millions of users and millions of requests like per second or something like that that would have been an interesting project to work on right imagine you need to have that but like on a high load right and what you essentially do you implement like an in-memory compiler for your commands it's such an interesting project to work on but it's of course we're not going to do that but probably in the near future but just like you know have that at the back of the head I think it's kind of cool still right so what I'm saying all of that is that this is a very dumb solution but then if you need to like scale it in terms of performance it scales also some somewhere in some place theoretically right probably hopefully not in a bad place uh I don't know so isn't that progress maduds all right so we've got some uh sub made yourself 777 thank you so much for tier one subscription with a message at sodium a goal again I almost said go for as far as I can remember this mode is called sodium gun yeah uh so and apocryphos thank you so much for tier one subscription with the message pew pew right just a friendly reminder that you can actually put anything in the message of your resub right including questions and even programming questions and since you put some money into a question uh I will have like a moral obligation to at least answer something to you I won't be able to dismiss your question or pretend like I ignored you right about like I didn't notice you right so if you put something there I sort of like morally forced to answer something to you even though I don't get money I just feel bad if I don't acknowledge the uh like the people who have good intentions and trying to give me money can you use it as a debugger uh the debugging what debugger of what debugger of its own Scripts I don't think so I think to debug this kind of scripts we probably need to create a separate tool but since the scripts script is so simple the debugging tool is probably gonna also super simple so I didn't think and you think it's necessary can I use you as a debugger oh my God I'm sorry I I can't read no you can't use me as a debunker but I mean if you if you ask a debugging question in the in the subscription we'll see all right so uh let's go let's actually take a take a look at the at this thing right so let's try to run it on my machine um because I haven't run it for quite some time so maybe I do have it still somewhere here so bags do I have backs in here I do have back so would you look at that uh right so can I um just You Know download everything so oh yeah I've made some changes right turn oh yeah I do remember that turn backs into a scap scheme yeah I remember that what I did I actually implemented like a lot of different built-in functions that's probably why the main uh thing is so huge right so you have place you have the let uh I implemented Colette and uh so what what did we do in Let's uh performance Define which defines new function by the way who said that you can't Define a function that while executes adds another function to the scope of the script so you can have a function that defines other functions you can do that so you can you have lists you have four like I defined all these things and this is what I came up with so uh yeah a function hello uh the arguments of the function are named any city right and then when you execute this function we say hello name from City and then we query the weather we query where they're in your place in your city and we tell you that here is your weather in blah blah blah right and then this is this is not part of The Language by the way this is what you can do with this language you can Define all of these constructions as separate functions right but here is an interesting thing so like how can you do a Define doesn't that mean that all of this thing is going to be executed before this function is going to be defined not really so the way the backs is executed and this is a feature of the of the bags itself it's all called by value right do you guys know what is a call by value cool by not the way but by name it's a call by name I'm sorry it's it's like a computer science term right that uh yeah it's a one of the evaluation strategies right it's one of the evaluation strategies so uh the idea is basically right the idea is basically that when you call a function like f and you do something like uh one plus two one plus two is not evaluated one plus two is not evaluated it's passed as a expression an evaluated expression inside of f right it's sort of like it's lazy in a husky sense lazy so essentially uh we start evaluating at the outermost function so this function evaluates first and it gets all of its arguments as unevaluated expressions and then within the implementation of the function the function itself decides whether it wants to evaluate functions or doesn't want to evaluate functions and that way it can actually like work as a defined construction because it's not going to evaluate all of these things it's just going to save them right so essentially here hello it probably evaluates at least two arguments right but then it just takes whatever it has afterwards and just like adds all of that as a new function in the school for something like that right and this is very useful this is very useful for example you can define a function something like uh subbed right for instance like you have a command with this specific expression right with this specific expression and sub takes its own uh argument doesn't evaluate that argument but the first thing it does it checks whether you subbed or not and if you subbed only then it will evaluate the inner thing and if you not subbed it will tell you no this feature is only for some people right right it all may be only modes right so this is a similar thing so this is why uh this is why uh we call by name right this is why we do not evaluate the arguments we just pass them at this so the implementation of the function can it decide itself whether it wants to evaluate these things or not right because it allows to create this kind of guards and check different things and stuff like that I think it's rather useful right so for this specific language for this specific language this is an advantage of using your own language for this kind of stuff by the way because you can decide how it behaves right if you go with lure you're stuck with whatever Lua like offers you and you can't change that unless you start modifying lure but now you're actually you know maintaining lower right so you can develop a language precisely for your use case so the arguments are strings all the time no they are AST notes there you literally pass them as a is to nodes uh all right so for instance let me see how um HTTP is defined right so HTTP is defined as so right so when HTTP command is executed we actually call this go function right which accepts evaluation context right and uh it also gets the uh array of the arguments of the expressions and as you can see all of the arguments they are expressions and expression we can take a look at what is an expression uh it's a structure it's an AST so you can check its type right so it's either integer string variable function called we also have void for whatever reason and depending on what it is you can actually cast it to either integer string or something like that right so and essentially um right so what we do we iterate like specifically for HTTP command HTTP comments needs to evaluate its arguments so what it does it iterates through the arguments and it asks the context to evaluate each individual argument so you see the function itself made a conscious decision okay I want this argument to be evaluated right so and that's how it works for example in something like Define uh right to maybe four and maybe not four uh where is defined right so here we accept arguments but the first thing we do in here we check the length of the arguments without even evaluating them right we don't even evaluate the arguments they're just a list of uh of trees for us right and uh we're only going to evaluate things that are needed to be evaluated depending on what function does right if for example I want to introduce an if construction if construction is going to be something like condition then and else right so and essentially if is going to evaluate condition up front but it's not going to evaluate then or else then it's going to check and then if the condition is true it's going to evaluate then and if it's false it's going to evaluate else right so you see what I mean so that's precisely why it is called by name right so the functions themselves decide what kind of construction they act as right so that gives you more flexibility and still this language is two handed lines of code right that's the cool part of it like you you can do all this like cool and it's two-handed lines of code and to be fair it's a very specialized language it is a very specialized language it's only good as a language that describes the behavior of the bot commands right and honestly I do not recommend to write in this language like that I do not recommend I just this was just a demo which you can do with this language but generally what you could do you would identify the building blocks of the behavior of your Bot like sending HTTP query saying something in the chat doing like making a specific at which API call and you just expose them as these building blocks as functions and then you can build command out of these blocks right so if you try to turn it into real programming language I feel like you're already doing something wrong right if you turn it into your into real programming language you probably need a real programming language the whole point of this thing is that it's not a real programming language it's just like a composition of predefined components it's a it's a glue code for predefined couples does it make sense makes sense let's go ahead and try to maybe run this thing uh right so the the problem with this thing is that it's not um how to say that a separate package but this thing that I think is so small that I feel like it there's no point in spending any effort uh on making a separate package to be fair like why uh what's the point okay so here we read LOL backs then we parsed all of the Expressions right we parcel with expressions and then we evaluate all of the Expressions so one of the things we can do let's actually try to recompile this entire thing so I'm gonna do uh go build Dot oh yeah it was actually developed with such an old goal that it didn't use the go mod thing here I think you can easily bypass that if you just provide the uh the file name right uh my goal was so old it didn't even spy on me to Google right if I try to do something like Bex uh right a known function mode a known function mode um it doesn't know about function mode right so this program tried to call the mod and I don't see how I just added that thing in there so you remember how it was like um confabulating functions like possible functions that you can Define I just added it there and the the environment told me that this thing does not exist right so there we go it worked you see you saw how it actually paused for a second this is because it literally was making a HTTP query right it's literally making an HTTP query all right so it worked it's just it's a very basic and simple glue um it's a very basic and simple a glue that we can use in our project uh I wonder what else can we do for instance um I'm gonna try some things I wanna try some things [Music] um so let me let me do a new main in here so this is going to be just a main fmt parental n and I'm going to say hello world hello world uh and we're gonna do go run Bex go uh hello world Okay cool so let's actually Define something uh let's define a command something like say um let's probably have to put quotes in here hello world right so this is my source uh right so this is my source and what can I do with that Source how can I parse that so there are easy parse all Expressions right so parse all expression it accepts the string and returns a sequence of expressions or an error if there was a you know a syntax error in there right so that makes sense uh that's pretty cool so parse all Expressions source and we get expressions or an error right something like that in the remote equal we're going to say fmt print Ln error I could not what the am I doing I could not parse uh source code for this specific reason and then we're gonna maybe exit with non-zero exit codes right so this is how you exit with non-zero exit code otherwise we can try to maybe print the literal AST that we managed to parse right so let's actually take a look at that so println and I'm gonna literally just try to print this thing so did we get anything uh and Define the OS okay so we probably have to import this OS sure there we go uh yeah that's basically the AST but uh it would be nice if we had like a Better Credit printer for this kind of stuff uh I remember that you have to do some like this like I don't quite remember it's just like hash over plus or something like that yeah so essentially Type 4 it doesn't really specify like the name of an actual enumeration uh but as an integer it has nothing as a string it has nothing it only has uh as a function right so this is literally a function and that is kind of strange right isn't it right because we have only one single expression which is a function call right and as a function call um it has a pointer to the string maybe right so if I take a look as phone call yeah it is a point right it is a point and the reason it is a point is because we have like a sequence of organisms and stuff like that it didn't really do like a deep um you know um how to say that deep traversal to show everything in that AST right it would be nice to have like um maybe a thing that allows us to print you can actually print this expression back but it actually recovers the original uh the original expression here which is not particularly great so you can literally just um you can literally just do something like s um and it just restores this entire I think it probably actually doesn't uh which is kind of weird because I mean you could do string isn't that how it works or do you have to explicitly say string ah because we have several of them okay so if I do something like uh for expert uh range I think it's kind of like I experts right so then it's gonna be I and that should actually work right because we have a string method for this entire thing yeah there we go I'm not sure why it is like that so yeah okay so you have to call string explicitly for some reason I thought that s quantifier will automatically call the string method for me but it doesn't call it for me right so if I just remove it um it doesn't do that which is kind of weird like I thought it does that automatically um I contains as an element itself let's actually find out does it contain its name itself no it doesn't somebody doesn't know good all right uh so whatever what I wanted to have I want you to have like some sort of a tool that actually dumps the AST if you know what I mean right so um essentially it will just like print this into I think growth not so let me let me see uh so how can I call a method all right so essentially when I have a method expert expert which dumps the uh the AST we can literally call it dump right uh right we can literally call it dump and I suppose it's going to just like lock this into head thing so and depending on the uh on the type we're gonna just like print this entire thing differently so we have a bunch of other types uh right expression void but let's actually use a little bit of a Max magic for this entire choice okay so I'm going to put it here case and cool so in case of void um I think what I'm gonna do is I'm gonna literally print uh avoid right so this is a void another interesting thing so I want to actually print it as in um in a yaml style if you know what I mean right so for instance if I have something like say uh hello world right the output that I want to see I want to see fun coal uh right phone call name say args right so args and then for each Arc it's going to be like uh for instance string right string value and so on and so forth I I want to actually uh see the the structure the tree structure of the of the entire AST I think it's going to be useful uh maybe it could be done like this right so maybe phone call and then in here you have like other things and also it needs to maintain the indentation right so uh because of that we need to keep track of the level right at which we are and as far as I know um go doesn't have default arguments does it right so it doesn't have them uh go Lang default arguments right so I'm pretty sure Rock Pipe Rock pipe Pike came up with a very highly intelligent reason for having or not having this entire thing that you would never guess unless you read his actual argument right but maybe it does exist I don't know foreign named returned what Duck Duck Go what about Google I swear to God optional primes so okay so they're um they're called optional parameters sure so go doesn't have optional because it's not ideal magic and because I said so okay so I don't care the reason so it doesn't have them uh sure so this is something that we have to just keep in mind uh all right so that's fine let's do fmt so we're gonna just like call this entire thing as expert dump zero then right so but then maybe we can uh Implement some sort of wrapper right that just passes that zero but it's just like you know the style thingy more of like a style thing here so uh what we can do in here is essentially just four I don't know how can you do a range can you do a range or maybe I have to actually do it like that level uh plus subscribe there's no plus plus because a rock Pike said so um there's no actual reason it's just because he said so uh and then we probably want to just do like maybe one space maybe two spaces okay sure something like that whatever maybe there is like a magic for like in a format parameters that I can actually allow me to do that but I'm a little bit uh a little bit lazy to figure that out um all right so fmt print f so here we're going to have an integer right so an integer and I want to actually bring the value of the integer right so it can be extra expression as int expression as print so in here I probably have to put a new line so for the consistency I want to use a printf in here right so I think that's cool printf and then we have Str which is going to be a string expression as s to R and for a string I have to wrap it in quotes but there's a one problem is that it would be nice to escape this entire thing as well so expression dump does not Escape strings right so this is something that we want to have as well printf we also need VAR right so this is going to be a VAR and expression as VAR there we go so all these things were rather simple right so all of them were the simple so the difficulty comes with a phone call right so we're gonna do in here we're gonna just do phone call and in the phone call what do we have if I remember correct the expression as phone call right so it's a very fun call we're having fun chat aren't you having fun I'm having such a phone call uh all right so it has a name right so here is the name and after that we want to iterate the arguments right so we're going to be iterating that argument and we're going to call in that thing recursively uh right so this is gonna be a range uh expression uh as fun call orgasm right and then what do we want to do we want to do maybe it would be better to actually do something like that I can never remember like if I add another argument in here is the actual element on the right side or on the left side I can never for some reason remember the the order is just like not obvious to me so my brain cannot comprehend it so I always get it wrong like every time but maybe it doesn't matter right so I'm gonna just like put it like this the compiler will tell me that I'm doing something wrong and then I will change it and then I will never learn what's the actual order so it that's how it usually goes right right so because I I feel like it doesn't matter it's just like I literally couldn't care a lesson which order you could actually put these things but I'm pretty sure there is like a highly philosophical reason and rock bike really thought out the actual order right so when you have to remember that um anyway but I personally I'm such a bad programmer I couldn't care less like I couldn't give a I just want my code to work all right so let's see uh not declaration inside of body okay so we don't need that stuff anymore dump is undefined uh which is rather interesting right so and it is undefined for integers who would have guessed I got the order wrong okay that's cool so now what I want to do uh what I want to do is basically just do these things so expression so ARG so it comes first so maybe I'm gonna do ARG maybe I'm gonna call it X for actually expert emacs freaking stop okay finally uh are we good yeah there we go look at that look at that AC dump look at that beautiful beautiful a-s-t dump isn't a poker's so let's actually try to dump something more complicated for instance the example that we had in here like what if we try to dump this I think it's gonna be really boogers uh so it's gonna be huge AST so in here we just want to read the file right so we already use a read file and then we parcel with all of the Expressions right so let's go so this is going to be that and we can say that source is basically a string of content because as far as I know read file returns an array of bytes right so it returns an array of bytes go doc right yes yes so yes it does return an array of bytes cool so let's go ahead and just try to execute this into I think and let's admire this entire a s t right so if we want to debug our like code we can see its entire structure in here so this is a function called Define and the arguments are variable another function call another function called and so on and so forth right that's actually pretty cool it's not even that big but uh it's pretty it's pretty interesting yeah I think it's I think it's useful it's useful to have this kind of thing and I want to actually add that stuff to the um to the original Reaper to the original uh Bex repo so what I'm gonna do I'm gonna uh just add this function call I'm not going to add this thing for for testing right so we'll say Implement expert dump right and I'm going to push that right into the reaper let me push that right into the report is it pushed is it pushed I think it is finally pushed Okay the reason I was doing all that is because I want to kind I want you to kind of recall how to work with this language because like I haven't used it for a year right so this is me using it for the first time after a year uh I can't really remember everything in this code but I now like record the gist of how uh how you're supposed to work with this internet I think and as you can see it's pretty safe forward right so it's easy to parse it's easy to Traverse it is it's easy to modify it's just like to handle on the field right let's go ahead and just try to put this thing in the in the source code of the bot okay so let's go so uh YouTube so where is the boat so again GateKeeper so and it's going to be CMD uh gatekeeper how we're gonna go about all of that I think I'm gonna literally just copy paste backs there all right so uh again I don't really want to mess with the packages and stuff like that uh right I'm gonna just literally copy paste the code into the into the project because you know what they say you know what they say they actually reusable code is the one that you can simply copy paste they don't actually say that I I made that up I'm the only one who say that but I'd like to say that but it's actually true right the most reusable code is the one that you can simply take and freaking reuse right so you take the code you put it in your project you just reuse it that's the most reusable code that it's as reusable as you can get you can't get more reusable than this that's the Pinnacle of the reusability right you don't need some dependency injection abstract factories or any you take the code you just reuse it that's the reusable code literally without any freaking cheers for that um [Music] the reasonable code is the light that made up by npm incorporation units I said uh okay guys so I removed main right so I didn't think we need that stuff anymore uh okay you know what I don't like about this code is that it freaking panics a lot it's a very panicky code it is a very panicky code so here we just check for unreachable for this one I think it is okay to panic right because I want to make sure that this switch case is complete uh is there any way to like to ask the go compiler to check that this switch case is complete right I'm pretty sure there should be some way um golang switch case uh complete because I don't want this to be a runtime error you know what I'm talking about how to write switch statements and go foreign check if complete can anybody ask share GPT please I don't have an access to it okay so um anyways exhaustive okay so let's try exhaustive thank you so much that's that's a better name uh exhausted I completely forgot about such a fancy a package you need a separate package for that everyone command line program it's a it's a separate linter to check the exhaustiveness of your switch case oh nice Lakers by the way and on top of that this language is gonna send all of your data to Google yes nice language this the feature is only available if you install Telemetry and go yeah yeah they actually should do something like that yo what the that's such a cool idea basically introduce new features to the language they should have actually they should have actually only allow generics and go if you enable telemetry yo yo ah that is such a cool idea I absolutely love it anyway so it's essentially the only way right now we can check exhaustiveness is by like at runtime right I suppose so um it would be nice to panic here as well right so generally like in this specific application I don't think panicking is a good idea because this application is supposed to work 24 7. right it's not supposed to even fail if any error has happened if any error has happened uh it should handle that log that and continue working for as long as possible because it's a service right so that's how a service should operate right but in case of exhaustive switch cases this is an error that should have been caught at compile time I think in that case panicking here is a good idea because it will force you to fix it as quickly as possible Right ideally I should not have this thing in here ideally it's something that should have been checked at compile time but we're programming and go we all make mistakes we all make oopsie dupsy and wacky so in this one it is sometimes in a decent when it isn't alright so let's take a look at other cases of planning no scope phones okay so interestingly um so we have a top scope we have a top school I just realized that scoop is a thing that I introduced specifically I can create a defined function right specifically I can create a defined function so variables and functions so I feel like that this is not particularly useful for me so I feel like this is something that could be removed by the way um will this be available in a vote I'm started learning go to yeah it will be available in inverter of course I'm not going to remove that I'm not 100 sure if I'm going to upload it to YouTube but I'm not going to remove it from Twitch item doesn't go has no in Norms thus it's not possible to check exhaustiveness how is that contradicting to each other uh essentially you have this kind of stuff you can define a type A type for your innum which is an alias well it's actually very strong aliens as far as you know and then you define the constants and we if you specify this kind of type and Iota this the consequent constants actually defined like enumerations right so you can roughly see the boundaries of a very specific enumeration you can roughly see them so the compiler can like can use this information to actually check exhaustiveness of the switch cases to some extent you can come up with the rules that check the exhaustiveness it's not an impossible computer science problem I didn't see it being an impossible computer science problem that requires PhD research uh so Iota is a special syntax yeah yeah so essentially um it automatically increments the consequent constants to emulate the uh the enumeration system enumerations all right so here's the interesting thing so this language apparently has a scope and it has a scope in a uh like a stack right because scope is a stack essentially uh right so but I don't I'm not sure if we need that actually all right I'm really not sure if we need that uh we have a vowel context and we can look up the variable right we can look up the variable and [Music] um in all fairness for this specific thing we can simply just have one scope and never push it yeah that's very nice that is fair enough so here the top scope is needed to check what's defined there this function is now if I can used by the way this function is never used so even when we look up a variable or a function we just yeah we just Traverse them in opposite order so I yeah we can just remove that is that cool that's how easy it is to get rid of the panic so you just like remove the entire function that contains the panic yet easy Bucky and easy and here we have another enrichable and which is yet another case of exhaustion of cells with switch cases okay so that means all of the panics in here in my personal incompetent go developer opinion are Justified so everything here is Justified usually for this boat I don't like pinex but if it's just unreachable that's fine okay cool uh right so this is package main do you have to specify package for each individual file yay okay let's try to compile this into I think and see if it files or not so I'm going to do CMD Gate Keeper ooVoo and we import it but not used IO util okay and another one is net http cool that's it it's as easy as that so uh Bex um let's actually put it this way uh stolen from and we're going to put the original uh repo in here so people know like from where we'll take over that I'm actually curious like where I was using topscope what I was using topscope for right so I'm gonna go to back back to backs back to backs uh back to backs top scope ah Ah that's very interesting but this is aha I see so it was necessary specifically for like to access like the top score because if I Define a new variable I add that variable to the top of the scope to the nearest scope possible so it's only needs when you really want to Define all of this like real language constructions like let Define and stuff like that uh right hello surgeon is Google really spining you yes do you see the language I'm programming in have you heard about Telemetry in go have you heard about Telemetry and go okay I'm gonna give you the link by the way so the go has a Telemetry so it sends uh all of the data all of your data to Google so they can Target their ads bad at you so yeah Telemetry and go that's the first ever programming language come with the compiler with Telemetry I didn't know the first one but I mean yeah so Google is literally spying on you as you program and go oh wait go to chain really has challenges I didn't really know actually so I think they actually postpone that idea uh but the fact that they even entertained that idea is extremely concerning to me to be fair and the title is more of like a joke and poking fun of them I didn't think they implemented that yet because the people really uh expressed disagreement with this kind of decisions so I didn't think they're gonna push it right away but I'm pretty sure they're gonna attempt like several times to push that because they really really want that they want that uh they they have like a local blog post and stuff like that and you can you can feel this they really want your day today I can really want your date please and I'm gonna see all of the projects You're Building yes yes yes so I can better Target my development tools to you please give me all of your data anyways so we'll get some sub we'll get some sub from elindrobranga thank you so much for 28 months of tier one subscription with a message thank you for all the awesome content thank you thank you for all awesome money thank you thank you thank you [Music] um anyways let's continue sending data to Google um how are we gonna actually approach this entire stuff so uh I need a context right so I essentially need a context but where do I store that context so if I go to the commands uh right so this is the command and I eval the command so in here I accept the database right except the database I accept the command in the command environment like an environment in which I execute that command another thing I need to accept in here is uh you know eval environment right so um so I already use and as a name in here right so maybe I should do something like eval and a ball and and eval context okay let's go to context to make it even more confusing you have an environment and you have a context how about that Isn't that cool by the way eval context if we completely switch to using the backs expressions for defining the behavior of the command eval context May potentially replace the command environment right because how do you send a message how do you send a message in uh in in the backs environment you just say say okay so in my brain my brain just merged together say and backs so don't add me okay say uh hello right and essentially depending on the environment in which depending on the environment in which you run this command this say implementation is going to be different which is basically what command environment is used for so maybe this this will allow us to get to read of the uh of this kind of stuff just saying maybe it will allow us to get rid of this entire thing I think that's kind of cool so uh all right so let's actually continue implementation after a small break because I already streaming for an hour and I need to make a cup of cup of tea all right all right so let's go ahead and try to compile that code so essentially I changed the signature of this function so it's used in a couple of places literally in couple so it's probably used in the Discord transport right so when you send command in a Discord and in a twitch transport when you send a command in twitch so I expect uh both of these places to break when I try to compile this entire thing I'm going to go there and I'm gonna try to see what we can do there uh GateKeeper show me it's actually Four places that's very interesting uh yeah the first one not enough arguments to call oh because we call this stuff recursively within eval commands Okay so I can actually pass the context there as well uh all right so it's a really it's a really fine environment oh yeah that's actually very cool so we have a command called serial all right which essentially solidifies your message for you can do surreal hello comrades all right and it literally just like turns this message into Cyrillic right so yeah it literally translates it to Russia this is how you say that message in Russian yes this is Russian yes yes that's how we speak we just take English and we just put additional features on the Latin alphabet and that's literally Russian right and American language but with the like with the fancy alphabet oh fun uh anyway [Music] so what else do we have in here so another one another one another one all right so and let's go to here so this is what handles when we send the command in a Discord right so there is a handle Discord message uh we parse the command if we couldn't parse the comment what we do we just feed the message to cards and carrots yeah keraton is a um state of the art in artificial intelligence and if the message cannot be parsed to the command we give that message to these artificial intelligence to train and become conscious right that's that's what it is that's literally what it means it's it's artificial intelligence I'm joking this is actually a mark of change it's not really that intelligent it's actually kind of dumb right so it listens to all of your messages and it adds it to like a huge Mark of change so then can later generate different messages based on on whatever you said I think I disabled that for twitch right so I think I disable the footage but for Discord it actually trains the Markov chain on people's messages so what we're doing here uh we just evolve commands uh right with database and command and the Discord environment so the thing we need to do we probably need to construct the eval environment uh evolved context right so and it seems relatively easy to do because it's just a bunch of Scopes right so it's just a bunch of Scopes and this is probably what I have to do in here I'm going to eval context uh and that's it so we're gonna use an an empty evolve context and I think that should be sufficient uh right so it's not a point and this is probably because in here it is probably in the here I do not accept this entire thing by a pointer but why do I put this as a pointer ah this is because it's an interface yeah that explains it so I don't need any of that scheiss in there all right so the same thing needs to be done for to which environment right so that makes sense um command environment so this is a command environment uh not commanded environment what am I talking about a vowel context right so this is a long context no pointer and there we go so everything seems to be compiling so essentially now we need to try to um evaluate something for instance I want to take these hard-coded commands right I want to take all these three commands and I want to turn them into uh into the com uh like a Bex Expressions right so that's what I want to turn them into so here what we have uh we have at author so maybe in the backs environment I'm going to put comments in here in the backs environment we're going to have a variable author which points at the current author of the message right it's a current author in furthermore it's going to be formatted in the way that can be just put in a message and it will actually add that author depending on the environment you add different people differently like on Twitch you put at on Discord you actually have to use a special syntax which includes the ID of the author or something like that you know what I'm talking about so yeah uh and essentially we're going to have author so a concatenation of the string is is going to be done through the arguments of the functions for instance I'm going to do say author um comma and then uh basically decentire message right so literally uh this entire message I can put it in here and then if I evaluate this entire thing within that specific context it should produce like a similar result right but we I will have to implement a variable author and a function say right so let's actually introduce something like something like an a variable called Source right so this is a source maybe let's go with Bex right so again like that but we need to escape some of these things in here right so we're skipping this thing in here and here is the backs of that specific command the first thing we need to do right the first thing we think we need to do we need to parse that command parse so we have parse all Expressions if I'm not mistaking bars all Expressions uh and it literally parses all of the Expressions but Kenny Parts only one expression in here so Parts one expression and it needs to be converted to runes and blah blah blah um okay so I think we need to use parse all expressions the parse all expressions uh but here's an interesting thing that means you can have several expressions in here right so because a single string may contain several expressions right it may contain several expressions so this is experts and uh we're gonna have an error in here we're going to have an error uh so and how we're going to be handling all of that by the way how are we going to be handling all that I suppose if the command if the command in the database because we're going to store this string in a database if the command in the database contains several commands we can just evaluate them in sequence right we can just evaluate them in a sequence which is kind of cool because it could be a sequence of several things maybe the comment will say hello world but hello and world are going to be two different separate messages and it's going to be like say hello and save world right so literally backs is going to be something in a database say uh hello I probably need to add support for for single quotes kind of cool and then say hello world I put single quotes in here because I didn't want to quote them inside of the double quotes you see what I mean and if we say if we store something like that in a database it would literally send two separate messages right so we can kind of like program the behavior of command in this simple scripting language uh right so to speak right because of that it should be relatively too forward to just do uh to just um iterate through all the expressions and just evaluate them right uh okay so this will be arrange experts arrange experts and we need to evaluate them the question is how do we evaluate them eval uh it should be a function I'm pretty sure should be a function a vowel context push context uh eval expression okay okay so you call to the context and you evaluate the expression and you get the result that's what's interesting you get the result of that set expression uh okay that's pretty cool expression context right so this is the context eval expression and we provide the expression right so we provide the expression and evaluation may actually fail because of that right so it may also return an error so this is going to be a result and this is an error wrap so by the way parsing this into I think may also fail right it may also fail which Rises the question how we're going to be reporting all that and what is the possible errors that we can get while parsing this into editing uh right so let me see so what do we usually report so we sometimes say expected uh-huh but we don't really see where usually they're relatively safe to report to the user I think yeah I think all of these errors are relatively safe to report to the user like a known variable a known function so because I'm thinking should I uh set that in a public chat or should I log it locally so people can see that I think it's relatively safe to actually like say them in the chat right it's going to be easier to debug that uh right so if we can't do that yeah so that's that's pretty very step forward okay if error not equal new we can just like literally say environment send message we're gonna add the author right so environment at author and we're going to say something I could not parse the source code of the command um syntax error um syntax error in telesport syntax error so I'm trying to make this uh think less cryptic but I think I'm gonna do that a little bit later uh command um because I want to make sure that the user of this command knows that it's an oopsy-doopsy that modes did not not the user okay so let's actually literally say that mods did and oopsie doopsy oopsie tell them that the um uh they have a syntax command syntax error and then we're gonna do ever something like that and so maybe if I just do it like that will it work maybe maybe not okay and then we return out of that mods did tell them that they have a syntax error um all right so in this case if error not equal new right what do we do environment send message uh maybe in [Music] yeah it will be kind of nice to Pink the the modes but we're gonna do that later doesn't matter and after uh mods tell them that they they have but tell them that they have a l runtime error that they got a runtime error my plus error though I'm not sure [Music] okay I'm gonna log the error because I think during the run time the runtime can return arbitrary errors and this is something that we generally do not want to show to the user right I think generally we don't really want to show that to the user you know what I mean uh right because you in the definition of the function right if you when you define a custom function you may throw a custom error which may contain sensitive information right I think it would be better to just generally log this kind of things and just ask the user tell the modes to check this kind of stuff uh right so it would be better to say mods did and oopsy doopsy while defining this command this command ask plus environment at admin right to check the logs right and then we're going to log the error right so I'm going to say print f um error error while parsing while parsing that Command right so we can say something like dead command and then we can simply provide analysis I think newline in login is not necessary because it automatically puts a new line in there anyway uh right and we're going to put error in here there we go so the same thing is going to go in here right so mods while defining command and we're going to remove this one and we're gonna we're gonna log error while evaluating a dead command and there you go so I'm copy pasting things around because in in the future I'm going to compress all that so it doesn't really matter so and what's interesting is that after evaluating the command you usually have a result right what would I want to do with that result I think uh in this specific case where you can just ignore it right I didn't think it it is useful in any way shape or form right uh it's it's not particularly useful in any way shape or form uh okay so let's try to compile this entire thing all right to compile the the bot and try to run the bot and see how it's going to go so it doesn't really compile because we have uh some stuff in here so result is unused but can I just say okay I'm not planning to use the result though uh right I do not plan to use it can it use an expression and um yeah this is because it's defined in a different order all right it's defined in a different order and there we go it seems to be compiling and seems to be working it seems to be it's working right so I wanna try to run the bot but I need to work with sensitive information so I'm gonna actually do this kind of thing uh look away look away working with uh credentials right so don't look at the stream right now while I'm actually setting up the tokens and stuff like that just don't look at the screen right so because I don't want it to be leaked and uh then people will hack me right so that's very important so check don't look don't look okay okay good um okay all right all right so I'm gonna do something like is that and uh used to used to use a couple way three condenser uh I think I already where is my gatekeeper I can't find my folder with the gatekeeper I'm gonna rebuild it into I think uh just in case super quick and I'm gonna run z-bot so the problem with the boot is the problem with zebot is that we um don't distinguish them so we I have a production bot and I have a this local testing bot so one of the things I probably need to do right now is uh set different prefixes for parsing so here it uses exclamation mark or dollar for prefix prefix in the command I think in here I'm gonna actually replace this stuff with uh this thing right difficult it's just like with a carrot roof thingy I don't know so I keep forgetting how it's called Uh right so let me try to rebuild this into I think it is rebuilding and I started the board I started zebot uh all right so we can try to do pink it's ponged and when I do dead a circumflex yes and um okay so we have a first failure we have a first failure so we've got a log with the message we've got a look with the message that looks like this uh right in here error while evaluating that command Commander okay who killed Captain Alex um [Music] all right so it says that we cannot evaluate the functions say right because in the original source code right in the original source code we call to the function say so first thing we need to do we need to actually Define that right so let's go ahead and Define that specific function so it has to be defined in at which environment right so in evaluation context in evaluation context we need to define the scope let me take a look at the backs right so this is a valve scope so we have scopes and in here I'm gonna probably um just create a new scope like so um I wanna if I can just Define something like this I think I should be able to just do it like that will it infer everything that is necessary to infer in here uh right so eval scope like I don't remember can I I meet some of these things probably not right anyway uh then uh I need to Define function funks and this is a map if I'm not mistaken right so this is going to be a map uh tring right map string and here we're gonna have a say but the question is what is a function right so what kind of arguments does it accept uh right what kind of arguments does it accept is it defined anywhere type phone book yeah okay so it's a function that accepts the context right so it accepts the itself context eval context context and the arguments right so this is going to be expression and then it returns uh the final expression the result expression or an error right and it returns a customer and this is precisely why I actually said that I don't want to log an error because here you can actually return accidentally something uh sensitive so you probably don't want to do that right so in here we're going to Simply um say through the environment right so depending on the environment we say things differently so we need at which environment to actually say anything so I suppose it would make sense to Define an environment first in here so then later we can refer back to this environment and say uh same message or maybe something what was it called I think it's called send message send message and we literally just so we're supposed to evaluate all the arguments in here but we're not going to do it right now we're going to just say um hello from Bex I'm gonna put a smiley face in here right and after that we can return something and I suppose the reason why I introduced expression void is precisely so I can return nothing if I want to uh right that's actually pretty cool how can I construct a void oh since void is zero the default expression is actually void Express this is so smart what the so I can just return this and uh new and it's a valid expression it's just like new yo what the ceremon what's up what's up what's up hope you're doing well um eval expert Funk are you making twitchlank I'm making a script in small scripting language uh that describes the behavior of the bot commands and in fact I already made it it already works I'm just integrating it with the chatbot right so that's that's basically everything about what I'm doing right now I'm slowly but steadily integrating this entire thing okay so let's go through the compilation errors and see what we have in here expression must go okay so I did a fakiwaki and potentials so here I suppose they had fun uh right so syntax error so it's supposed to have uh these things in here and these things in here so a new line yeah so I keep saying that over and over again so don't you find this ironic don't you find this ironic that this language doesn't require any semicolons at the end of the statements but if you are defining elements over uh array of a structure it's going to be so annoying it will require you to put these commas in here don't you find this ironic just think about it like why it's so weird uh we got some subs let me actually acknowledge the subs uh I actually won uh these two computers thank you so much for 46 months you want the subscription with the message so bro yo what's up bro what's up you're always welcome you're always welcome my friend to my streams thank you so much thank you thank you thank you for being in here so yeah it's kind of interesting it's been so relaxed about semicolons but it's been it's been so anal about this course it's just like why why I don't mind actually like don't get me wrong I don't mind I wouldn't even mind if it was super annual about semicolons but like why is such an inconsistency like because Rob Pike decided so okay so yeah that explains everything um just comment your question and code Google will answer you an email nice I mean who needs co-pilot after all if you can use just use go Telemetry and the the Google the the actual Google Engineers will get back to you and fix your problem not just like the chat GPT sorry anyway that's a good job um let's try to run zebot I'm actually going ahead and running zebot zebot let me actually make it a little bit bigger so can you see the chat by the way uh we're gonna do a ping okay uh would you look at that thank you see a good time uh hello from Bex smiley face is not cool so yeah so it doesn't really act as intended so what we have to do uh we have to now take all of these arguments right so we have to take all the arguments evaluate them uh concatenate them in a single message right so concatenate them in a single message and then um send them you know as the as the message we've got another sub young 2000 thank you so much for twitch Prime thank you thank you thank you really appreciate it why I see almost eclipsed python as the most popular language according to Toby what he is being popular again thank you so much for 17 months thank you thank you thank you is it is it gaining popularity what the this is because of my yesterday stream I'm pretty I'm joking it's probably not so you see it only took one C stream for me and C is already overthrown uh overthrowing python and Visual Basic like it's so weird that Visual Basic is top 10. it's actually losing but I mean it's still weird probably because of the Microsoft Office here because by itself who programs in Visual Basic by itself I'm pretty sure everyone just like writes macros for for office um and Assembly Language is a little bit sauce in my opinion because Assembly Language is not really specific language the family of the languages right so which assembly is the is the most popular one like is it is it by assembly they mean x8664 or does it mean arm or what exactly do they mean it's just like a family of the things [Music] scratch I'm also surprised that scratch is popular rust is gaining popularity what the I should stop I should stop actually programming in Rust because it's gaining too much popularity we're not going to give any more exposure to the rest all right so uh uh what we need to do we need to iterate through the arguments and just like evaluate them and concatenate them what's interesting is that what's interesting is that arguments can evaluate to Strings uh integers and other function calls so that's kind of the problem right so what if one of the arguments literally evaluates to this functor how are we supposed to print it I have a feeling that this is going to be a run time error we're gonna allow only printing uh strings and integers we're not going to allow printing anything else are people really writing more Excel macros than websites what the I wouldn't be surprised honestly I wouldn't be surprised I'm pretty sure uh Excel runs the entire world I'm like I'm pretty confident the Excel writes like runs the entire world do do all right so hello from Bex and uh so let's actually iterate this into that thing I keep forgetting how you um how easy it is so first comes the index and then comes the the element and then comes the element so for index ARG in not in range RX right there we go so then we do context the vowel expression right we evaluate the expression organ so and what we're getting here is the result all right so this is the result or an error in case of an error if we've got an error what we have to return it's not new uh we're gonna return like a void expression and the error itself so we basically bubbling them right then after that we need to check that result is either string or integer so I think we're going to use switch case for that so this has been result and I think it's kind right so I'm pretty sure it is kind uh it's type okay sure so it's integer string variable right so essentially these two things should never happen if everything is performed correctly right if everything performs correctly honestly like the problem is that you may have a variable that contains literally AST of function right and because of that you won't be able to properly print it anyway um uh so because of that we need to check this entire thing so this is going to be the case uh if uh type is what expression integer so this is one thing and then it's going to be Str and if it's something else if it is something else we have to report an error I'm pretty sure about that so it can be expression uh expression and what we need to say in here it's it's rather interesting so I need to say something very descriptive right so I'm probably going to do fmt error app right so this is how you create a new error in here so let me actually readjust everything so you can see the entire thing okay so I'm going to put it at the top and here can you see stuff at the top so I'm editing so oh nice code by the way uh right nice code by the way I'm indenting it too much so it's difficult for Google Telemetry to actually steal my code this is intentional their code analyzer is going to basically stack Overflow while trying to analyze this code and that is that is my goal right I'm doing that intentionally my code is not well it is but it is on purpose it's on purpose it's basically to debate the Google analyzers right so they stack Overflow that's the the whole idea anyway so um we can say something like this evaluated uh into uh into something into this which is neither which is neither Str so I can't uh say command can uh can not display that right so and what we essentially can do we can take ARG and we can basically render it as a string and then we can take the final result right and we also render it as a string so in the error message we can see actual expressions in here hopefully right hopefully we'll be able to see actual expressions in here right if this is an expression if this is an integer or a string we essentially have to append those things but by the way people I remember people ask me what the is this thing uh this is basically leading uh White spaces right so if I have some reading white spaces emacs actually shows them to me right so if I just put something in here it will go away effectively right so what I want to do I probably want to create a string Builder into which I'm going to be appending all these things right so that's basically what I want to do let's create S Beam which is going to be strings Builder right so this is a strings Builder and in here uh we're going to essentially just do things like let me take a look at go doc strings to build a so what do we have we can write some we can write string um which is probably fine right so as being right right string and then I want to convert an integer to string is there any easy way to convert an integer to string is there something like uh I to a or what not golang I2 I to a not a to I um or maybe you can just do string string condo yeah can't you just like take result as int and just do string isn't it something that you can do probably you have to use esterconf I feel like you have to use this to your consoles take a look at the esteroid i2a and can it fail it cannot fail okay that's fine uh is equivalent to format INT in 64. okay that's fine so that means we can do um SDR conf i2a all right and then I'm going to put it like that I feel like I wanna move this entire thing somewhere else right so maybe we're going to have a function that creates a vowel context from the environment I think that's a good idea right so essentially let's just go ahead and create something like this and it could be something outside of the twitch as well right but what we'll see uh right so eval context contact from twitch environment right so here we're going to be accepting um to which environment right suppose twitch environment yeah can you just give me to which environment thank you so much and we're going to return the eval context right so we're going to return evolve contacts then eval context I'm going to take this entire thing um the vowel context from twitch environment and I just provide this entire thing a vowel context from twitch environment let me just return to this entire thing so I think it's a little bit easier to comprehend now obviously I think it's a little bit better now right so because it was a little bit too too nested it was a bit too nested uh okay so what about the um the right string all right right string and essentially since the expression is the string and you can just do result as Str not integer Str and that is it all right so after that we concatenated all the arguments of what we need to do we just need to send that specific message right so this is going to be SB uh string if I'm not mistaken so let me take a look at strings Builder right strings Builder there we go uh so do we have we we literally have a string that's pretty cool all right so that's the entire implementation that's how we Implement string but this is not enough right so this is not enough because what we can have in here we also query the variable author we also query the variable author and we need to add that variable here as well so in the scope we have functions but let's also Define vars so in according to Bex right towards uh is is just a map of Expressions right so it's literally a map of Expressions so map string expert right so we need to have author and what is the author the environment already contains at author uh right it's basically environment at author so even though it's a function we basically evaluate it once and we cache it into the scope which may create problems in the future but maybe not because usually at author is not going to change throughout the execution of the command right and it's going to be cached for entirety of the execution of the command well we'll see it's something to keep in mind but this is an expression right this is an expression this is not a string so what we have to do we probably have to construct it literally an expression right so these things should become as Str and the type should be expression Str there we go so that's basically it so now in the environment right in the actual environment we have a variable and a function right custom function uh so that's pretty cool seems to be working seems to be working I'm really happy about all that so uh let's go so I want to recompile and go to the compilation errors build GateKeeper and what do they have it's it's not a kind it's a type uh Estero conf we have to import this entire thing let's go ahead and just import all that stuff hmm and it seems to be working it seems to be working okay so let's see if it's going to answer the dead Command right is it going to answer the document I'm going to restart the boat right I'm restarting the boat so we're gonna try to Ping uh Listen to I think it's so slow my god well what about that okay it worked right so this entire thing worked right so it evaluated this in the stuff and uh now it is working so what that means what that means we can now take all of our commands including built-in commands like weather for instance we can split their functionality we can split their functionality into these building blocks like taking HTTP query and whatnot and then get rid of the syntax switch case get rid of this entire switch case and basically put all the commands into the database right so these are small scripts in the database essentially and the implementation of eval command is going to consist of just this thing and the backs is taken from the database right that's basically the idea uh right that's basically the idea we can do a similar thing for gatekeeper or some other stuff right maybe we can try to do that right now so we need to we can't just move everything into the database like right away because there's a lot of things in here right so and some of the things are kind of difficult to um import into the uh into the backs right so I think I want to do that incrementally right so we we're still going to have a separation between build in commands and the commands that are stored in a database and I'm going to slow slowly migrating uh the commands from the like hard-coded code into the database right so it's going to be like a longer process than just like quickly migrating all that so I'm going to just prepare it and slowly migrate all this one by one one by one all right so maybe we need to create the table where we're going to be storing all of these commands I think that makes sense right so uh here in the boat I have uh the folder called SQL right and it contains migrations right it contains migrations uh so essentially how does it work right only first start the boat looks at all these files and sequentially applies them to the database so they can then SQL queries right so it goes through each file and just runs each SQL file on a database right and then it remembers which files it already run right and then the next time you run the command it doesn't run things that it already run if you want to update your database you create a new file in here right so SQL then on the next run the bot will see okay there is a new file in there that I didn't apply it will first apply it and this is how it's going to migrate to the new scheme of the database so this is how it works in here so this is migrations uh right so and it stores the information of what files were of late or already applied in the database itself right it starts it there so we can even take a look at this kind of stuff like um so let me see so opt postgres it's actually I think it's PG SQL bin psql and uh I don't remember I think you have to do GB just D not DB gatekeeper right there we go so we take a look at the tables uh it it has migration tables right and if we select everything from migrations right so it's a table yeah right it contains like literally information like what files were already applied like file name the query that was applied and when it was applied and so for instance if I add a new file in there it will check this uh table then compare it with what it sees in the in in a file system and it will see that it needs to apply another file before even touching this database because the code uh assumes a different scheme of the database and if they call the same difference the database it's not going to work correctly with this state of the database so this is basically how we approach that right so yeah by the way I build my possible from scratch myself yes because I'm using Debian stable not just DB unstable stable but old jibian stable right but that's sinking old Debian stable right usually jibbon stable is already old but this is extra old so the way um I use recently I think is essentially if I need some sort of a software right I obviously cannot just install it from the repos if it's not something basic right so things like like very basic things like Curry kills I don't really care about it right if I need something fresh I essentially download the source code and build it on my machine like a slackware style right and what's interesting is that I think I reached the point where the new software that I'm trying to build is not happy with the libraries that I have on this machine my libraries are too old I'm really reaching the point that to build a new software I first need to build a fresher Library and only then on top of this lamp no of course not um I'm running it on a separate machine with the newer version of Linux in a virtual machine that means for testing purposes like the like to test things I'm running this on my machine right now but I'm gonna kill it right now uh right you incrementally phasing out of all Devon exactly right so after some time it's going to be basically from scratch right at some point there will be no debit in here um so are you drinking whiskey or strong tea I'm drinking tea actually it's a green tea actually [Music] so you won't be able to build new libraries because the computer hold I'm using like the compiler that I downloaded from official clang website all right so so this is not the stock compiler I mean GCC is maybe ease but clang is is not right it's a it's a little bit fresher than that anyway so um and probably like I need to spend some time to just upgrade my dip in stable I'm just like too lazy and Linux you know Linux being Linux like it's I'm just too afraid to touch anything right I'm just afraid that listen I think is going to break right so that's basically it um it's pretty secure uh great table so what we're gonna have in here is suppose we're gonna have commands right so we have commands and what's going to be another thing one two three four uh we need a name right which is already probably taken right because highlighting but it usually doesn't matter and the backs of the command let's call it decks I think it's a pretty good name so in terms of um in terms of what um so I'm thinking do I wanna limit the amount of characters that I want to have in here probably not now let's actually do varg chart and 64 characters is a 64 characters enough for everybody this is 64 characters so are we going to have command that long I'm going to have come in that long I think it's already too old it's too too long I think that's fine so this is the first limitations in terms of the limitation of the backs do I want to limit backs right so if I say all right so you can have 1024 [Music] um okay so here's the idea I don't want Bex to be used as a real programming language so essentially if your expression is too complicated you probably want to extract that expression to go function and I kind of want to encourage that right so because of that I want to limit the amount of stuff you can put in there right but what if your command is just say a certain message which is uh very long right what if it's just very long message it's probably not gonna look great in um in chat anyway because for example for twitch there's a limitation of 512 characters if I'm not mistaken right twitch cannot even display that many characters anyway like I literally can't send such a huge message right so if I literally try to copy paste this thing I think it won't send that yeah it even told me uh five-handed characters right so 500 I can't even say you send that thing so even if I need or did it sell it anyway so it actually basically cut it out right so yeah there's no reason to make this kind of stuff unlimited and generally I heard that it's advised in a database to limit basically everything just put limits on everything because you never know what kind of stuff may happen and you will have databases like that in infinitely grow or something or some you know things that are uncontrollable right it's better to have some sort of limits in here and because of that I think it's going to be vulture 1024. I think it's a reasonable limited limitations limitation [Music] um what about getting from a long URL but the information that we get during evaluation of the command is not stored in a database that's what's interesting right so for instance you can have a command right which is basically HTTP uh https what the I'll get some data.com the length of this command is 32 characters which fits there but the result may be longer than 1024 so we're not talking about actual returning thing we're talking about limiting the database so if you have data that is bigger than this size it's not a concern of the database because it has nothing to do with the database right now we're talking about the database and how much you can store in a database you see what I mean so how much data we generated while evaluating this thing is not a concern of the database you see what I mean right so it's about just storing the source code of the command um uh all right it's like a completely different problem like it's it's not related to what we're doing here okay so what I want to do I also want to say that uh the name should be unique right I think it's reasonable to demand a name being unique right so do I want to put any you know IDs in here or any indices right now probably not right now maybe later I'm gonna put something in there but for now we can just keep the center I think like that all right so uh let's take a look at the database right so I'm going to connect to uh to the database right so this is what we have in here I'm going to restart the the bot right I'm going to restart the bot and it should migrate and as far as I know it's already migrated and as you can see we have commands right so even if we take a look at what we have in the comment from commands uh there we go so we can try to insert something into the commands right so let's insert um into commands essentially name backs and uh what kind of values do we want to insert into this thing um so um I have an idea long time ago a long time ago in a galaxy far far away with the old boat I had a command called Steel right and essentially what it would it would do I think I have to do it like that yeah oh this is actually so cool right so since you're supposed to use single quotes it's super easy to use double quotes in the backs right it will take um the ARG the argument that you provided right so let's actually say call it Arc zero so this is the first argument that you provided into commandment we can say um ARG in the current year the current year and then some sort of a mode like cake w right uh something like that it's more of a like a joke of Imagine using X in 2023 right and you would do a command uh that sets that says something right uh something like steel yeah still go and Bot will say go in 2023 ah something like that so that was the idea so people can make fun of things or make fun of old things in in the modern year so it was actually very fun command people really liked it I want to bring it back right so there you go we brought it back now what we have to do we have to essentially interpret this commands right we essentially need to interpret the community that's as simple as that uh so uh let me go into the comments All right so and I think I want to go specifically into twitch and update the context so here we don't really have a year I'm gonna add the year but I'm gonna make a shortcut right I'm gonna make a shortcut so I'm gonna hardcore the year as integer uh 2023 but it should be unheard coded so I believe it should be automatically queried on the current machine and then we should say Okay unheard code the year right and how could the year uh already so that's pretty cool so Android code here and another thing that we need to have is ARG zero right Arc zero the problem with that it's reliant on the commands right so that means we need to get the command in here right so because it's literally the argument of the command so this one is going to be more of a Type X pression Str and as Str it's a command Rings there we go cool so we have all of these things in here so that means evaluating this entire thing should be um should be portable right so the next thing we're going to do we're going to go to the command evaluation and the first thing we're going to do we're going to query the set command from the database right so we're going to query this set command um so how we can do that I'm gonna like literally headquarter all that stuff in here um I remember that in keratson we do a lot of database queerage queerage look at this word uh so we query the database a lot that's what I'm going to say um okay so DB yeah query row right so this is how we do that I want to select um name and backs maybe only backs uh Backs from uh commands commands where a name is equal to uh how do you yeah so it's equal to Door one we don't really need to order anything all right there we go so that's the query that I need to make right so select Backs from commands where a name is equal to uh to the name of the command right so it's a little command name like that uh command name so essentially the next thing I need to do I need to scan all of this like all of the rows but I expect kind of one and I think there was a way to say that I expect one thing right I remember there was a way to say that I expect one thing but I don't quite remember are all right so let's do go doc SQL DB sqldb query query uh row context uh-huh was there any like maybe it was something on the level of a scanning so let's take a look at the row uh-huh [Music] in the four chat attempts SQL injection I mean that's fine I don't really care about that specific database even if I up uh right though yeah SQL DB escapes but here's an interesting thing you still can have a minor SQL injection even if you use like a proper escaping and stuff like that I recently discovered that you can inject SQL if you use like constructions you know what I mean right so if I hit something like name like and then within the name you would do something like this you can have a minor SQL injection that injects additional parameters in here like in a recently discovered that I never thought about that before and it's yeah it basically suggests that you should probably avoid the like you can circumvent that right it's it's really easy to escape the syntax of like it's nothing like escaping SQL but still right I mean if you're you should never like put user input into into the like argument of like right at least that um MySQL real real Escape final version yeah I mean it's a function like that um yeah we need this kind of function because of real real Escape and it's kind of like the once I discovered that it actually spooked me a little bit uh that means that it's not enough to just rely on escaping of the possible SQL right you still have to constantly think about this like SQL injections even if you use this kind of escaping because you can inject things through other quirks of SQL not necessarily through the syntax of the SQL because like it's like sub language of SQL and it's just like can we just solve this problem once and for all I know uh I don't know everything about using sqlc it lets you write a schema increase in SQL and generate go code from that this is basically add an additional layer of abstraction on top of uh things and I don't like to add layers of abstractions without any particular reason if they don't solve like actual problems right because these kind of layers they don't come for free they're like almost act like physical construction so that means you um you will need to deal with the complexity of that additional layer whether you want it or not you still have to deal you may think that it solves your problem makes your life easier but in reality it all leaks through anyway right so um DB to XT yeah it will be better to actually install that in the text file so name is equal to to that right so the next thing I need to do is basically query the the stuff right rows next uh and does anyone remember I remember like that go package for SQL had something uh to check for the rows Rose skin yeah you can scan only once I mean yeah if you escape if you expect only one thing you can just do one single scan and just forget about it I think that's reasonable uh right so this is the uh the follows frequency let's say backs right and backs is supposed to be just a string back string we didn't really expect anything else and if it has no rows yeah okay so essentially if it has no rows we have to execute one of these commands in here that's going to be the idea right so if we didn't find such command that's what we do uh right so laughs [Music] but that's rather interesting so how can I it would be nice to have something like eval built in command and then simply evolve built-in command is being command environment context easy easy all right all right if error is um still not equal new right so something went wrong right so something went wrong and we need to probably log that somewhere log print we can still say something to the user about that right so uh we can still say something went wrong please ask so usually with a database so I'm gonna copy paste one of these messages I suppose um just copy paste one of the messages eventually I'm gonna you know factor that out cap right and we just return out of here right if something went wrong we just yeah whatever log print f error while querying uh while querying um command s s so the command is name and then we get an error right we don't show that to the user we just like put it in that cool so after that we can just take the backs and just evaluate it right you can just evaluate it so and the way we evaluate it we evaluated the same way as we do with that right so I can just copy paste this entire code and go back and put it in here so we already have bags we don't need to have it in here mods did an opportunity while defining this command ask to check the log that's fine and as you can see here we had coded the dead command but now we can just simply remove that and can say command name all right and the same thing is going to be here as well okay cool all right so that's fine essentially we create the command if we didn't find it we just evaluate the built-in command right so I removed a value four dollar one yeah thank you so much I'm gonna just put it in here let's try to compile this thing and see if it's going to work um [Music] okay so let's go to the compilation there's uh commands it's a single command that's fine too many values we don't have to return here apparently anything else okay so here we also have to provide the command when we constructing the evolved context all right so that works that works so we need to now try to evaluate the still Command right and still command is not hard coded in the source code it's defined in the database right it's defined in database and it should query it from the database uh so what I'm thinking is that I'm gonna just split my screen a little bit and have I'm gonna put this thing in here all right so the chat is going to be here and I'm going to start the gatekeeper right so now we should have still go while defining the command right so it says that it expected um something in here so mod mods did an oopsie doopsy and potentially a foggy wacky all right so I didn't understand what's wrong in here what exactly is wrong in here like it says expected uh so that's the syntax server it couldn't it literally couldn't parse Listen to I think it's it says expected this right always those modes yeah exactly those ones are get demos uh all right Dex go gatekeeper expected this thing so it usually happens uh when we have something like this Commander command Commander Commander Sparks who is bled sugar anyway so maybe we can just print bags uh uh so let's actually try to print this thing printerland uh and then log println um Dex let's have some Bex chat together it is compiling actually let me bring the chat so we can have bags and I'm gonna try to run this into I think okay um so still mm-hmm well I didn't see any problems right I didn't see any problems so it's says that this thing is not working maybe this is because it doesn't support the spaces in the uh in this stuff like yeah hmm or maybe I did some weird logic in here maybe not [Music] we need to literally try to parse this thing uh locally right so we need to try to parse it locally so let's go to let's go to some sort of setup we're gonna try to parcel this so Bex dot go yeah I'm gonna go here so this is going to be two Funk Main and I'm gonna put this thing in here I wonder like what exactly could have up um of course all Expressions bags and then we give experts experts error if ever automatically no fancy print app whatever s error and just twice maybe maybe just return for experts expert range experts and we can dump this entire stuff comes here we go run Dex go okay this is true uh no what okay I expected this thing so what's wrong with you my friend okay so it's that is that because of this thing God damn it you can't have numbers in variables what a shitty language who who made this language who the made this thing let's actually quickly add support for that like why not why can't we have that uh all right who the made this piece of shy suit uh all right so if these things starts with letter we keep hmm so if it starts uh with the letter span runes trim runes uh Source runes is there any particular reasons the reason why the will do that so I would expect some sort of um [Music] um so this is the digit I see ah I see so span runes we just like yeah see we could try to do the following thing um X room letter or is digit so essentially the variables have to start with letter but then they may contain uh digits why did I do that I mean it's a such a simple fix uh I think yeah I think you can use ins in varnish you're trying to pretend like you know my language data icon just recorded myself better than me is that what you're trying to tell me like I mean yeah now you can use digits in in variable names yes I I just implemented it yes I just added that feature uh all right so I mean I I don't really know my own language that well as you can see so foreign okay so what do we have in here so this is a function it's supposed to return Boolean uh okay it compiles remember that I moved it chat chat chat chat are you ready the moment of truth the moment of juice still go first try Birds try and this command is defined in a database here it is here it is I should be able to to modify it actually believe it or not I'm pretty sure I should be able to to modify this command so up to date uh commands update commands set backs to something like I don't know we can set it to um [Music] um so we should do something like author right so let me let me put this thing in here so we can see a little bit say author space the command was expired sorry smiley face the comment was expired sorry and then where name is equal to still right so I can literally now modify on the Fly Right can I can I do that now if you just do still huh if you do still the command was expired so as you can see I modified it on the fly without restarting the the boat I just modified the source code in the um in the database right so that's actually pretty cool I think ARG zero so what we can say in year oh w ow let's actually put forehead should be fine mm-hmm still scripting languages steel scripting languages that's super cool so I can also now add more commands right I can also now add more comments as far as I know we have when Command right uh so we can maybe add vanish command people were asking me about vanish Command right so uh commands I'm pretty sure it's not going to work because we are kind of escaping uh we're kind of escaping the messages so the the bot cannot accidentally send the command right so I'm pretty sure it's not going to work so we can do something like insert into commands right we're going to insert a name and backs values so what kind of Wheels we're going to insert we're going to insert vanish right and in terms of uh what's going to be the vanish command right let me see so we can say say um time out time out space the outer for one second I think this is how it works right so that's basically how it works and it's not going to work properly uh well use right so values so let's actually do something like Revenge yeah so as you can see it escapes those commands all right it escapes those commands so one of the things by the way we can do one of the things we can do we can introduce another custom Command right we can introduce another custom command that literally times out the uh the user and doesn't doesn't use escaping right so it's going to say time out we can time out the altar though that means I have to parse the author right at some point but yeah I feel like it's not particularly particularly useful uh right insert all right so maybe we could introduce like a say an Escape right you know what I mean say an escape uh so update commands uh set backs say unescaped oh I know unsafe say and safe that's perfect right and we're gonna say slash time out space alter uh one second right so that's what we're gonna do uh that's what we're going to do [Music] um so and and it's not going to work by the way again but because we don't have a say unsafe right we don't have save and save I'm already tired so I'm trying to speak Russian uh all right so did it work I think it did in fact work uh right so if you try to do avenge now if you try to Revenge uh it says mods did an oxidoopsy while defining this command ask sodium to check the logs right so in the reasons because uh vanish command and escaped character underscore it doesn't support end this course what a shitty language it doesn't support numbers in variable names and underscores any function names okay so I think I think this is something that we have to fix as well so let's quickly fix that uh let's in fact quickly fix that let's in fact let me fix that so uh when we are parsing a function uh is letter uh oh it depends actually yeah so this is the same code that parses both function codes and variables if I understand correctly right so this is a fun call if it contains this thing but if it doesn't oh it's an expression okay what the hell what the hell happened here by the way so that was weird but yeah that makes sense so this is expression War uh and so on and so forth so that means here I just have to say or X is equal to underscripted so that's it should please pretty easy so now we do support uh Escape can underscore but we need to implement that command specifically right so say there we go so how can we even do that how can we even do that all right so let's say unsafe and I'm gonna literally copy paste this entire thing because it's like duplicate code right but I'm gonna unduplicate it later I I promise trust me I know what I'm talking about so instead of send message we have to send something else but it actually very much depends on the twitch environment right so how do we do that in twitch environment I wonder so uh we do send message and this is what we uh what we do in here so I suppose it makes sense specifically for twitch environment to introduce something like um send message unsafe right send message and save where we effectively just do this entire thing except we removed that dot in here and this is the dot that sort of escapes any potential commands in here so that's kind of the uh that's kind of the point in here say I'm safe right and in here we send message unsafe all right there we go that's basically the idea this compile it seems to be compelling so let's bring the chat back right let's uh that was weird but I suppose I just reloaded the configuration so nothing particularly special right so since I'm a mod so vanish should not work on me right but it should work on you now try did it work did it work oh it didn't work you know why I feel like twitch changed something with its commands I think commands don't work through IRC anymore I forgot about that this is probably one of the reasons why um it didn't work my tutorial didn't work anymore yeah so I suppose commands this kind of commands now are through their API right so that means we'll need to make API calls all right but whatever uh so vanish for the issue is super funky man but so basically it will time you out for one second and it will remove all your messages so now we're stuck with just still still um rest API still rest API rest API in 2023 whoa how do you connect to Twitch by the way sockets and I'm yeah I'm using regular sockets should I use web sockets should I use web sockets Maybe oh it depends on the kind of sockets you're using right so it works in twitch chat but I mean in twitch chat they can just actually uh proxy the commands through API calls right so since it's a web um uh make vanish to not print not found please what what do you mean ah I see what you mean in Discord like yeah yeah sure I'll do something like that um all right so I implemented everything I wanted to implement I integrated a small programming language into the thing right into the into the chatbot so now I should be able to migrate all of my hard-coded commands into the database and modify those commands by modifying the database so does anyone have any questions before I go do you reverse the SQL query in your code from like to equals I'm pretty sure it pretty um [Music] all right so does anyone have any questions before I go I suppose no questions right so you have an opportunity to ask me a question so some people subscribed alright so I completely missed that thank you so much uh use uh use the 10 401 subscription thank you thank you thank you and Flash I love my own thank you for twitch Prime with a message love you big man I love you too uh how do you write clean code is just kidding thank you thank you for not forcing me to answer that question uh all right so I guess that's it for today uh thanks everyone who's watching right now I really appreciate that favorite one and I see you all on the next as using addition I love you [Music]
Info
Channel: Tsoding Daily
Views: 37,679
Rating: undefined out of 5
Keywords:
Id: TS0C_pt08Go
Channel Id: undefined
Length: 151min 36sec (9096 seconds)
Published: Thu Mar 23 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.