 So we're gonna start off today with our keynote. Now I am not the keynote today. Every year we try to get maths to speak. Welcome to 2017. Welcome to 2018. So every year like to keep this forever. We weren't sure what year we were gonna end this. We actually just recorded maths saying keep like welcome to keep Ruby weird and then a whole bunch of years after that so that we could we could like play each year. Now this year this year we wanted to try and get maths to record something special for us so that we could play it for the very last year but we weren't able to we weren't able to get him to record anything for us so unfortunately we're just gonna have to do it live. So I want to welcome maths to the stage morning. All right so we're gonna do we're gonna play the little laptop dance here because since this was a surprise we did not test his equipment so bear with us. Morning everyone. I was not supposed to be here maybe. But yeah this is the conference. Keep Ruby weird. It should work. Okay is Ruby weird? What's your opinion? Ruby weird? Yes or no? Yes? Okay Ruby's neutral. Ruby is only abusable. So the Ruby is weird because we are weird. Weirdness in our mind. So we are weird so we program Ruby weirdly so the Ruby is weird. But actually I admit some part of Ruby is weird. So I'm going to talk about this weird thing today. Okay the weird thing is the keyword arguments. In Ruby 2 which was released in like 2013 which is the 20-year anniversary of the Ruby language and then we introduced the keyword arguments. So in keyword arguments we can look at this system something called comments but when we failed we return exception instead of the instead new so that we can provide the keyword arguments like options. The many other language has keyword arguments as well. Like a Python has keyword arguments small has some sort of keyword argument. Object C and Swift for example. So each language is different. For example Python so they don't provide the special keyword arguments. Every argument can be keyword argument in Python. Like this. Okay def foo abc defines the argument named a and b and c so that you can call those functions providing the name of the argument. So you don't have to specify any keyword things in the method definition. You can just call them by name of the arguments. So that we call it the one the c equal 2 b equal 3 that makes the 1, 3 and 2 because the 2 was assigned to the c argument and the 3 is actually the b argument. You understandable? So this is quite a unique Python program I have written. In small talk the keywords are part of the message or a method name. Like this you can put the number 42 at the position 0 so that that works like a RE bracket 0 equals 42 in Ruby. That in this program put an ad is a part of the method name. We often call it the put column ad column. So this is the method name. So in small talk these kinds of keywords are very crucial. It very mandatory in the language spec. This kind of the characteristic of the method name is inherited by the language of object c and swift. But in Ruby keyword arguments are near hash of the arguments. So that you can... P is a method. You know that. P is a method to print the arguments. When you call this P method with the keyword argument you can just print the hash. Weird. Let me explain the background. In Ruby 1.9 we introduce the two things. One is the symbol hash. The second is the expanded hash in the arguments. Symbol hash means the hash like this. The full column 1 bar column 2 instead of the column full arrow 1 column bar arrow 2. This is the simplified version of the symbols as a key. Expanded hash in the arguments means like this. Instead of writing the one column hash we can write the one column inside the brace. So we introduce these things to mimic the keyword argument. In Ruby 1.9 we can put the keyword argument hash as the optional argument. Then firstly put the keyword argument like using the module or something like that. This kind of the manual parsing keyword argument is kind of pain. So that we introduce the keyword argument in Ruby 2.0 to avoid manual parsing. For example to implement the previous one manual argument like this one instead of writing this one in Ruby 2.0 we can do like this much better. That's still weird because what should happen? We define the method m with the mandatory argument a and the keyword argument. The optional default value is 10 and the print the argument a and the key value. So that when we call m key column 5 what shall we get? Yes. Because this is the hash so that this hash is assigned to a and because we have the optional key the default value is given so that we get the hash and 10. In detail you can call actually you can call like this key column 5 as hash with the key column hash the a called key column 5 and the key axis is empty so the default value is used then we get the hash and 10. Yeah it's easy right? So the popular too what should happen? Okay h is the hash then print the hash you get hash what should what would happen when we call the m with h it's easy too it happens like this because the keyword argument is the hash at the bottom the argument list so it'll be considered as the keyword hash so the keyword argument is used then key will be 5. Easy. Yeah keep going. What should happen here? Okay we have the optional argument which default value is the empty hash then the keyword argument which is default to 10 then when we call the key column 42 what should happen? 42? 42 10? The answer is like this because the keyword arguments were bound before the keyword optional arguments so the these keywords are considered as the real keyword arguments so that the key will be 42 then we don't have the optional argument so the default value is used the empty hash and the 42 is the answer we I keep going so that we have the optional optional argument which defaults to 42 and accept the keyword argument as hash and then print them so when we provide the empty hash and the empty hash is the keyword argument what shall we get? Two empty two empty keyword arguments the correct answer the answer is like this because because the expanded the empty keyword hash will vanished we'll be vanished because it's empty right and then we have the only one empty hash at the bottom the keyword arguments and the callee interpret this as a keyword argument then we don't that callee don't see the optional arguments so that it's assigned to 42 then the keyword empty keyword arguments it's kind of insane you know it was it works mostly okay but we have some weird corner cases and they're kind of confusing with the hash and the keywords but that yeah I can say it is half big solution at most and then yeah the ruby design or the design of the anything like including programming languages uh kind of difficult we have a lot of the constraint and restriction and then the biggest one is the compatibility matters so that it is it is tempting for us language designers to fix the errors like like like the above but the changing behavior changing existing behavior might cross the existing software that that's not very hard for users for example so that in age of the ruby one eight and one nine so that I had to introduce some kind of the possibility to the language because of the unicode support and the virtual machine the beta virtual machine and then but you have to migrate your your application from ruby one eight to ruby one nine so that it is in some case it is this kind of burden so that some people kept using ruby one eight four four years maybe five years or something so that we had some kind of the community division for years by this kind of the compatibility issue and then in worse the the people in python community had that kind of the division uh the python two people and the python three people for more than 10 years and then they declared that the end of the life of the python two in year 2020 which is two years ahead so that yeah python three was released in I don't remember exactly but probably the 15 years ago so that they are nearly 20 years of the community division this is quite unfortunate it's a kind tragedy yeah and then yeah we have four five per six this is a different story the per six is totally different programming language anyway so we had some kind of tragedy in many programming language communities so that you don't like the code breakage you know you you love to upgrade your software your your language but that you don't want to fix or modify your application to just to just upgrade your language but at the same time you don't like the confusing behavior like that so which you hate me more this is the trade off this is the trade off code breakage or confusing behavior so the compatibility issues is very big like a you know that kind of the small change could break your software for example we have the spam method which takes the the hash as the the arguments but that these hash can include the 10 to 11 which we map the the file descriptor which key is not the symbol so which cannot be the keyword arguments or like this example is the the very boilerplate example of the create elements of the hdmi file it's this is kind of like a dsl so that take the name and attributes right this is quite easy but if you want to add the new keyword argument children to to express the children of the hdmi tree but this time this hf is not the keyword arguments so that we get the this kind of the argument error we have we surely we will have some kind of the compatibility errors unexpectedly when we fix anything so what shall we do we have several options uh we have three i i will put i'll explain you about the three option to the keyword arguments the first one is a keeping keyword argument weird as it is uh out there the the second is the key the something we're introducing something named the keyword hash just the third one is the totally separate the keyword arguments okay let me explain one by one the keeping keyword arguments weird like as they are is we have pros and cons it's a trade-off so the since we don't change anything so we will not have the compatibility issue this is great but uh we have the drawbacks the keeping above confusing behaviors it is quite amusing but confusing and then the second option is introducing keyword hash that means the uh expanded hashing arguments will be the keyword arguments this is a kind of an example okay the take the keyword arguments okay a cone one is expanded hash argument in the argument list so that the take the keyword arguments then the say you can tell this is the keyword are not keyword arguments are not so that we when we call this form about form you can get that this this is the keyword arguments and the second form is the you know the the hash wrapped in the braces so that it would be not it would not be the keyword arguments so then and then we prohibit the known keyword expanded hash like you know the one arrow something things without braces so that we usually see that this one will be error and then instead use this they were wrapping in the braces so there's always a trade-off so the pros is that the this thing is relatively simple the difference between the current behavior and the new behavior is minimal so that relatively easier to implement and then the transition is easier than the the lot of runs and a simpler argument delegation that means that okay when you delegate the argument to the different method currently we do this that takes the argument splat then they take the block as an argument then delegate these arguments and blocks but with the separate keyword arguments we had to do that okay we have to delegate the keyword arguments so then yeah in my opinion two things is annoying but okay but three three things is too much three things are too much uh the this okay counts for the keyword hash has the of course the the compatibility issues especially the known keyword expanded hash in the arguments and any behavior change would cause the error in applications and then especially expanded hash is and especially makes ones and then keyword hash can be leaked that this one is the the leaking keyword arguments so the the foo returns its keyword keyword hash assigned to the the variable kw then calling bur with the keyword hash cause uh much is the this this keyword arguments and returns one this is kind of confusing but then yeah i think it's sortable for most of the users and then the the biggest drawback of this option is it is hard to optimize you know you have to allocate one hash per call when you call use the indeed uh keyword arguments but uh there there can be a room to optimize but uh this kind of keyword hash requires the hash object in your software that means that you have to you must allocate one hash per call the the last option is introducing the separated keyword arguments the keyword arguments never match with the normal arguments so the prohibit non keyword expanded hash is that is the you know the benefit of this option is the most same behavior we can eliminate these kinds of confusing behavior of the current keyword arguments it yeah at least less confusing and then there is room for optimizations but uh it also has a drawbacks and then it is it would be the huge compatibility in compatibility i mean and then the behavior change will be bigger when we choose this option so that like uh and the argument delegation must be like this instead of this so that we have three options as i explained key keyword arguments weird like us there uh and now did this confusion is the very corner cases but uh yeah we can ignore or maybe we can introduce the sometimes the keyword hash and which introduce to uh which can solve uh these weird behavior using the information the the last one is the keyword hash or not the the last and then the biggest option is the separate the keyword arguments all together okay do you understand the three options okay you do okay think about 30 seconds think about them uh this is the option these are the options keep current behavior as it is and introduce the keyword hash to distinguish the hash add i mean the keyword arguments as a hash and the normal arguments and the third one the third one is the separate keyword arguments all together to by fixing the language themselves uh the they are trade they have trade off the the first one is no we don't pass them we don't change them we can keep compatibility of course but uh we keep these kinds of confusing behavior first one and then the second one can solve many confusing behavior but and simpler but uh it's kind of primitive like you can see the keyword argument hash as an object as an object and then the the last one is most sophisticated but it is a little bit more complex to implement but there's a room to optimize the performance okay these three options okay you understand that okay raise your hand so that uh i'm pretty interested in your opinion so that if you have uh you prefer the first one unchange keyword argument uh raise your hand if you prefer first one confusing but that's compatible okay uh maybe i don't know one third of the users or more oh yeah it's it's more than i expected okay thank you uh the but this conference is the key will be weird so that yeah it's complying to the theme okay the gay did you make your mind gay how about you prefer the second one one two three okay very few of them but not not less more than 10 person 10 people i prefer the second one okay how about the last one most sophisticated one oh it's more than i expected you love the changes courageous okay thank you this is great variable input for me in any way uh i tell you avoid non keyword expanded hash in your in your lobby program and then yeah the when you get back home so that yeah fix them uh in summary uh compatibility is pretty much important because you know the if your your language or your library or your framework or whatever the third party thinks breaks compatibility you will be punished for no reason right it's it's kind of pain so that don't do that unless you have very uh a parallel reason uh changes are very tempting yeah i it's it's tempting for me to break the language every day it's it's quite tempting yeah if i change this behavior and break the compatibility i can make this the ruby language far better than the far better or something like that i i feel every day i don't do that usually because i i'm not going to punish you guys for using ruby you know the keeping compatibility itself is designed so that now the programmer is fundamentally designers so that you design your software i design my software my i design my language and then your users of my language okay you use my many gems and then the gem gem offers uh designers and then you create your applications your uh users of your application it's you know the it's it's kind of layered the the higher layer uh author can punish their users for no reason but uh don't do that it's quite tempting i admit but don't do that for no for no reason okay uh we have uh weird design in our language and even our application or library or something like anything for example we have the weird keyword arguments but there are reasons there are there are reasons we have constraints we have uh the restriction we have historical reason or anything but and uh you can fix them but we have trade-offs that we can easily fix them by punishing my users or we can fix them but providing some kind of migration path to the future version or something like that and then ruby three may address keyword weirdness but um i don't know yet but i'm making up my mind by from your body of input and then but at least at least we can tell we promise to keep keep moving forward because you know ruby is not really the language the mere language and ruby is the community okay ruby cannot be ruby without you the community so if no one use ruby and so there are you know there is virtually no ruby the ruby can be ruby uh along with gems frameworks your applications and the you users your programmers the these are very valuable for the ruby the community so that you know we don't have any initiation to the ruby community and we don't really have the membership of the ruby community you don't have to decree you as a ruby community member in any sense you just use ruby you just like ruby or maybe even you love ruby whether you don't have to declare anything so that that means the ruby cannot expect you community members a loyalty so that you can you can leave when whenever you want you can go to say python javascript uh elixir whatever if we want so that that point is we the ruby community the the virtual existence ruby community have to provide you some kind of attraction so that that means if all your open source software we have to make language better or make language community ecosystem better by providing tools gems frameworks use cases or maybe some blog path or anything we have to attract people this is crucial and then on the contrary the punishing users by providing uh by introducing some kind of incomparability can be paying for the users and it can be motivation to leave but at the same time the the change will attract people for for providing better language so that we it's it's quite difficult forecast but uh we try our best to move forward at least we move forward to provide the better things better language better community to let you play with ruby so that find out the weird things and then play with the uh the ruby behavior and they keep ruby weird and then writing your applications and then I believe playful mind is the core of the ruby so that I declare I will keep ruby users weird yeah this is my sometimes up you know see my mystery talk and then this is the end of the talk thank you thank you mats I enjoyed your presentation I like the the ideas around changing the hashes I think that all of them have very like all the different options have very good uh arguments I think I think we have some time for questions does anyone want to grill mats on stuff like his production code yes oh you're at the opposite side of the I'm coming I'm coming can you talk about an interesting breaking change that you wanted to make that you haven't the the one thing is the I the thing I abandoned four years ago was the the changing the changing the scope of the local variable uh in ruby the local variable the local variable this is scope is limited to the block or the the method or the class the in which the the local variable is first assigned but uh in many cases so you want to use the local variable out of the block for example like a you know you find some uh object in the loop so you use the that object out of the room so in that case in current ruby you have to assign the that variable first the local variable equals nil then assign to the the variable in the in the loop then use the variable after the route right but uh I try to introduce the some kind of the scope hoisting like in javascript does so that if you use that local variable out of the block so you can declare the the block scope one step out one step broader so that you don't have to assign the local variable equal nil at the top of the loop but uh uh yeah when I first think of that that idea it is it was good but uh after that it is kind of confusing so that I just abandoned the idea I had the I had those I have a long list of these kinds of crazy ideas and uh I abandoned most of them uh thank you I guess making that change was too too too big a scope thank you thank you for providing us visibility no no this is Friday morning uh questions more questions questions I think we have we have some time so preferably somebody in that corner so I can run to the complete other side of the room anyone okay I guess oh wait was there one down here no all right let's end this thank you matt thank you