What's New in Scala 3?
Recording: What's New in Scala 3?
if you have a scholars learn sorry o'reilly's learning platform subscription you can actually start reading the updates but what i'll do is i'll walk you through some of the examples here i've also been blogging about scholar three on medium if you like go to if you like google medium and scala dash 3 you'll find these blog posts i'm a little behind i need to do some catching up or i won't be done by the time scala 3 comes out so i noticed that uh some of the scholar folks who are online here i hope you get that language out reasonably soon but uh no rush no pressure um i heard you you said you've been talking about the new uh brace versus indentation syntax so i won't just talk about that explicitly but i'll just point out some examples i actually decided to go all in on that for the book since it's about scholar three uh actually to be quite honest i didn't like the idea when i first heard about it because it seemed to me it was just a kind of let's call it gratuitous change for lack of a better word not something that's strictly necessary to make the language better but i kind of understand why it's done as you said when i joined kind of embracing maybe uh more appeal to python programmers and i'll be honest i actually kind of like it now that i've used it a bit so um in fact you can see some examples here i was playing with some of the new syntax isn't necessarily brace related but like here's a for loop where um you know it's uh yeah i just do four i from zero until nine and then you can actually do an end for if you want and you can do end method name or end class name whatever so that's another little bit of that syntax i haven't actually used this really in anger there have been a few classes that i've written that are fairly big and that's why it's here so that you can have a good you know place to know when you've reached the end of something without counting tabs or whatever but um it's one of the ways that you can write things a little different you know while i'm here you can do things like you know if i let's say if one is greater than two here i am flying into old habits you don't need parentheses if you do this then you can do things like this um uh change okay i think if i do i'm at this yeah so um you can have these new keywords like then uh so you can drop the parentheses and stuff and i went ahead and like i said went with all of that but let me let's talk about something that maybe you've heard a lot about that i think is really pretty interesting which is the new context abstractions and these are basically implicits what's coming that's different there and the argument for this change is that implicits is kind of a low-level mechanism and we've all learned all of these sort of idiosyncratic patterns of using it to do various things and so what they're doing in scala 3 is actually introducing some new terminology in some sense let's call it that that it tries to be a little bit more explicit about the purpose even though the old implicits are going to be supported for backwards compatibility for a while but we can go into a little bit about why this is happening so let me find that spot in my uh sample code here um oh i know where it is sorry you can see i've got a lot of code now you if you go to my github repo you can find all this code now it's not well commented because it's typically used inside um not the book where i do comment on things but anyway let's start with one like our old friend aerosos you remember this is the thing that lets you do you know a arrow b and it returns a two element tuple well one way to do this now in scholar three is that they've introduced true extension methods so instead of instantiating you know a class that does an implicit conversion to an arrow associate uh you know basically the if i let me just write that like the old way is something like this where there's you know this class you know arrow is you have some type a and you pass it an a of a and then um you know there's this uh and actually i'll talk about the some of the annotations you're seeing here you know then it was this right it would uh you'd call the arrow and it would return a tuple that's sort of the old way to do it but now we have an extension method where this will actually for any type a and b uh again we want this to work for every type in the type system i can now add a new method and i just use tilde here just so that it wouldn't collide with the existing method of the true arrow and basically does the same thing so this is the new way that you would write something like this implicit or i should see implicit conversions are much less common now because a lot of stuff you'll do with extension methods instead so this is a really valuable thing we've we've known we needed it for a while in scala and it's pretty exciting there's a couple of other interesting things to know here that i'm showing the recommendation now and i think these might eventually become warnings or even errors if you don't do this if you want something to be used as an operator have the infix notation now in fact you don't have to do this if it actually uses operator symbols like this so this actually doesn't require the infix notation or the in fixed annotation but if i had you know if i had a second method you know like def um a source or whatever that you know just called you know this um then i would have to have an annotation eventually for that to be allowable in infix notation so that's another way of kind of constraining what you can do there are some interesting um exceptions to this the collection methods either you know we're all used to writing like foo space map space block um i think all of those will still work out of the box either because they'll be annotated within fix but it also turns out um if i just get rid of this if you do something like um you know let's say list map and then something like this if it sees a curly brace it will also allow it without the annotation functions so that's kind of an interesting little twist for that the alpha annotation is actually putting this is the name that will be used for this method in bytecode as i understand it rather than some synthesized thing that the compiler would generate and the purpose being that now you have a you know fixed name that you decide it could then be used by java code that wants to call this library however you cannot reference this method in scala code with this um uh new name this alias if you will you'd have to define you know a separate function like arrow two but if you really wanted to do that um it says correct anything i'm saying wrong here i see you online and uh so hopefully i got all of this right if you don't it'll be in the book so make sure you pipe in if i make mistakes here um by the way um if you just have one extension method you actually don't need the colon but if you have a colon then and again i'm using this bracelet syntax it's like i've declared a type and i can have as many methods as i want so i really could add a new method or whatever here and it would be part of the same type so extension methods a lot of what we do with implicit conversions will just go away just use extension methods and it'll be much more concise and once again much more obvious what we're doing whereas if you look at a implicit conversion if you're a newbie to scholar you may not really know exactly what's going on until you understand how they're used um and that kind of leads to the interesting case of type classes so what you'll notice about this is that if i wanted to actually implement a separate version of this arrow thing for different types there's no mechanism that i'm seeing at least right here that would let me specify an interface so that they're all implemented with the same signature it would just be sort of ad hoc and random where i'm adding something to string i'm adding something to you know my personal class and they may or may not be consistent so type classes helps us you know avoid that so here's an example of a type class i actually adapted this from the dottie documentation i should mention that too if you if you go to the documentation at epfl's site i think it's quite good much of what i've learned about scala 3 i read there of course like anything it's a work in progress some things are actually evolving and changing other things in other places the documentation is a little out of date but it's it's generally quite good for not only examples but you know what's actually coming in scholarly so here's what we might do to create like a semi group and a monoid and i'm assuming this crowd kind of knows what they are but basically monoi just is a generalization of addition uh with with a unit like zero if i'm adding numbers and the addition part is just what i'm going to call combine or this i'll add a second method that um you know this funky darth vader spaceship tie fighter is that what they are anyway something like that um so semi-group these are the math terms semi-group doesn't have the unit and monoi adds the unit so other than that these are just regular traits though as far as we're concerned but notice what i'm doing here there's a very interesting thing that's going on here i'm going to make these instance methods and hence i'm declaring these as extension methods these two right here whereas unit i don't need a separate unit for every single instance i can just have the equivalent of a companion object instance so by not declaring this as an extension method when i actually instantiate this trait it will become sort of the equivalent of an object member in fact it will be an object member as we'll see in just a second so let me just uh actually set this up as a script so let me just paste these in my reply here and in case you can't see the bottom that well i think i'll wrong way there we go i'll put this at the top a little bit so it's maybe a little easier to see for some of you uh and i forgot the import statements don't you love it when uh your examples fail i'm actually using the uh dottie reppel here and it's it's got some nice features like you don't do paste colon paste anymore it's gone you just kind of you know it's smart enough to figure out what you meant so that's kind of cool and now i'll actually instantiate this for strings and integers i'll just go ahead and paste both of these these weird comments are part of the way the book is built just for sectioning off stuff but anyway what you're seeing with given is the alternative to an implicit value you just say you know given a string monoi as minor as is a new keyword then um now i define what unit means in this case and i only need to define the combined method because this uh arrow thingy or plus method just calls combine notice again that this is defined um without the key without the extension part and this is defined as an extension i didn't come say this maybe enough but this is the object i'm adding a method to so i'm adding to the type string and i'm giving it a name s so that i can reference the equivalent of this and similarly for integers and notice what the names of these these objects that are output they're called string monoid and inflanoid and in fact you can do this you can do antmonoid unit and that's where the unit ended up now if i it also turns out you can have anonymous ones so let me just do an anonymous one for doubles here oops just quickly and then i'll show you how to actually do this for all numeric types using my fancy uh ide called sublime text here oh i forgot to do this i don't want i want to make this uh anonymous oftentimes anonymous is fine notice the name this is actually a standard pattern for the name of the eye of the object that's generated it does have the unit but that's kind of an ugly name to remember so that's why i actually gave these names up above and uh yeah we can see that they actually work that they obey that you know i didn't in this thing i'm not using scholar check or anything i'm just showing you examples of these things in operation and they're you know they obey the usual properties of associativity and all the things like that that you may have heard about when you talk about addition and then just to wrap this up a little bit these givens can still be parameterized so if i want to declare one of these givens for all numeric types this is how you would do it and now we're going to see how implicit clauses work uh parameter list rather so now i'll do a given numeric monoid of type t and i'm going to pass in a you know basically one of these context bounds that we've usually this would be you know implicit value of some such thing um and this will be the thing that that verifies that i can only use this particular instance of the type class for something that's numeric so there's numeric instances for you know in all the integers all the doubles uh including big decimal and so forth oops i mean the wrong thing still once again i gave it the name i want uh actually to reference the unit you'd have to like give it something so let's do this there's the double and then now it just works for things like big decimal okay uh someone asked if that uh they're wondering if the dotty rebels based on ammonite that might be true you know that's a really good question i don't actually know if anyone wants to chime in on that but i'd love to hear that whether that's actually the case um it is not it is not okay thanks seth not to say that's not a bad rap too but uh okay uh let's see what else can we talk about so so anyway that's that's sort of a capsule summary of the new facilities um with uh you sort of it'll eventually replace implicits where you declare given instances those are like the implicit vowels uh using is the new thing for um you know an implicit parameter list uh these could also be uh anonymous i could leave out the num um uh colon if i wanted and if i wanted them to reference the object i could either use implicitly but that's now a bad word right so there's also a function now called summon s-u-n-m-o-n that you can use to to grab the instance when you don't have a name for it so otherwise things work a lot like they did before okay so this is pretty fun i think it's it's really going to clean up our code a lot of special extension methods make it a little bit more uh intent driven as when you read it versus kind of using a lower level mechanism but basically solving a lot of the the same use cases that we have um okay let's see what else can we do here um i apologize that i didn't have as much time to prepare in advance for this as i had planned to but um i'll mention a few other things quickly about the syntax and then we'll come back to it a lot of times you'll just write stuff like you used to like you can see um here i'm doing a on the left hand side i'm just using a for loop like we had before with the yield statement so that looks like regular scala too but as i said we now have this ability to write this without using um curly braces if you want now there is one actual disadvantage to the curly brace thing and different let me find my example of that so one of the cool things about scala has been that we could write like our own control structures because whenever you you can always pass arguments to a function using curly braces so if i write something that's like simulating a while loop where i'm going to say loop for n number of times and call this function on the niche index you know that works kind of the way we would expect it to if i paste this over here then um you know what we'd love to be able to do like we used to do in scholar three is you know maybe n and then uh you know we can do the curly brace thing if we want like just just do print oh i think i forgot i have to uh oh i need to find him why don't i just do something for real all right there we go but what we can't do in this new syntax is i kind of like to be able to write something like this maybe where i do you know to be consistent with the syntax and that doesn't work so we do have to use curly braces for these things i think there is a positive there is some work being done to maybe add this feature if i recall correctly but it's kind of more experimental um than available today so you're still going to be doing it the old way for a while most likely which is fine can't have everything in life right okay uh actually let me bring up the book for a second that'll remind me so here's like a draft i'm working on where i have i'm also trying to make this smaller it was like 600 pages in the last edition and 547 is too big i actually wanted to get it closer to 500 so it won't quite be as something that you can use as a weapon hopefully when it's done but let's let me find a few other things in here uh pattern matching is uh mostly the same but there are some interesting changes um where did that go uh let me just find a good example of that well one of the things i can just type this in let's just do that that you it actually works a little bit better if you want to sequence them so if i have like you know um let's say let's just do this uh i'm just sort of making up a kind of a trivial example oh catch is the wrong word of course and you can actually chain them which didn't quite work before this is obviously pretty basic you can type that's interesting oh oh and i matched on the range so this is what i really needed to do right something like this and i'll just put this in for rather than make it a uh partial function they tell if i would do this correctly sorry this is a okay that's a little better so but anyway the point being you can chain match statements better than you could before and there's actually a type change that's happened underneath um one of the other things you've heard about is um is intersection and union types let me let's talk about those for a bit how are we doing for time pretty well uh where did i have those type system okay here we go so that's not one i want to use oh actually i want to be down here sorry so i have the way i've restructured the code is now i have um the usual source main directory tree and then i also have a script uh directory tree for things that are actually just supposed to be evaluated with the rebel and then some of these are tested so okay here we go so um one of the things that's changed now is the idea that um instead of doing like uh sort of a path well path is the wrong word but if i define these traits and then i do something like this where i combine them in different orders the types that actually come back are these intersection types and what this is saying if you think about like set theory um if i just had c as the type then valid values would be anything that's in the set of c but if i add these other mix ends then now not only does that element have to be a member of c it has to be a member of the set of t1 and a member of the set of t2 so it's actually a more constrained set of values that are allowed what's interesting about this is that these the two types here are actually considered to be the same in fact if i wrote something like i have down here where i deliberately put the types completely out of order these are all considered equivalent types in other words they commute in the same way that set set uh theory would um like intersection union and sets commutes but the behavior does not necessarily commutes and i'd particularly contrive this example so i have these overloaded cam methods that call up the chain and will actually return different results so if i do uh c12m for some string let's just put in one and then if i do this with c21 notice the uh ctrl t did the nice little switch of the things there that's good notice that the uh the different braces and so forth come out in a different order so even though these things are equivalent types they still behave differently based on the linearization that's used to resolve which of the super methods to actually call next it's kind of interesting related to that is union types although it even though they're kind of dual in the sense that you've replaced the uh your ampersand with a uh a vertical bar they're actually used more like replacing eithers then something that's it would work close to what we're writing here so let me just define a few types here and a few values for like some good result and some bad result where the bad result might be the message that comes out of an exception and the way i could then declare the sequence of elements where i'm mixing good and bad things in the sequence is by using this syntax here good or bad notice that by default if i don't annotate the type on the sequence it infers the uh object and this is actually a quirk in the compiler i ask on the scala um get uh get uh one of the mailing lists i forget what it was anyway and it actually should probably say any ref but any ref an object are basically the equivalent so that's what's in it's inferring in this case because these two types are unrelated so it goes all the way up to the type hierarchy but in fact this is the real least upper bound right here is uh good or bad and it's sort of equivalent in a way to you know sequence of either good or bad kind of types so it's a it's an alternative for doing that so if i process these let me do some work here where you know if you pass me an integer greater than zero then i'll say that's bad the integer should be less than or equal to zero else i'll return good you know typical sort of thing you might do with an either and then but now here's the trick of how you have to work with these things just as with either where you pattern matched whether it's a left or right you don't have to do that left or right wrapper around the real thing anymore it's now either just a good or a bad so it works it works conceptually the same way but it's a little bit more concise to work with it this way so it's kind of a nice tool i don't you know we'll see how much people uh migrate to this versus using eithers or something equivalent um obviously if you're doing it does give you a little bit more flexibility but um we'll just see i kind of like it because it does make it a little bit more concise i'll see a few other questions oh getter yeah thank you for uh reminding me of saying i could not remember even though it started with the word get there okay once again this also uh i just this this is a list of stuff it just shows that everything is associative and it also commutes and i forgot to define these types and we also have this type equivalence because they commute because they are associative they uh commute now there is some interesting stuff though that happens uh let me see if oh yeah when we talk about contravariance this is kind of interesting so let's talk about a contravariant function and what happens there so i'm defining a function that's going to take either a t1 a t2 or a t3 and return to string oh i should grab the whole thing let's do this sorry once again i have to pattern match on it this is equivalent to this type in other words you know uh when you have something in contravariant position like these types here like this tuple type well no it's it's a uh it's a it's a union type it's equivalent to this distributed rule yeah there's this rule of distribution and arithmetic like normally you know a times parenthesis b plus c is a b plus bc well here this is how it actually works the the ores of the unions get converted into ands and then um these these types and the return type permute through like so so this is the distributed rule for covariant or sorry contravariant types in an expression like this looks completely weird what is this actually saying it's saying that the only valid function that i could assign to something of this type is it has to be a function that can take a t1 and it can take a t2 and it can take a t3 and return a string and uh so if we try some a sequence like that not delete it i just pasted i pasted it one thing sorry all right let me uh where did i define this ah here it goes but here's the here's a sequence of these things now i can do this and they both return the same thing where they just these are just strings now so this is pretty strange the way that i mean it takes a bit of thinking to kind of you work out the mental model of why this uh works you could try a truth table for example to kind of uh piece it together uh the fact that i picked a function which adds all of these you know arrow stream things makes it a little harder to corroc what's going on but if you if you kind of ignore those for a second then um you know it's basically saying that this maps to uh you know these these grouping expressions with uh and instead of four or vertical bar instead of uh this so that's co that's contravariant uh behavior covariant behavior is a little bit more obvious um you know if i have an array of these things i think it's probably the same one i just pasted then um uh actually i forget what i did here uh let me just go on it's actually a little bit easier to follow what's going on here um oh actually this is the this is why this is there let me just comment on this for a second so the reason this is invalid is because we're basically saying that the sequence will always contain t1s but i've given it a sequence where some of the items are in fact t2s or could be or they could be t3s so that's why you know we'll obviously avoid surprises which is what type systems are all about this this is not a valid assignment even though you might sort of look at this and say oh t1 or these others well okay i'll just put t one no can't do that okay um any other questions can you have string and none would that be useful when you don't want to wrap option strength um so if you had something like this let's say val x string or none you could do something like this but these would be treated completely independently so in the sense that and keep in mind that what i showed up here how do you actually work with something like this well you end up doing pattern matching like here so you probably don't gain that much if it's just trying to eliminate heaviness some in there you probably end up still having to do k string or case none so that probably doesn't buy you a lot however there is um now the ability to do stuff like this you can declare something as either a string or a null and uh i'm not actually using this as there's a compiler flag that makes this a bit more of precise that i'm actually not using in the code because it tripped up things like um lazy infinite recursions like there's this famous example of defining the fibonacci numbers as an infinite sequence folded on itself kind of thing and that actually trips up the type checking with this one apparently but you do have this ability now that you could um basically be very explicit about what's allowed to be null and it's of course designed to support uh interrupt with libraries where that's allowed uh someone asked too about when you need nun type yeah this is the one that i've tricked over already like you wouldn't um i think case none works but sometimes you actually if you have an object you're working with sometimes doing none that type gives you what you want when you need to say something of a certain type i think maybe like this which is a bit weird looking but this is what you have to write if you were you wanted to like capture the value or something anyway read that okay that's interesting someone mentioned that in react it's common to see methods that take string or by name string or ant so i think you can most of the time you should be able to uh just write you know a by name function and then pass it a string i'm not sure why you need both but maybe there's a reason for it the entire can understand something entirely different but you will have to be pattern matching on what you were given to know what you've got all right um there are some things that are i haven't really spent a lot of time learning about yet but uh so i'm a little hesitant to get into too much but we do have uh my here it is get uh the uh getter webpage but if you go to the dottie documentation you'll see there's a lot of stuff about type lambdas for example uh which is kind of cool for dealing more effectively with higher kind of types than we've been able to do before but i haven't did necessarily always turn to whatever miles saving is doing today or tomorrow so let me let me click through a few things here to see what i want to throw in there is a new enumeration syntax which is pretty nice so you'll now be able to write stuff like this which is a little i can never actually remember the scala 2 syntax i kind of maybe now i do because i've done it enough but this is a lot more direct about how to write enumerations my understanding too is that this is actually basically compiled to java enumeration so they're more interoperable as well and you can define methods on them there's kind of a cool example with an enumeration for the planets you give constructor arguments and so forth let me see if i missed anything under content contextual abstractions that i want to oh yeah here's a kind of a cool feature given imports uh the way that you'll do uh imports now when you want to import these what used to be implicit values is explicitly say import something dot given if you just do import something dot underscore it will not import those implicit values and that the rationale for this is that it gives you a little bit more control over what's being brought into scope uh so that you you know you see this and you know that there's some of these given uh values that are coming into scope whereas before you know import underscore you just didn't really know you had to have some way of figuring it out when it when these things showed up and there's a little bit more about um you can say i just want to i need a given i know that it's of type x and i know this package happens to have it so this is what i'm going to import to get that thing whatever it's called i don't care okay seth mentioned that if you want a java if you want java style enumerations you extend java lang eno so that's something i need to add to the book i guess actually i'm kind of following the philosophy of scala you appeal more to python programmers so i'm not really mentioning java quite as much as i used to in previous editions um i'm sort of on the on the argument that i'm not sure how many more java developers will come over to the scala fold like in the past but but i think we'll probably bring in people from other communities like data science types who you know we're told they had to use scala for their data pipelines but are used to using python so okay we talked about type classes i think this is the one this is a different example there's a way now if you know haskell type class derivation is the idea that i could say i want my tree type to derive equality ordering and so forth and then the compiler will just generate the type class stuff for you and you won't have to do that explicit thing that i showed you a minute ago um that uh i think that when i last time i tried this it actually only worked for this new eq type class it actually wasn't supported yet for the other two that may just be the effect that you know that's not quite uh the library itself isn't quite fleshed out yet for the final 3.0 release but that'll be kind of nice that we can do stuff like this and not have to you know explicitly provide the border plate for some of these things so that's what type class derivation is about it's just auto-generating some of these things equality in this case would be a way of being being having a more precise equality check that is more tight aware and so forth similarly this leads into multiversal equality speaking of the quality where um now we'll have an ability to provide a much more precise way of checking equality rather than just doing it at the anti-valve or rather the any ref level and this also involves there's a compiler flag that i think is mentioned in here to turn this on whereas if you leave it off um it won't be quite as strict i think this will be a nice evolution of avoiding mistakes when we do comparisons which any of us in the programming world learn after a while that it's far more for non-trivial to do comparisons than it seems at first um let's see let me uh well i think we're getting close to the hour so i want to kind of wrap up there is a totally new uh meta programming facility now available uh new way of writing macros if you're if you write macro heavy code this might be the area where you spend most of your time upgrading from say 213 to scala three is uh you know the way that this is handled um actually i saw some comments on gear the other day about uh rob norris was going through this exercise with some of his code and actually went faster than maybe he expected but and finally i'll mention maybe some drop features and then maybe we can take some questions i do encourage you just to browse this website because it's really quite good at explaining a lot of stuff that's changing um we've they've added um parameters to traits and so a lot of the reasons for having the delayed a knit feature where you could have this block that's evaluated sort of in before some other things happen like constructor calls that's gone because it's not really needed anymore the old macro facility has been replaced with the new features they've also gotten rid of existential types so there won't be this foursome construct anymore um uh it really wasn't as needed as we thought i won't click through all of these actually some of these some of them are pretty obvious we knew the procedure syntax was going to go away eventually where you didn't have an equal sign here's an interesting one now because now it's easy to just define types and so forth at any point in the code package objects aren't really as useful anymore so these are actually gone instead you would just do something like this instead of defining a package object like we did before another big change is the the 22 field limit for functions and tuples is gone but beyond 22 these new types tuple xxl for t-shirt size i guess and function xsl will be used instead and there's some kind of cool features added to tuples as well you can do operations like create a new tuple by appending an element to an existing tuple like we've always done with lists and so forth so some new behaviors there i know all of you will be sad to know that xml literals have been dropped sorry can't have everything um symbol literals also have been dropped which is probably a good thing uh because i don't think they were used that much and i i actually came from the ruby community after i did java then ruby for a while and came to scotland actually really liked using colon for uh symbols and in ruby but that of course would collide with the type annotations um an auto application is about uh sort of auto tupling as i recall and now you'll have to be a little bit more precise about the client arguments even if it's an empty argument list and about converting to and from tuples and if you do the qualification of private and protected they've they've also dropped uh this uh qualifier because it's effectively um unnecessary you can you can get around with other things all right so there's a comment here martin dersky is really promoting the new function types with implicit parameters uh context functions his example about making the usage simpler than reader modad was a cool one yeah i mean that's an area where i need to spend some time understanding a little better that's discussed and under con contextual abstractions that's discussed here context functions there is actually yeah there's a really cool example that's right um how you could use this mechanism to do like a very nice little mini dsl and so they implement an example here for that um and a new slightly new syntax notice how this type is declared up here with this the question mark equals greater than sign let's see uh super traits is kind of a cool idea um it kind of gets rid of this thing where you'd enter you know you declare a value and the rebels says that it's also of type uh product and serializable and so forth traits that are declared with the super key word just are omitted from that type inference um and so it also makes it easier to like declare that you expect an argument of typhoo and you pass something that has a different type because it's got traits mixed in that you don't really care about for for type checking those sort of things uh here's the section about explicit nulls that i talked about a little bit where you can you know explicitly say that something could be a null and um there's also a flag to try to trip up or try to catch cases where you haven't initialized things safely this is um also triggered by a compiler flag yeah this this new flag why checking it actually maybe it was this one that was tripping up my uh view example of an infinite definition of fibonacci sequences i think it was actually this one not the uh the uh the null checking explicit null stuff that i mentioned earlier so that was a mistake all right anyway i've been kind of rambling a bit lately um was there any other questions uh that anyone wanted to bring up or other particular features that you've seen that you want to mention is anyone actually using the new syntax without braces and stuff and what are your thoughts about that uh opaque types that's a really great one let me quickly talk about that this is a a better way of doing what any vowel was designed to do where you extend in any vowel and you don't create a wrapper that actually didn't quite work as well this opaque type idea is that i could give a type like logarithm but it's actually going to be properly handled as a primitive basically a jvm double uh on the the stack uh you know inlined in an array and not in a you know a wrapper type so this is a i'm glad you brought that up because this is one of my favorite changes is this idea that we can you know have these very lightweight domain specific types but they're actually as efficient as if we could use something like a primitive instead and that's the idea with this new opaque type uh match type i um is the change that they've made to also do things like make it easier to chain match expressions um uh no sorry i got that wrong match types are bits up here yeah so you can do crazy stuff like this so notice this type declaration for element uh where you match on x and then um return a different type based on what x is so it could be a character as an element of a string um or before just an array it's just a t or something like that so this is another uh change to the type system that's kind of cool let's see someone's asking can you talk about the new tuple can we write or at least match on tuples in a flat manner even if they are nested differently um i'm not entirely sure what's changed here i don't know if you have any comments about this seth this thing in the this question in the chat um any any other questions comments criticisms complaints things you wish were done but weren't the scholar three match types work with opaque types i think they do because if unless i'm mistaken they they are type checked in the same way but um the implementation is again this underlying uh native type oh flat mapping tuples all right let's try that yeah i forgot how this works actually if you do this so there are some new methods now in tuple and i think fl i believe flat map or maybe it was just map is one uh where i can do uh let's do this captivates i played with this a little bit one day and i forgot how it has to work yeah anyway as you saw a minute ago there are some new methods now that let you treat tuples a little bit more like um regular collections you can see the list here oh right it takes a poly function yeah um and i forget the syntax for those but there are ways to handle this so you can actually do mapping over tops anything else anyone has thanks for looking forward to the new book uh available at a dealer near you sometime eventually soon i would buy the ebook quite frankly you know let's thank dean again and guys feel free to um ask any questions now by voice or say anything you want to share for one i wanted to ask you guys uh we did this lunchtime meet up right because we are in the virtual space with space and time no matter anymore and we're in the land of eternal youth in california anyways you know the time was meaningless here uh forever so but i just wanted to ask you all if this time slot works right because i mean obviously we had the record showing we had more than 60 people uh showing up which is pretty high for this online uh setting so what's good about this is it's a kind of nominal lunch time in in california it's kind of uh afternoon in uh east coast and again you know kind of still kind of lunch damaged in in chicago and it also works for some kind of not too late people in in europe so i just wanted to to ask you guys if if if you would rather keep this time slot rest so the options are salar our wonderful organizer was actually pioneering early breakfast meetups which is like 8 a.m pacific time which is even more conducive of europe and east coast but we did not see too many people uh although on twitch we had actually i think a hundred people like so i mean it really depends right so uh just wanted to ask you guys what do you think um does anybody have a preference uh early morning kind of breakfast time slot uh this kind of time slot uh or you know evening kind of traditional physical meetups are you know 5 6 p.m does anyone have a preference someone said i think it is a nice break you know in the middle of the day if you're breaking for lunch it's a good time to geek out a little bit in a different way just my excuse yeah i mean certainly works for me and it's like it's not too early it's not too late pacific time right um so if you guys kind of like it maybe we may keep it at this [Music] time so yeah so folks are um i see folks are answering in in the shot great time not a bad time okay i have to drop off to fight a work emergency but i thanks for the opportunity to talk and hope you enjoyed it thank you very much dean and we are looking forward to next week in case you guys uh following we have reactive summit on tuesday and uh we actually commemorate the panel with dean uh is the future reactive there and then we have obviously scale by the way um thursday and friday right and i'm doing a python talk there you go yes array right which is right an interesting distributed framework exactly so you guys are all welcome to join again i dropped the code uh sf scholar 20 for 20 off of that uh in the chat uh feel free to register and send as many of your co-workers as you like who will have like obviously a nominal price this year so uh great gotta go see y'all thank you everybody thanks dean thanks guys