What If... ?: Ruby 3
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Number of Parts | 69 | |
Author | ||
License | CC Attribution - ShareAlike 3.0 Unported: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this | |
Identifiers | 10.5446/37812 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
00:00
Inheritance (object-oriented programming)Multiplication signFlow separationSummierbarkeitXMLUMLComputer animation
00:52
MereologyPoint (geometry)SequenceTrailBitMereologyMachine visionPresentation of a groupRandom matrixQuicksortTraffic reportingSpacetimeData storage deviceComputer animation
01:59
MereologyClient (computing)Binary codePoint (geometry)NeuroinformatikMultiplication signUsabilityMeeting/InterviewComputer animation
03:01
WebsiteTwitterInformationHash functionComputing platformFlow separationMultiplication signContent (media)CuboidCodeGreatest elementComputer animation
04:16
Slide ruleSlide ruleType theoryBitFluid staticsPhysical systemView (database)Social classWeb browserConnectivity (graph theory)Computer animation
05:02
Disk read-and-write headLine (geometry)Rule of inferenceUniverse (mathematics)Power (physics)Musical ensembleYouTubeMultiplication signOrder of magnitudeEndliche ModelltheorieComputer animation
06:20
Integrated development environmentType theoryConcurrency (computer science)Multiplication signContent (media)Projective planeRevision controlStiff equationEndliche ModelltheorieGoodness of fitBitMereologyConcurrency (computer science)Type theoryIntegrated development environmentObservational studyGroup actionComputer animation
07:35
MereologyDifferent (Kate Ryan album)Programming languageBitFormal languageComputer animation
08:12
MereologyFluid staticsTypsystemVariable (mathematics)Type theoryString (computer science)InferenceAerodynamicsSymbol tableType theoryPhysical systemCompilerFluid staticsDynamical systemString (computer science)Message passingPower (physics)Dependent and independent variablesRun time (program lifecycle phase)Contrast (vision)TypinferenzNumberSymbol tableMultiplication signOperator (mathematics)Process (computing)Computer animation
09:22
Data conversionVulnerability (computing)Type theoryQuicksortArithmetic meanCrash (computing)Error messageComputer animation
10:02
CodeParsingAlgorithmBitRule of inferenceComputer fileNatural languageMultiplication signNumberInterpreter (computing)Type theorySequenceCodeMessage passingVirtual machineParsingString (computer science)Derivation (linguistics)ParsingSystem callIdentity managementFormal grammarCompilation albumResultantFlagToken ringFunction (mathematics)RippingMetadataPatch (Unix)FrequencyPhysical systemMereologyMachine codeLetterpress printingLine (geometry)Hash functionBytecodeGraph (mathematics)Formal languageComputer animation
12:06
Block (periodic table)Local ringRegulärer Ausdruck <Textverarbeitung>BitType theoryBytecodeInformationDependent and independent variablesRun time (program lifecycle phase)CodeConstructor (object-oriented programming)Computer animation
12:40
Type theoryWordINTEGRALFormal languageComplex (psychology)CompilerCore dumpBitContext awarenessTypinferenzQuicksortRapid PrototypingProgrammer (hardware)Line (geometry)Loop (music)Virtual machineCodeComputer animation
14:20
Database transactionElectronic mailing listType theoryNatural numberDatabase transactionFormal languageElectronic mailing listType theoryPhysical systemNumberComputer animation
14:57
Database transactionParameter (computer programming)Constructor (object-oriented programming)Electronic mailing listImplementationType theoryNatural numberLengthElectronic mailing listDatabase transactionString (computer science)CountingImplementationMultiplication signWebsiteIntegerRange (statistics)Negative numberPasswordCompilation albumMereologyPhysical systemRight angleCodeNumberSoftware testingGoodness of fitRun time (program lifecycle phase)Logic synthesisComputer animation
15:53
Natural numberTypinferenzJava appletCore dumpType theoryCompilation albumWeb pageRoutingParameter (computer programming)CompilerException handlingMereologyCondition numberCodeFormal languageMultiplication signRoundness (object)Particle systemDecimalInterpreter (computing)Covering spaceProcess (computing)NumberGoodness of fitDampingComputer animation
17:28
MathematicsAerodynamicsProgrammer (hardware)Computer programmingMeta elementType theoryNumberMathematicsUsabilityRun time (program lifecycle phase)QuicksortRevision controlMultiplication signArithmetic meanShape (magazine)Physical systemGoodness of fitProgrammer (hardware)Formal languageComputer programmingPointer (computer programming)Software developerError messageFluid staticsCompilation albumObject (grammar)Software testingPanel paintingComputer animation
18:59
Web browserMereologyVideo game consoleSource codeElement (mathematics)Digital filterQuicksortWeb browserPhysical systemFunctional (mathematics)ParsingQuicksortGoodness of fitSubject indexingNumberBit rateValidity (statistics)Cursor (computers)Formal languageJava appletConnected spaceScripting languagePrimitive (album)Parameter (computer programming)Process (computing)Integrated development environmentHypermediaSource codeIntegerString (computer science)Line (geometry)Medical imagingMultiplication signComputer scienceCompilerWritingInternetworkingWeb pageRight angleMereologyInterior (topology)Level (video gaming)Video game consolePivot elementConcurrency (computer science)Type theoryComputer animation
22:30
SoftwareQuicksortProjective planeProcess (computing)Scripting languageForm (programming)Web browserFormal languageFront and back endsSocial classVirtual machineCodeServer (computing)Client (computing)Computer animationLecture/ConferenceXML
23:45
MathematicsServer (computing)Control flowIntegrated development environmentWeb browserHash functionScripting languageJava appletIntegrated development environmentWeb browserMereologyTerm (mathematics)Reverse engineeringQuicksortServer (computing)Reading (process)Compilation albumLine (geometry)RoutingGame controllerScripting languageDialectWritingProcess (computing)SummierbarkeitProjective planeNear-ringKey (cryptography)System callPrice indexWeb 2.0Computer animation
25:26
MereologyConcurrency (computer science)Term (mathematics)Interpreter (computing)Rule of inferencePrimitive (album)Parallel portThread (computing)MereologyMobile WebComputer animation
26:03
NumberInterpreter (computing)Thread (computing)Wechselseitiger AusschlussConcurrency (computer science)Local ringCondition numberMereologyInterpreter (computing)Web browserTerm (mathematics)Formal languageThread (computing)Concurrency (computer science)Wechselseitiger AusschlussHash functionOrder (biology)Social classMoving averageExtension (kinesiology)Vector potentialBasis <Mathematik>Food energyRegular graphMultiplication signComputer animation
27:53
Concurrency (computer science)Parallel computingCondition numberThread (computing)CodeConcurrency (computer science)ResultantParallel portEncryptionProcess (computing)Arithmetic progressionMultiplication signContext awarenessMultiplicationVirtual machineSequenceReading (process)State of matterArray data structureDifferent (Kate Ryan album)QuicksortPrimitive (album)Flow separationThread (computing)Condition numberHash functionRoundness (object)Core dumpShared memoryComputer animation
29:47
Surjective functionQuicksortThread (computing)BlogData managementDifferent (Kate Ryan album)Parallel portConcurrency (computer science)Multiplication signCAN busState of matterBitTerm (mathematics)Mass
31:12
AbstractionConcurrency (computer science)Thread (computing)Algebraic closureMathematicsParallel computingBefehlsprozessorPrimitive (album)Software developerFormal languageJava appletMessage passingConcurrency (computer science)Functional (mathematics)Core dumpPlanningTwitterAdditionThread (computing)Parallel portComputer hardwareOverhead (computing)Database transactionSoftwareSemiconductor memoryProcess (computing)BitMathematicsCoprocessorLine (geometry)Physical systemMultiplication signCodeType theoryProgrammer (hardware)Universe (mathematics)Asymptotic analysisVirtual machineNatural numberEndliche ModelltheorieConnected spaceFinite setOperator (mathematics)Level (video gaming)Fiber (mathematics)Algebraic closureRow (database)Theory of everythingGroup actionState of matterFrequencyDecision theoryCellular automatonComputer animation
36:48
Type theoryIntegrated development environmentParallel computingConcurrency (computer science)Hash functionConcurrency (computer science)Different (Kate Ryan album)Type theoryNumberRandom matrixComputer configurationSoftwareThread (computing)Computer hardwareTerm (mathematics)Code2 (number)Source codeDatabase transactionWeb 2.0Projective planeMultiplication signCompilation albumPrimitive (album)Particle systemSemiconductor memoryQuicksortIntegrated development environmentParallel portAdditionComputer animation
38:00
Coma BerenicesComputer animationMeeting/InterviewXML
Transcript: English(auto-generated)
00:11
So I think we'll go ahead and start. First, thank you so much for coming. I really appreciate your choosing to spend your time here with me, coming to see my talk. There's a bunch of fantastic talks that are going on.
00:22
So thanks so much for choosing this one. And thanks also to RubyConf, to our sponsors, to the venue, to New Orleans. Thanks to everyone who helped make another RubyConf possible. As always, I'm super delighted to be here and I'm delighted to have you here. I apologize that I can't really see any of you. It is unbelievably bright up here.
00:42
But, you know, well, you'll see in a minute why I do need to see at least some of you. So this talk is called What If Ruby Three. But it's also known as the Future of Ruby, Part Three. The Futures.
01:01
So this is designed after one of Justin's slides. So this is the third part of a three-part talk track sequence on the future of Ruby. So we've sort of seen the past. We've seen some of the present and apocalyptic visions. And now we're gonna talk a little bit about what Ruby could have been like
01:23
or what it still might be like. And we're gonna do things a little bit differently than the way I normally do talks. I normally rely very heavily on presenter notes. I oftentimes will inadvertently read rather than talk to all of you. So on Justin Searles' advice,
01:40
I'm forgoing presenter notes entirely and we'll see how that goes. Yay! Also, that's actually excellent. If at any point I just start trailing off or lose my space, just start applauding. That would be really helpful for me. It'll give me a minute to reorient. But I'm delighted not to just be friends with Justin.
02:00
I'm also a client. And what that means is, Justin has to buy me fancy dinners now. Anyway, so this is a computer talk, it turns out. And that means you have to start with zero. So hello, my name is Eric. I tend to speak very quickly,
02:21
particularly when excited. And I find talking about Ruby and the future possibilities that Ruby and the community have to be really exciting. So if at any point I start to go off the rails, pun intended, and speak way too fast, and this is why I kind of need to see some of you, especially those of you closer to me in the front, just kinda like, or maybe something to give me a sense
02:41
of ease it back a bit, and I will slow down. I'm gonna talk for between 35 and 40 minutes. If we come closer to 35, we'll have a couple minutes for questions. If we come closer to 40, then I won't have time for questions, but please feel free to stop me after and ask me any questions or we can chat about anything that you would like.
03:02
So like I said, my name is Eric Weinstein. I am a director of engineering at Fox Networks Group in Los Angeles. We're currently building a platform and a team around the content APIs around our television content, which includes The Simpsons, Archer, National Geographic, which a lot of people don't know, Fox Sports, and more.
03:21
So we are hiring. Please feel free to ask me about that as well. All of my information is in this human hash I felt compelled to make. I write a lot of JavaScript and Node at work, but I write Ruby in my, well, not as much free time as I would like to have.
03:40
I've been writing Ruby for several years now, and I recently wrote this book, Ruby Wizardry. I've been saying recently, I guess it's not so recent now, it's about three years ago, which means we're due for an update. But it's hard to see at the bottom, but there's a 30% off promo code, RubyConf30. If you go to nostarch.com, that's the publisher's website,
04:00
and you enter that promo code, you would get 30% off the book. So if you're interested, please go ahead and do that. And thanks so much to the folks at No Starch for setting that up. The book teaches Ruby to eight to 12 year olds, but if you have questions about that, please do come find me after the show. This is not a long talk, but I do think we benefit from having a roadmap.
04:22
So I'm gonna start by talking a little bit about Marvel's What If comics, then the power of narrative and meta-narrative, and we'll finally look at some of the possible futures of Ruby through three What If stories. What if Ruby had a static type system? What if Ruby ran in the browser? And what if Ruby did not have a global VM block?
04:46
So like I said, I'm gonna do my best not to read to you, small classes, small methods, small slides. And hopefully the meta-narrative component, which you'll see in a minute, is entertaining and not like Clint Eastwood yelling at an empty chair.
05:02
So what if? So if you're not familiar, the What If comic line from Marvel, they did two separate runs, are basically non-canonical stories about the Marvel universe. What if the X-Men had been founded by Professor X and Magneto together? What if Jessica Jones had joined the Avengers? What if the Avengers defeated everybody,
05:21
which I feel like is maybe like, not the most interesting question, but I would read that. I would definitely read that comic book. So actually I probably did. So basically, what if things were different than they are now, subject to the rules of the universe? Like what if the history and the potential futures were different?
05:40
And What If is a powerful question that is deserving of powerful music. And I had wanted to use Marvel's fanfare, you know, the ba-na-na-na-na-na-na-na, like the really, someone's mutant powers are activating or they've put on their costume for the first time. But then I remembered that this talk will be on YouTube and I did not want Marvel to yell at me. So I've picked a different music.
06:06
I'm actually gonna play that one more time just because I like it so much. Does anyone happen to know off the top of their head what that is? And again, apologies for not being able to see you. I can't tell if hands are raised, so just feel free to shout if you know. If you don't, it is actually the Bloopsaphone theme song.
06:23
So if you're not familiar with Bloopsaphone, it was a project by Why the Lucky Stiff. You know, there's been a lot of good content today about the history of Ruby in our community. Why was a very big part of that. His projects were a very big part of it. So I'm delighted to be able to share a little bit of his content.
06:41
And if you have questions about Why, I never met him, but I've studied him. Or if you have questions about how things used to be or Bloopsaphone or whatever, please do come find me or another grumpy old person. So, Ruby three by three. So Matt said this morning, the goal for Ruby three is to be three times faster
07:02
than Ruby two. And I do think that we will get there. But there's also a question of what else we'll get. We saw there are gonna be some new features in Ruby two five. Every Christmas we get a new version of Ruby. It's exciting to think about what could ship in Ruby three. And so as I said, we have these three what if scenarios focused around types, around Ruby's execution environment,
07:23
and around its concurrency model that I think could be really interesting. And it's possible that people will look back on this talk and say, this was truly the beginning of Ruby three. Good, I'm glad this part works. Feel free to read that in Ron Howard's voice
07:40
if it helps you, it helps me. And thank you for laughing. Also if it helps, if this seems a little bit new and weird and strange because this is gonna be Ruby that doesn't quite look like Ruby, feel free to think of it as a different programming language. I don't know how many of you know this, but back in the day when Matt was selecting
08:00
the name for Ruby, he narrowed it down to two, and the other was Coral. So if you want to pretend you're at CoralConf for the next 33 minutes, if that helps, please do. So, let's start by talking about Ruby's type system. And what if Ruby had a static one? So static and dynamic type systems differ
08:22
in the fact that a static type system, in a static type system, all the variable types are known at compile time. So whether you have a fixnum or a string or a symbol, when you compile it, you know. You're not going to have something not responding to a particular message or method at runtime because you know what type it is
08:40
and you know what methods it responds to and what messages it will accept. This may or may not make use of type inference, so if you've written a lot of Java, you'll see you're constantly indicating what type everything is. If you've written Go, then you're aware that you have a powerful type system that doesn't require you to specify the type. Sometimes the compiler won't quite know what you mean and you'll tell the compiler, when I'm doing this,
09:01
here's the type that I mean. But generally speaking, it's smart enough to figure out what you want. This is in contrast to dynamic type systems where the variable types are not known until runtime. So you can have something blow up because you've tried to call each on it and it's not an enumerable or you've tried to add two things together that don't respond to the plus operator,
09:21
things like that. And further, there's this notion of weak versus strong typing. This one is much more contentious than static and dynamic typing, so please don't at me to tell me that I've erred totally in my distinction. So the idea here is that for the purposes of this talk, weak typing is does not secretly do the wrong thing
09:42
instead of throwing an error, JavaScript. And strong typing is throws an error rather than secretly doing the wrong thing. So according to these definitions, Ruby would be strongly and dynamically typed. And to understand what we sort of mean when we think about Ruby types, I'm just gonna do a quick crash course through YARV,
10:02
yet another Ruby VM, which is the VM that modern Ruby uses. And the steps, broadly speaking, are tokenizing and lexing, picking apart your string of code to figure out what pieces are in it, parsing it to figure out the grammar and what should happen, compilation to byte code, so we convert from human language to machine language,
10:22
for some definition of machine language, and then we execute. You type 10 times do a thing and we do that thing. I apologize, this is a tiny bit hard to read, but at the top you have 10 dot times do n, we puts n, and we end. So we'll just print out the numbers one through 10.
10:42
And here you can see below, this is the result of calling the, I wanna say it's the lexer method. So Ripper is a tool that ships with Ruby. You can use it to pull your Ruby code apart and sort of see how it's built and what it does under the hood. And so here you've got not just tokenization where you can see all the way on the right, you know you've got 10 and then dot and then times,
11:01
but you also have this metadata associated. It's that middle column, on int, on period, on ident. And so this is what Ruby has, this is what YARV has seen when you've typed 10 times do and puts n. The parser in Ruby, as far as I know, uses the LALR, or I think look ahead,
11:22
left reversed right most derivation parser, which effectively says go from left to right, look a little bit ahead if you need to disambiguate what rules you're going to apply from I think it's the parse.y file. You can actually see what the parser is doing if you pass the y flag to the Ruby interpreter. So if you do Ruby-y example.rb or whatever your file is,
11:41
you'll get a lot of output indicating what the parser is doing. And both of these examples come from Pat Shaughnessy's book Ruby Under a Microscope, which if you have not read it, I cannot recommend highly enough. Is this speed okay? Great. And then if you want to look at the YARV bytecode, you can call RubyVM colon colon instruction sequence
12:01
dot compile, pass in your string of code, and then call disassemble on that. And again, apologies if this is a bit hard to read, but you get your bytecode instructions. Now the interesting thing here is there is really not a lot of type information. Ruby is not statically typed as we're going to Ruby bytecode.
12:22
There's really nothing that will prevent you from calling a method on something that doesn't respond to that method at runtime. There's nothing about YARV that will say, hey, timeout, you're trying to call plus on something that doesn't respond to it, you're trying to call this method, and that's a bad idea. Things will just blow up at runtime. Now there are ways to fix this.
12:42
I don't know if any of you are familiar with this logo. I think by itself it's a little bit enigmatic. This is absolutely not something that you should do. I mean, you can do the second one if you want. Actually don't know if you can brew install Ruby. So Crystal is the language that has that logo. And Crystal is very, very similar to Ruby syntactically,
13:02
but it is statically typed. And I think it's fast as C, slick as Ruby is the tagline for the Crystal language. So if you're interested, I think it's crystallang.org. But if you just search Crystal language, you'll find it. And this code actually works both in Ruby and in Crystal. So the Crystal compiler and the YARV virtual machine
13:21
will both understand what you want and will create accounts for you. The interesting thing here is that Crystal does leverage that type inference that I talked about. So you occasionally have to tell Crystal, like I mean this when I tell you this variable is used in this context, it has this particular type. But oftentimes you can omit the type annotations.
13:40
And one of the things that I think is really interesting is that you can have something that is statically typed that looks just like Ruby. So we could, if we wanted, create a Ruby compiler and have statically typed Ruby, we would give up some metaprogramming magic. We would give up some of our rapid prototyping loop. We would be sort of sacrificing programmer speed
14:00
for execution speed. And whether or not that's antithetical to the core tenets of Ruby, I think is something that is up for debate. Certainly I think there's a role for more complex type behavior. And so what I'm thinking of here is a language called Idris that I have contributed a little bit to.
14:23
Idris is a dependently typed language written in Haskell, based on Haskell. And what I think is really cool about its type system is, so I've just made up this get transactions method or function, just gives you a list of nats. And nat might not be a type you've seen before. And nat is just a natural number.
14:42
You know, it's a non-negative integer. I don't know why I said get transactions and picked these numbers. It just came to me. But the interesting thing is that you have this list of natural numbers. And so if you call get transactions with these numbers, everything is fine and Idris does not yell at you. If you use these numbers, starting with the negative four,
15:01
Idris does yell at you and says, I was checking the right hand side of get transactions and I was told that this would be a list of natural numbers. But I don't have an implementation for negative natural number. So the interesting thing about dependent types is that dependent type also has an understanding of the values. So it's not just list of a,
15:21
but you can have list of a in this range of values. You know, list of integer greater than zero. List of string with length three or more, right? You can't count the number of times you've written tests for the password part of your website where you're like, oh, the password has to be at least eight characters. You can actually encode this in Idris's type system and say, this has to be a string
15:41
and it has to be at least this many characters long and if it's not, your code does not compile. So catching that at compilation time rather than at run time, which I think is extremely interesting. So interesting, in fact, that I wrote some not very good Ruby code to emulate it. So I can share the gist after this talk.
16:00
The part I kind of want to call your attention to, this is identical to the account code from before, except I've added this type method that says, look up this method, it should return a natural number and if it does not, throw an error. Deposit should take a natural number and give you a natural number. Withdraw should do the same thing. I don't know why you would pick natural numbers
16:20
because you probably want to be able to overdraw your, well, you don't want to overdraw it, but you would like to have that opportunity or you might want to, I don't know, have decimals or something, but if you pretend that your account always has seven or 10 or 15 or however many integer dollars, natural number dollars, this will catch it for you. So again, this is not any modification
16:40
to the Ruby language, so there's no compilation step. This is really just enforcing pre and post conditions to say, hey, timeout, you told me that this would be a natural number and you gave me a negative number or float or string, et cetera. If we did want to modify Ruby's core language, we can change the way we do type annotations
17:01
and we could say, hey, you know, this is an amount and it's of type natural number. Or we can kind of go more Java E route and say natural number is the type and the argument is amount. Or we can say it's a float, or we can kind of take a page from Crystal's book and say, you know what, the interpreter, the compiler is smart enough to figure out what this is.
17:21
Let's just use type inference and really only disambiguate when we need to. So the question here then is, is this a good idea or a bad idea? I happen to think that having stronger static types is a good idea. I catch a lot of errors at compilation time
17:44
and the number of times something has blown up at runtime because something was nil or I was not thinking about the shape of the data or the correct type. I do think that there's room to make these kinds of improvements. So Matt's talked this morning about good changes and bad changes. And I guess the question here is really about trade-offs.
18:01
If we keep dynamic typing, we trade execution speed for programmer speed, potentially developer happiness, we lose some flexibility and we lose some metaprogramming magics if we get rid of dynamic typing. We keep those with the Ruby that we have now. Static typing means that our programs will run faster, but we give up some flexibility
18:22
for the safety of compile time checks and knowing that something is going to be a particular type at runtime no matter what. And with dependent typing, the kind that we saw with Idris and with my example of the account, we trade flexibility for sort of these ultra-powerful compile time checks, which may be unnecessary. May mean we write a few fewer tests.
18:43
Again, it's a trade-off and I think that the answer is going to be somewhere in here. So that's what if Ruby had a static type system. I suspect something like gradual typing could sort of ease its way in in a future version of the Ruby language.
19:01
So now we'll kind of pivot and say, okay, well, types aside, what if Ruby ran in a different environment? What if Ruby were to run in the browser? Browser, that's good enough. For those of you who don't remember, this is Netscape Navigator and this is what the internet used to look like
19:23
and in some places still does, such as on the about me pages of computer science professors everywhere. But this would be cool, right? Like this would be amazing. We could pop open the console and not have to do a bunch of hacky editing in preview and get, you know, so for those of you who are not familiar with the magic of %w,
19:42
we get an array of strings, the strings one, two, three. We call map and we say, I actually want all those to be integers and integers come back out. For those of you who have written JavaScript, this is more along the lines of what happens. We try the first one and it doesn't work and actually I did not understand
20:01
why this doesn't work for a long time. It turns out in JavaScript, if you call a method on an array and it's supposed to have two arguments but you only pass one, it will use the index as the second one. So what it's saying is, I have one. I'm gonna parse int that with a radix of zero. That's basically like not passing radix so we get 10 which gives you one which is the right answer.
20:22
The second one is two but we're using base one which is not a valid base so we get not a number which is a numeric value that is not a number. And then for three, we get the same thing but two, three is not a valid value for a base two system so we get not a number again. So basically the way to fix this
20:41
is to pass an anonymous function and say I actually want you to parse this number and use 10 as your radix. Now you probably could get away with writing your own parse int that kind of partially applies parse int and just automatically says if there's no radix, it's 10 but that's a lot of work. It would be really nice if we could write Ruby in the browser.
21:01
And the question is why isn't that a thing? Why doesn't that exist? And technically it does sort of. So for those of you who have not seen this logo before, this is Opal. Opal is a source to source compiler for JavaScript so it converts Ruby to JavaScript and then executes the JavaScript in the browser.
21:22
And we can imagine a world where we have tools like this but we don't actually have to go through the pain of JavaScript. We can actually just write Ruby and run it in Chrome, Safari, Firefox, whatever browser you like. But I think the question we should think about is if we had Ruby in the browser, would we all be a lot happier
21:40
or would we complain about Ruby the way we sometimes complain about JavaScript? Would we, what is this language? Why is it dynamically typed? How come this happens and how come this, really is it the environment or is it the language? How different would Ruby be from the beginning? It were designed to run in the browser and deal with HTML and be sort of this asynchronous first language.
22:03
How different would their concurrency primitives be and how different would parallelism be in Ruby if you had to live in the browser? If you're curious about what that would look like, we can chat later on. There's another talk that I think is very interesting and this one is sort of the,
22:21
it's similar to this talk in the sense that there are a lot of imagined futures and some true history. And this is a fantastic talk if you haven't seen it. This is also Gary Bernhardt. It's called The Birth and Death of JavaScript. You can find it on DestroyAll Software. I recommend all of you watch it. And the idea here is to kind of trace
22:42
the history of JavaScript and then go into the sort of fictional future where everybody writes JavaScript and nobody writes JavaScript. And one of the ways that you can accomplish that, and this is through a project that I think is maybe two years old now, it's called WebAssembly. So the idea is you have an assembly-like language
23:00
in the browser that other languages can target. So JavaScript can target WebAssembly or Ruby could target WebAssembly or Haskell or Idris or whatever language you would like. And this raises the possibility that in the future, Ruby could come in a form that not only will allow you to compile to YARV bytecode, but you can actually compile to WebAssembly.
23:20
And if there are multiple backends for the Ruby virtual machine or a different virtual machine that Ruby can leverage to create browser-compatible code, then we could have Ruby in the browser. And we could have our Ruby methods and classes and we can share code between the client and the server the way we're supposed to now with JavaScript but somehow don't.
23:41
And we can have all the problems of JavaScript and Ruby and everything will be great. So again, is this a good idea or a bad idea? Right? In terms of the server side, we sort of keep control over the environment if we stay where we are but we still have to write JavaScript. If we allow Ruby into the browser
24:01
by compiling to JavaScript, this seems almost to be like the worst of both worlds where we get the wild west of the browser and potentially a lot of headaches of JavaScript in its environment and we still have to read JavaScript because something will go wrong with the compilation, the source-to-source compilation. We will have to understand what JavaScript Ruby generated through Opal or whatever project
24:21
and we're still gonna have to look at JavaScript. Or potentially, we could use WebAssembly and we sort of mitigate the JavaScript part. We still have the wild west of the browser and we may have to learn WebAssembly but we no longer have that source-to-source headache. You know, the sort of thing that, I don't know if this happens to you but this is actually apropos.
24:43
Whenever I write CoffeeScript, I write maybe two lines of CoffeeScript and then something blows up. I'm like, oh, nope, not Ruby and then I change it and I'm like, oh, nope, not JavaScript. Back to Ruby, nope. And then I end up just going to coffee to JS or JS to coffee or whatever the URL is, just pasting CoffeeScript in to see what JavaScript is coming out and then reverse engineer it with the JavaScript
25:02
that I want until I have the CoffeeScript that I'm supposed to have. And I would like to avoid that. So again, there are trade-offs involved and certainly we don't necessarily want to go down that route but I do think that the WebAssembly project, Wasm as it's sometimes called, has a lot of promise
25:21
and could potentially be another environment for Ruby to target in the near future. So that was our second scenario of three and our last one is what if Ruby had no global interpreter lock? And I call this part like what if Ruby had no GIL but it's really, you know, what if Ruby's concurrency story were different?
25:42
What if the rules of Ruby's concurrency and parallelism primitives were not the way that they are today in terms of threads and new dexes and locks and things like that? So I know it's not a GIL anymore. It's not a global interpreter lock since we moved away from Matz's Ruby interpreter to YARV. It's now a global VM lock.
26:01
Again, there's no need to at me about these things. But please at me if you have questions or if you want to talk more about all the cool stuff that's in this talk. I make this joke. I don't think this has ever happened to me at a Ruby conference. I think it's other conferences where someone at the very end gets the microphone and then asks a question that is actually a demonstration of how smart they are.
26:23
But again, Matz is nice, and so we are nice. And like I said, I have not seen that. It's another reason I'm delighted to be part of the Ruby community. So what is the GVL? The GVL is a global VM lock. Again, formally a global interpreter lock. It's a mutual exclusion lock that the currently executing thread has.
26:42
It's like the talking stick. When you have the talking stick, nobody else is talking. When you have the VM lock, no other thread can execute. This is for a couple of reasons. There are some classes in Ruby like array and hash that are not actually thread safe. There's the potential for race conditions and data corruption to occur.
27:00
And anything that calls out into C land, if you've ever installed Nokogiri, then you know this is the thing that happens in Ruby sometimes, compiling native extensions and things like that. It's even scarier than the browser in terms of the wild west. So you want to be very careful that you're not corrupting data, that you don't have race conditions, and the GVL is meant to mitigate that. And not all Ruby's have the GVL.
27:22
C Ruby does, JRuby does not. I actually don't, I don't think Ruby needs those. C Ruby might be the only one that has the global lock, but there are other scripting languages like Python that do have a GIL or a GVL in order to protect you from the terrifying world of C.
27:41
No, nobody wants to, okay. So that one, I should be nice. Just channel mats and be nice. But concurrency is a historically difficult problem in Ruby. And concurrency and parallelism, and I apologize if I'm sort of beating a dead horse, are different, and I think the takeaway is
28:02
concurrency is do one thing at a time, but you constantly switch among those things, you kind of make progress on all of them. So you're kind of round robining, you know, you do one thing, you context switch, you do another thing, you context switch. And it happens so quickly that to us it appears to be happening in parallel, but it's really in sequence. And parallelism is truly doing multiple things at once.
28:20
You have multiple cores or multiple machines, and you have a problem that can actually be split apart, solved in parallel with those pieces not talking to each other, or potentially talking to each other in terrifying ways. And then you have a result at the end, right? And as I mentioned, thread safety is an issue here. The GVL's job is to avoid race conditions
28:40
and data corruption, it's meant to protect you, especially for things like arrays and hashes that are not necessarily thread safe. And it's important to also note that we could just pull the GVL out of Ruby and accept this lack of safety. And really this discussion of concurrency primitives is sort of separate from the GVL.
29:01
You can have the GVL and have different concurrency primitives, you can get rid of the GVL and keep threads, it's sort of, they're sort of separate questions, but they're really, I think, intimately tied together. I think the shared concern here, the culprit is shared mutable state. That's what these concurrency primitives
29:22
we're gonna talk about, that's what the GVL are meant to mitigate, is you have some state, it is mutable, and you're passing it around. And generally if you talk to people from other backgrounds or who have strong functional backgrounds, you can either have mutable state and it's local, or you can share state and it's immutable, but it's when you try to change stuff and pass it around that things become really difficult.
29:44
So how are we potentially gonna solve this problem in Ruby 3? This I stole from Olivier Lecher, who I think also got it from, I think it was Koichi's talk a couple years ago. And this is the notion of guilds. And I would refer you to Olivier's blog post
30:02
on this topic, or if you just search Ruby guilds, you'll get a whole bunch of resources. But the idea here is to have sort of a concurrency primitive where you separate out what can be done, safely done in parallel, safely done concurrently, and what can't. And so if you have threads that are running in the same guild, they are not able to run in parallel
30:24
but guilds, threads from different guilds, can. And so the idea here is sort of tackling that problem of shared mutable state by limiting how mutable state can be shared. And I apologize if it's a little bit tough to read on the dark background. But basically the idea here is that you create a new guild and you have that guild running separately
30:43
so that when you call Fibonacci, you can rely on the guild to sort of manage parallel execution for you. This is not necessarily separate from the GVL. It's not necessarily going to save us from it. In fact, if I recall correctly, you do have a GGL, which is a different lock for the guild.
31:01
And so really what we want is something that gets us away from locks, where we say we don't actually want to restrict access to something, we just want to be able to safely do things at the same time. Turns out, Matz has a thought on this. And this is a little unfair because this tweet is from three years ago. But I found this very, very interesting. He says, my vague plan is add more abstract concurrency
31:24
such as actors, add a warning when you're directly using threads, and then eventually take the GIL away. If you're not familiar with the actor model, the idea is that actors are kind of this primitive thing in your universe, and they can make local decisions,
31:40
they can create a finite number of additional actors, they can send messages around, but basically you have actors that communicate through message passing. And they can determine how to respond to messages and things of that nature. They can modify their private state, but they can only communicate through message passing. And if you've used celluloid, I think celluloid is a Ruby gem that's a very good example
32:01
of the actor model used in the Ruby universe. And this alleviates a lot of problems that we have with locks, because we no longer need them if we say, you can modify your own private state, but if you wanna change something else, you have to send a message. And so we no longer have to lock or restrict access because we've already fundamentally said you can't change anything that doesn't belong to you. And if you've come from a Rust background
32:21
or you've started working with Rust, then there's also this notion of borrowing and the borrow checker. And again, you have this notion of ownership where this belongs to you and you can change it. If it doesn't belong to you, you can't. And it's just interesting to me that we have these things where we have Google Docs where some people can edit things and some people can't. We have things like GitHub and Git
32:40
where these massively distributed systems where people manage to collaborate all the time and not really tread too hard on each other's toes. And it would be really delightful to have this in the core Ruby language. So how do we get these new concurrency primitives? This is going to require changes to Ruby. So I said we can look at guilds,
33:00
we can look at implementing actors along the lines of what we saw in Celluloid. We can steal things from Go because Go has been stealing things from us, so it's only fair. And so you can have this fetch method and if Lycos go get it, makes any sense to you, then congratulations, you are one of the grumpy old people that I was talking about and we can all hang out later on.
33:21
And then you have this notion, okay, for each of these URLs, I'm gonna go fetch and do something with them. So if I'm gonna go fetch them, these are actually happening concurrently. There's no explicit spawning of a new thread, there's no explicit locking or anything like that. We just rely on the virtual machine to do this correctly for us. We could steal from Clojure. Clojure has this notion of software transactional memory
33:42
where the software actually says if you try to do something and two of you are trying to change the same thing at the same time, somebody quits and tries again. You do get a little bit of overhead from these aborted and then retried operations, but it turns out the performance hit isn't that bad and you do get safety when you're working concurrently.
34:01
And so there's a method or a function rather in Clojure called PMAP, which is parallel map. There is some overhead because underneath the hood, it's creating a thread pool and stuff like that and doing all kinds of dark Java magic. But again, this has abstracted the concurrency story away from you. You don't have to create threads manually, you don't have to create fibers manually. You don't have to think about it. You just know when I call this method
34:21
or use this function, I'm going to have a concurrent, basically I'm going to be doing a lot of things all at the same time. And I as a programmer don't have to worry about that. So I think that definitely does, I said earlier I was not sure if static types were in some way antithetical to Ruby's core message, but I do think that this kind of borrowing
34:41
new concurrency primitives from other languages is not, in the sense that we definitely get developer benefit and we definitely maintain developer happiness because we don't have to think about threads. We just write code and it works. If you are actually interested in Clojure, I'm happy to talk about that later. If you're interested in how talks get written, this little bit of Clojure will tell you,
35:02
and even if you don't read Clojure, I think you'll get the idea. You pretty much just alternate between these two things and then at the end you have a talk. Although actually now that Matz has noted that we have Unicode, you can actually do it this way. And this is actually a lot more concise. So yeah, pretty much you drink coffee and freak out,
35:21
and drink coffee and freak out, and then you stand up here. Yeah, it's easy as that. I do, yay!
35:40
Thank you. Nearly done. So again, is this a good change or a bad change? If we keep the GVL, then we maintain thread safety, we have all the protections that we have now at the cost of performance, and we're probably going to start to see an asymptotic increase in performance where we start kind of hitting up against a ceiling.
36:02
If we get rid of the GVL and we adopt another concurrency primitive or another way of handling shared mutable state, then we get true parallelism and a significant performance gain, especially for CPU-intensive work where you want to be able to use all of your cores and do things at the same time. Again, this could be at the cost of safety. If you look into Clojure software transactional memory,
36:23
or I think there was a Watson paper a couple years ago about hardware transactional memory actually relying on the processor to protect you. They did it with Ruby and Rails and they saw substantial performance increases and I think they were actually in the process of looking at hotspots and they were going to get an even better story together. I'm not sure if they published a new paper, but if you search, I think, Watson Ruby HTM
36:43
or hardware transactional memory, you'll find that paper. It's not too long, it's very interesting. All right, so we're at the TLDPA, which is the too long, didn't pay attention. So if you just came in or you weren't paying attention, you can now get the whole talk in about 30 seconds.
37:00
So types, there are a lot of different ways of handling static typing versus dynamic typing. What if Ruby had static types? I think what we're going to shake out is there might be something to be gained by coming to gradual typing, having the option to put type annotations into your code. In terms of the environment, there might be something to be gained
37:20
by targeting web assembly. I hesitate to recommend source to source compilation, although projects like Opal have been doing fantastic work, and the less frequently you have to dig through the trans-compiled code, the better it is, I think. Though I'm really curious to see where web assembly goes. And then parallelism, I think there's room in Ruby 3
37:42
for all kinds of new concurrency primitives, whether we pick actors, whether we modify the threading story for guilds, whether we pick software or hardware transactional memory, but there's a huge number of opportunities and possibilities available to us. And I'm just really excited to see where it goes. So, having said all of that, thanks so much for your time.
38:02
I really appreciate it.