Alright, so let's get started. Thank you for sticking around during lunchtime. This is going to be five years of till, minimalism versus growth in language design. Okay, here we go. Okay, quick introductions. I'm Hisham. I've been doing free software for a long time with involved in many projects. I work at Kong where we do free software like free open source API gateway using mostly Lua. I'm currently working on the team that's having web assembly support in Kong and some of my other projects are LuaRocks, package manager, Google Linux, the weirdest distro ever and Htop, the process monitor. So, but here I'm here to talk about like the project that I'm most recently excited about, which is till. Till is a statically typed dialect of the Lua language. Right, so if you know like what type script is to JavaScript, you can think it's the same, right till is to Lua, what type script is to JavaScript, but let's not go too far with that analogy because here we're trying to keep to Lua's spirit, which is like a very minimal, a very tiny language and like I don't have the backing of Microsoft and hundreds of developers working on as they do on type script, but essentially we have a compiler, till that outputs Lua files. And so here's a quick taste of what till looks like. This is just like a random function I picked like from the source code of the latest version of till that I'm working on. And so what's lighter here like is what is not Lua, essentially the parts of till that are different from Lua. So we have a couple of different operators, you can add types there, but otherwise as you can see it's it's mostly regular Lua. I made the mistake of talking about till before without showing lots of search code. So this time I'm gonna make sure I show source code till is like the epitome of like conference driven development because when I first had the idea I started like hacking it together and like when I first presented it like was the challenge like can we do this right? Can we add types while remaining minimal and when I presented it back in 2019 like I was like halfway through like the compiler student compile itself and I show like oh I started like 500 errors and I'm currently like 100 or something like that. But eventually I got it working and then the next year I came back here and show it to you and I said like minimalist type Lua is here and there's this weird title because the language didn't have a name yet. So and then eventually at the third part of the trilogy we had a name and we actually had users and had stuff going actually going on with the language. But and then I basically said that well now I think I'm gonna get let it settle for a bit so that people can actually use it because if the language keep changing syntax like all the time and stuff like that like people won't feel comfortable adopting it right. So yeah so that's what's be going like we have like this small community I always like to make a distinction between like a community and a user base right because especially in the industry people like to look at numbers so whenever people ask me how is still going like I tell him like oh we're like 1.8k GitHub stars which is like the vanity metric like that doesn't really mean anything right but it means something right but in but in practice when I when I think about a community I think about the people who are involved with it and then I could say like like oh there there are like all of the other people who gotten involved right because I'm just doing the source-to-source compiler right and then there's people doing the build system there's people doing like the VS code plugin right that gives like IDE autocomplete those sorts of things so in nowadays for a language that's that's part of the whole package that's what expected of a modern language right so if I if I think on when I think of the two community I think about like I don't know like 10 people or or even less right but the people who regularly discuss on GitHub and all of that so right that that's the community right like the human aspect of it and speaking of community feedback here is like this is a full screenshot of like all of like if you go through all of the issues pages there are currently like if you open the the till GitHub repo right now there's like 67 issues like these are all of them right and I one thing I hate about GitHub is that they call everything issues right so like feature requests like back in the days of search for so we're like separate pages for like bugs and feature requests right and out like calling a feature request issue I think it's like super weird like I would like the program to do something that you did not design it to do now your code has issues right it's like no so basically what I do I label all of them like so the ones with the light labels here are feature requests and the ones with like the darker labels which are like the red ones those are the bugs right so I currently have like five open bugs and like three pages of feature requests right and and it's nice like sometimes you don't want to close your feature request you want to keep them around so that other people who have the same request can see and comment on them right so basically over time your job is going to keep accumulated an endless list of feature requests you're going to look at the repo and one day will have like 200 open issues oh this program must be all broken right no no it has a lot of people who are very interested in it this is actually a sign of success like people are interested in your program enough so that they are using it and asking for more stuff right so yeah so but then once you have this many feature requests like and we're here talking about minimalism how to keep the language small right I cannot add everything that people ask for and this is like my hobby side project currently I don't even have the time even if I wanted to right but I don't want to because I wanted to keep it small keeping to the like that idea from the very first talk like the challenge was how to keep it small right and the challenging thing is like I can't add everything that people ask for or even everything that people contribute because not only people go there and ask feature requests some people actually send in features like all written like a spoil requests like like I would like to do this extra thing and here's the code to do it please add it and I go like sorry right but but it's super important feedback right so uh yeah but when you go go back like it's always nice to look at that whole list and look try to look at the big picture right and then I saw like two like very recurring themes on things that people were asking for like related about like one is like nil safety right the famous uh billion dollar mistake right as as mentioned by touring award winner like 24 when he talked about this uh saying like adding the concept of null to a programming language was back in the day was his mistake because like everything that came out of that afterwards and um and lua is another of those language this does has like a nil type right and all of the consequences come with that uh and the other one is that people keep asking for abilities to express more complex table types because lua is like every like the only single composite type that you have like apart from like integers like like numbers bullions like and like tables right which is a thing that doubles as a hash table and an array right like it's there's a thing with keys and values and if you use numbers the the it has like some special behaviors to make an array access efficient but otherwise just think of it as one big thing with keys and values but once you start talking about types you look like oh this table is really an object this table is really a map this table is really an array this table is really a a map except when you use integer keys then i wanted to act as an array like these are kind of things that lua programmers do all the time because once you have a table that accepts everything right you start having these composite types and all these weird things and but then people mix it up right and those are the bugs that people run into when they're coding in lua with no explicit typing and they would like teal to help them with that right so let's talk about the first one uh a little uh so as i mentioned i was mentioning like giving that every variable can accept nil and you can pass stuff around like that uh until basically every type includes nil as a possible value right if you declare a variable as integer you can still put nil in there like essentially every variable is like optional right and in that sense so this has some consequences right this makes for example that uh in lua like you declare a function to have like three arguments you can just pass one argument or no arguments and like the lua vm will accept it and people do that on purpose because essentially they mean like oh in the semantics of my my application that argument is optional right so uh so lua accepts that and because lua accepts that teal accepts that right and uh another side effect is that in table like missing keys are valid right so um people let's say you define a function that operates on a table that has like x and y uh fields right uh but then your in your program since you decide since you designed that function that just wants to take something that takes x and y you want to pass other things right that have extra fields and sometimes they don't right so uh it gets it gets really messy right uh so in one of the previous talks i mentioned about like that i started looking at like doing the whole thing about uh implementing like nullability checks into the variables and how like and i showed like the size of the teal compiler source code versus the size of like all of the code to do proper reachability tests for null variables and everything and make like the whole check super automatic and it started to get like bigger than the compiler itself uh so that was sort of like a complete but heavyweight solution right so a very lightweight solution or i would say lighter weight solution like then actually having the proper optional types that people really want right was to have just arity checks which is like how many things you actually put inside the parentheses when calling a function right so and yes if eventually we find like a lightweight way to like nicely do optional types this will become sort of a redundant feature but this is this is what it looks like right if you have a function that takes like two parameters like if you pass two parameters then it's valid so if you just pass one parameter this didn't fail before but it will catch the error now but if you pass two parameters and one of them is nil well you know the arity of the function is still two so that's so that's valid right but who will write this right so i mean it's very like 80 20 thing like it's a very simple thing that catches like the kinds of mistakes that people actually do right so you have you kind of have to be uh forcing to to to get into trouble with that so uh yeah but if you want to be able to do that then you act you actually mark the arity like not in the type but in the argument right like the the argument is optional it's not that the type of y is like an optional integer the type is integer but y is an optional argument right so that's like a very simple to implement thing like that i had it i can draft state for a long time and i just decided to put that in into the language because it's always like oh do i want to add one more feature to the language right do i want to because i was able to do like to write the till compiler in itself so with the features that currently has you're able to write a compiler so like i go like okay the features look enough right but people get asking for more features so but then like being possible and being pleasant is kind of different i already feel like like coding in till in general because of the helps that type give you already feels like more pleasant to me as a very in a very subjective way than coding in like plain lua right but when i started working on the next feature like then i really wanted to have this because i wanted to do big refactors and change the numbers of arguments of things and i wanted the compiler to tell me uh if uh if i was making mistakes so i added this feature feature for my own use and it already proved like useful enough and uh yeah so if we're doing that for nil safety for for arguments what about uh for table keys can we do that it's trickier to pull it off right because uh even if you want to say like oh this key is optional this key is mandatory some one thing that people do in lua all the time is just like start a table with like open closed bracket like this is an empty table and start filling the elements one by one so like after the table is ready right that argument's no longer optional but it's optional for a while and it's a very common pattern so um however uh since i had a feature that i created for my own use of how i specify maps i adopted that for records as well so uh which is that total annotation because like lua like modern lua has these annotations like const and and so i just i don't want to say total which is for things like this right if you have an enum saying like which essentially restricts your string type into a set of known strings right you can say that the map that you're declaring here is total so the compiler will give you an error here because you specified north and south but not east and west okay so uh right so essentially we did the same for uh records right so uh you can specify a total record and for that use case of i'm declaring a table and i want everything to be in it uh you can uh you can specify that again like it's a lightweight solution then the whole solution but it's something that already gives you uh you know gets you a long way um okay so uh just because we started late right how how do how do we go on time like do i just keep going and then right okay all right so uh yeah so then the second one which is like the more interesting one is like subtitling table types i mean like i have avoided going with like complicated uh sub typing definitions as as you start combining uh those kinds of features like you can you can go real crazy with that like with even like features that programmers in type languages use every day like if you combine like generics and sub typing like there are computer sign results that show you that you end up with like a computationally undecidable type system and things like that so uh so i have avoided like delving into this complexity for as long as i could so for that super common case of i have this table which is a record in an array at the same time i added this jenki type that's array record that's just for doing that uh and to avoid having to do sub typing and things like that like and complex type hierarchies just because i wanted to have collections like i added like invariant generics so you can have like list of t but you cannot specify anything about t and then that worked and because uh typing and callbacks and passing like checking function arguments for covariance versus contravariant and all that gets complicated you just do bivariant matching you like you accepted both ways which is like wrong like it's unsound by design right but it will at least prevent you from matching like completely unrelated functions like you're not passing like the wrong function but if you're doing the thing like in the correct ballpark it will catch it right so um yeah which is some kind of like unsoundness by design that top typescript already has to do so uh yeah and one big limitation that we have because we had union types but you cannot you could not have union types of multiple table types right because at runtime the code that it translates to when you're trying to check like which which value i have in this union type which is like oh it's a it's an engineer or uh like my record like my object the luo code that that would generate uh became like luo code that says like show check that the luo type is number or check that the luo type is table and then it couldn't tell all the tables apart at runtime right so you will have to generate code that actually checks the tables by their contents right so you can tell like is this a circle is this a triangle is this like what is this right and turns out that in the real world a luo programmer is like an existing luo frameworks that people would want to use with till define their own object or oop like object-oriented systems with their own like inheritance systems and how to how to declare like the the the type checking right people already do this writing this custom code for type checking right but then the till compiler doesn't understand that right so uh for things like this if i want to have the is operator to work nicely in till so that the compiler understand it like i need to be able to translate that to that like framework specific way of determining like what the type is right so since we had records before like the the next version of till is going to have interfaces right so the interface like this was instead of writing record you write interface right but now you can you can actually have subtyping from interfaces which are abstract into records but then you have this fine where clause here which has an expression like it has a bit of code with essentially is like when you want to do an is check this is the code that you should use like it's essentially a macro right you have to replace this everywhere you need to do that change right and now essentially you can do uh you can do union types as long as the all of the types that you are putting in the union declare like there how to do the is operation right and yeah we're only on time so yeah so that's essentially what i described there and the thing is that that that magic where clause right essentially i had to add a feature to add a feature right because like i'm really having i'm having i'm really having to implement like a macro expansion thing for expressions just in order to have that work loss so like why not expose that but then again i thought like oh so i need to add macros to the language no i just went lighter wait again i just added macros for expressions and not like a full macro processor right which is what many projects for lua have tried to do in over the years but one of none of them like have become established right and turns out that where now it's syntactic sugar like we actually have like macro expressions in the language right but it was motivated by that right so in short what happened like till has seen use okay people want more features and less limitations which translates to many future requests oh no right but many future requests they relate to the same pain points right so the idea is that you try to combine them and come up with like the what's the most minimal design to try to address the most of these pain points so the things that came up out of that were like optional iris interfaces macro expressions and the idea was that i would just pick the lighter weight solution right because whenever possible like just to try to like just harking back to the title like minimalism of the language versus its growth right both the growth of the compiler the growth of the language specification and the growth of the user base right so so that's the approach that i took like you know you sometimes you have to choose like the incomplete solution just in order to balance all of those desires right so yeah that's it what i had thank you for sitting around thank you we need to free up the room for the next round but we can still have one or two quick questions Yeah, yeah. So have you decided what to improve the meta programming or doing some stuff, but what the meta tables and all that stuff? Okay. Have you ever decided for a new program or a new country you know the goal with the LAT? If I have some plan to improve the handling of meta tables, meta tables, it currently does have support for meta tables in records, you can specify them. The checks are not very strict, right? And I haven't had much feedback on that. So like if people run into trouble, I look into it, otherwise I'm just going to keep it as it is. Right now you can use them and no one's complaining, so I'm happy with that. Thank you. Thank you.