Java Generics: Past, Present and Futurit by Richard Warburton/Raoul-Gabriel Urma

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello going everybody goods whoo it's great to be back here in Antwerp fantastic I'm Richard and I'm rel yeah rowl I heard it was like a big year this year like an anniversary or something yeah there are some delicious cake downstairs so it's judge Ava's birthday Trevor's anniversary 20 years 20 years of Java fancy sighting whoo right all right so that's all together on the count of three say Happy Birthday Java okay three two one happy birthday fantastic fantastic no that's not fantastic though I think we can do louder than that right we can do better than that can't we yeah yeah okay three two one happy birthday Java fantastic let's be better is it okay claiming it's better people need a bit of beers a thing before the show cool cool so we're here to talk a little bit about generics for the next hour or so and a lot of people when they see generics kind of see a situation that's a little bit like this right it's like there's something that's kind of complicated going on on their screen but it's not really very obvious not really very obvious what's going on here Richard what are you doing on this picture whether you look at a pavement that's that's what the roads are like in the UK this is this is the result of austerity that's what that's what happens with the roads right but the point is where we want to kind of enlighten you a little bit and look at some of these features look at some of the things we have in Java which are already available today which you can use but aren't necessarily use so much and then as the talk goes on we'll also have a little kind of brief crystal ball gazing and see about some of the upcoming features there might also impact generics and change generics in the future as well so that'll be quite exciting but first let's go way way way back into the past they don't remember 2004 yeah I hope everyone's hand should be up here you are hopefully all over 11 years old and there was this website right called the Facebook do you remember the the Facebook what ever happened to that we have a brilliant developer friendly UI as you can tell with the square brackets and binary numbers in the header that's essential awesome awesome developer UX well also in 2004 Java added generics so what so let's go back and just recap why generics were added to Java to begin with here we've got some great Java some vintage Java 2004 era remember there's no for each loop before there either and if we just run this code we'll see it works perfectly we can just ship it right hang on there's a pretty large cast class cast exception there so what's what's going on here router why is this blown up in our face well it looks like you're adding do two strings in a number then you're treating and casting back to two strings obviously the number it's not going to be a casts back to shrink so what can we do to add a bit of type safety here which generics rights you know that's what we can do we can add some generic soon we can say this is a list that only contains strings and as Java went on we could also use the diamond operator introduced in Java 7 to say instantiate this ArrayList and infer the generic parameter from its target type that's pretty good right that's pretty good so from the runtime error we've moved to a compile time error so that's pretty fantastic so now it blows up at compile time and solves a runtime error perfect but Richard you know I could do that before Java generics anyway right I could create an extra class called list string and another class called list integer and I don't have to add this whole complexity here in the language what's wrong with that Richard what's wrong with that well the problem is that we might not just want to have a list of strings you won't have a list of integers we might want to have a list of our person classes favorite tutorial example any old other class that we want it doesn't really scale up to a large code base P no the the c-sharp pre generics collections a I does have a string list doesn't it for this exact reason so this kind of brings us to a more interesting kind of trilemma that you might engage with this kind of thing on the one hand we've got simplicity so you know not having to worry about this complicated set of rules that generics brings to us on the bottom left-hand corner we've got static safety so my static safety we mean the ability to take runtime errors that will blow up in your face at five to five on a Friday afternoon and stop you from going to the pub and convert them into compile time errors which you can just say this code is broken I'm going home for the weekend it's fine anyway in the bottom right hand corner we've got concision and we don't mean concision we're not saying jars necessarily the most concise language across all respects but what we mean here is not having to copy boilerplate template code all over the place to achieve this kind of type safety so we've got languages like you know java scala c-sharp c++ which just subtly typed and have some kind of generics or equivalent feature sitting here with both static safety and concision and they give up simplicity to achieve that we've got languages on the dynamically typed spectrum like JavaScript Ruby Python which you've got simplicity and consisting safety and on the other thing we have like say the string list approach or perhaps even languages which have some generic types but don't allow arbitrary one-time types to be generic like phantom for example and they achieve simplicity and static safety but if you actually want to do it in the general case you need to copy and paste loads of code around we've kind of bring this up because we're talking about generics there's always a lot of complexity and downsides involved we always need to remember there is this big trade-off nothing's a free lunch it's all a big trade-off it's interesting to see actually all those languages like JavaScript Ruby and Python there's a lot of work that's been done to actually add static type checking to those languages you'll see lots of type annotation proposal so it looks like the echo system sort of migrating down this button the left corner of the diagram as well fantastic so that was 2004 this isn't this is 25 Dean so what are the things that we can do with generics today that are available in the language that maybe we don't really see people doing that much but which might have some benefit for them what do you think role well so we're gonna review three three patterns that we've seen in Angelica basis which hopefully you'll you'll find interesting so the first one our intersection type so there's a feature in Jack only two section types and we'll look at that then we'll talk about the curiously recurring generics pattern so very useful planning to bring up in a you know dinner to look smart really recommend it what does it mean no one knows I don't know we'll talk about it and then wildcards probably everyone's favorite feature in Java all those question marks we all love it fantastic yes we all love it so let's start off with intersection types and section ties readin idea that you know comes back to primary school so does everyone remember is really cool and sexy Venn diagrams you know who loves the game diagram I'll have a good man no ma'am so the Venn diagram is saying essentially given to two to two areas we've got a region in the middle that's gonna be the intersection and turns out we have a similar idea in Java that works as follows so let's say in the first example here once you declare is a type parameter called T and say that it's gonna be a subtype of a okay so it's bounded by a when we say a subtype what we mean here is if a is an interface it implements it and if it's a class it extends it nice and simple precisely and within section test what we can do is to say that actually T can be a subtype has to be a subtype of a and B okay so we do that using this sort of ampersand operator and that's in section type so is that useful feature well let's look at a at a good example so I'm just calming this out so we don't have them compare so we're going to look at a example here which is sort of a series ation this relation use case so we've got some some subjects here we go so person is has a name and husband has an H okay so what we're going to do here is to read up some data from a data input stream and just realize it into a person object and print print print the output so let's just run this code so we see what happens fantastic don't drop her age 89 who's a fan of madmen a few people if you're not putting your hands up go watch madmen it's a great TV show but yeah set back in the 60s if Dawn was alive today he'd be a very very old man he'd be very happy I think to see some code about him yeah so now you know let's say we've got this read method here which is that the meet right so that's taking the data input stream take the source is going to read off the name of the person and the age of the person create a personal object around it okay and of course we serve we have got this try and catch block here in the case I've got an ru exception let Richard software the software industry always changes isn't it yeah new requirements come in or perhaps a new change of some internal structure suppose we want to you know use a different input source like a random access file here rather than a data input stream so what are we gonna do here's the code that used the random access file and unfortunately this code here now is not compiling so if I mouse over this area here from it it tells me well I method readout created expert data input stream but we're giving a random access file so that's problematic we've got a type checking error so so what we can do so you know classic software development technique you know if we get paid by lines of codes yeah as we always do Raoul has just doubled his income here this is demographic compares ship it yes compile ship it great but I heard I heard someone saying that having huge blocks of duplicate code that does basically the same thing perhaps not a great the greatest of ideas around your program who came up with that rule yeah yeah okay so let's see if we can do something better so obviously we had those two methods that were exactly doing the same but they were just expecting different types so what we're going to try and do here is to find this around the middle if you remember this Venn diagram what we want to find is what's in common between the data input stream and a random access file maybe we can use that as a common functionality so obviously you know we need to be able to read information because there is the mess of read it - read int and we need to build also - to close this resource it's within a try-catch hair block which is auto closable so what we're going to do is just take a little bit into the definition of this class data input stream it implements data input fantastic so that's the interface that provides us those read oppressions also extend this class a photo input stream which extends the stream which eventually also implement an interface called closeable all right that's fantastic so let's do the same exercise with random access file so if I look at random access file we can see that actually it's also implementing data input it's also implementing closeable so those are the two interfaces that those two classes have in common so Raul I've got an idea we've got two interfaces let's have a new interface that extends both of them how about that yeah let's just do that so we're going to say extends data input and closable right so this is a sort of type that we like to create and we'd like to be able to replace this with in our method here right so if I take this piece of code paste it around here that's you know we would like to do something like that because the distinctive face a represents on this data input in close bone which is exactly what random access file in data input stream are implementing but this doesn't work and the reason it doesn't work it's because obviously this interface here is not being implemented by those two classes would need to retrofit this interface on to existing JDK classes and unfortunate we're not stewards joining room here has the master keys we we don't have those master keys so we're gonna have to come up with a different trick and the trick is to make use of intersection types so intersection types are use for in such the situation where you want to create a dummy type where you can provide a subtype for several interface or classes so what we're going to do here say we're gonna have at a parameter call I that's going to extend both for data input and closable fantastic so we declare this in front of the return time here we're going to use this new dummy table that we created as the input to read and make sure to replace it into the block of the method read and fantastic seems like it's compiling which it yeah let's ship it ship it let's see fantastic Wow actually worked that static safety might be useful so we're not necessarily saying you want to throw these interception types around the code base obviously you can see there's a bit of a readability hit but and you may well not have had a situation where hey you actually want something that implements both data input and closable interface but you might well I've had a situation sometime in your career where you're like there's just this missing interface and it's not there and it would be really really useful if it existed and this is possibly a tool which you can use to address that kind of problem so that's nice precisely but Richard there's under use cases for using section types and the other one is this one what have you done to your door role how are you gonna close that it's not my door it's actually Stuart's door of there I'm pickups to it I don't know so yeah what is going on with this code what the hell so you know we've got something as an object and compatible but comparable objects should be an object right which is what this is very strange let's break it down step by step shall we let's do this so you may recognize the intersection type right this ampersand symbol hey so we've got something doesn't in section type of both object incomparable and that's a signature that we've taken right from the collections API so why have we got a sexual object well to really understand this we need to sort of a take a step back and go back in the past and before generics were introduced this is a signature that we would find for the max method it would take a collection so no genrich's head and would return you an element in that collection therefore an object right which is within this collection this object would be the maximum and once you've come up with a signature for an API that's a signature that you stuck forever to preserve binary compatibility and arguably here we could say that actually max really should be returning something as comparable because if the elements in the collections are not comparable how can we actually find a maximum right that doesn't make a lot of sense so we could argue that she the signature for this Maxima that should return comparable and that's something that you know we wanted to fix when when I say we I mean the library designers people the keys with the keys wanted to fix so when generics were introduced we ideally would like to say something like that right all the elements in this collection so that's the tea that you see here have to be comparable I don't worry about those extra question marks we'll cover that later but which means hey actually the signature that would be compiled by the Gela compilers as follows something that returns a comparable that's because generics are erased and the strategy was used to please to have a sort of migration path between non generic code and generics code so they can interrupt no problem we've got ahead actually the generated signature for max is different to the one we had in the past right in the past it was returning an object now we're returning something as comparable so we've got a binary compatibility and binary compatibility czar very bad no one likes them no one likes them especially the Skylar Fox I think so the trick that you know the language designers came with is by adding this extra extra bounce so by saying that actually the signature of max here is the elements inside microsomal above object and comparable what the java compiler will do is pick up the left-hand side of this intersection hey object and use that to produce the signature for this method and by using that we preserve binary compatibility so that's the story behind this sort of crazy signature has to do with binary compatibility which is a good thing for us right so we want to have compatibility but we paying the price a little bit from the complexity point of view ah here's an even more fantastic example so Java right and it lamb for expressions whoo come on whoo great and we got a situation where certain types of lambda expressions you might want to have them have give them the ability to be serialized right but at the same time you need to tell the compiler here's a target type for your lampur expression here's some functional interface which the compiler will say hey right that's the target type for the lambda expression that's the type I'm going to use and you might not want to make every instance of that functional interface serializable you might not want to say every comparator is serializable for the more serializable the comparator has been around for a while so you can't just retrofit and say it extends another interface willy-nilly now here's an example method where you do want to have something that's both a comparator and serializable so the intersection type is used in the return position here and the lambda expression gets casted to that intersection type and that's basically telling the compiler look go generate me something that's both a comparator and serializable so this is a possible pattern that you can use if you want to make a serializable lambda that's an instance of a non serializable functional interface and so that's quite cool the compiler is happy here because in this context there's always only one single abstract method provided by the compiler interface serializable is just a flag interface so technically you could have any amount of interfaces as long as they also flag interfaces whether that's useful we don't think so the serializable is a good use case for this intersection type rustic so Richard what's your what's your door doing on the slides it's not really my door I swear it didn't it didn't look like that originally Wow we've all seen this kind of thing the top right this this class II gnome of II extends enum of II what's going on here if you're an academic you might call this s bounded polymorphism but as we all know there's an internet meme that much more accurately describes the situation going on here yo dawg I put a tight perimeter in your tight parameter so you could what why are we actually doing this again what fantastic its system goes let's have a look into a bit of a code example and see what's going on so we've got a little method here and we've got two very confused people and one of the confused people is called John and the other confused peeper s'en is called Bob and John is confused because if we uncomment this line of code here where we try and clone John and put him reassign it to himself we try and make a clone of him there's a compile error that's a bit weird let's look at the dalish of confuse person 1 in details let's see what's going on yeah fantastic so it's implementing grenoble of string which is surely there should be picked up as a compiler error right yeah maybe it should be maybe it should be picked up as compiler so we can take that cloneable of string and just make the make it cloneable look infuse person 1 to begin with and that'll be nice and now we need to update the clone method and make it return confuse person 1 and instantiate a new confuse person 1 that's cool and if you look back to our main method that compile error goes away that's exactly what we'd expect but it still feels like that should have been a compile error for confused person 1 to extend cloneable of string to begin with that's right yeah let's have a look at confused person to Bob now Bob take a clone of Bob and we clone that clone again it's like a very bad Arnold Schwarzenegger movie but unfortunately just like a very bad I love short snake a movie you can't do any kind of abstraction or generalization of lessons learnt so if we try and clone this confused person and clone them again that's something which we should just be able to do on anything that implements our cloneable interface if you can clone something then that thing should in and of itself be cloneable that's a reasonable thing that you might want to express so how can we change that in our cloneable interface well at the moment we'll see that our cloneable interface just takes a type parameter T and has no restriction or control over what that T is right so that meant that we could have confused person of one implementing cloneable of string it made no sense but the type system allowed us to do it whereas if we say cloneable of t extends cloneable of t that's lovely that would a stop that earlier compile error with confuse person one and B we can now clone our clone fantastic all the Arnold Schwarzenegger's are happy at this point in time cool what else is there what else is there that we could talk about when it comes to generics well what so you you introduce that question mark into cloneable mmm so we're going to talk about christian martino called wildcards so we really believe there must be a reason why the language designer chose a question mark for this feature maybe but so confusing and puzzling it is a level of for sites amazing so wildcards what a wild cards all about Rowell well here's some example of well cards that you may see already in in the java api so question my extensity lovely lovely that seems reasonable then we've got a competitive question what super T alright that feels a little bit weirder and we're going to talk about this but n this is other guy here burn research so you can have a question myself compare more they sell is a question of super team I'm just just lovely to nest those things together so we're going to try and shed some light on what this stuff is about but the sort of the key the key summary is that it's all about subtyping it's all about getting flexible api's and that's what we're going to try and demonstrate so Richard what are we gonna what's going to be the domain for this sort of a little excess that we're gonna write well let's let's send some messages around at the moment we'll just be printing them out on the console just so you can see what's going on alright so we'll have a couple of different types of messages we can send emails and text messages how about that so a couple of different subclasses of the message class fantastic simple so turns out we've got a log and look mr. lug method here so let's just log a new email message I'm gonna say hello there Vox fantastic cool these got to be the most advanced log system ever all right well yeah don't troll this is still more efficient than log4j but yeah back to the point in hand we didn't need to say anything our log method just took a message and we could pass an email message in as a parameter we're gonna pass a text message in as a parameter nice and familiar I'm sure everyone does this every day on a day to day basis and so what about if we go a little step further than that we were a so email messages was possible because email message is a sub type of message it's extending it so we can substitute them that's great let's see if we create an array of emails emails rain they go just going to create one simple aim a message we love beer it's almost five o'clock so it's beer time isn't it yeah so we've got another another method hit call log all that's going to take a array of of messages so let's see what happens if we actually pass this that seems to be working so let's compile let's see if it runs what happens let's see if it runs shipping all right so that's working as well so it looks like actually an email message array is also a subtype of a message array so with a little bit we've extended that relationship we had between an email message message so just normal subtyping we sort of lifted that now to an array of email messages an array of messages so that's pretty good that means you know API is quite flexible we could pass also and we have text messages that's brilliant is there a name I can use for this if I want to impress people with my my knowledge of types not something you do on a regular basis but what would you say router what can you do there what's it called it's got covariant erase that's there that's the technical impressive words so if you see your so in such a situation where you've got subtyping that is lifted to something more than just regular types we will quite co-variants that's a sort of word that date that you love from here but you know since we've been able here to use this subtyping principle by passing it as a noggin to the logo message we means we can do some of some more interesting things so I'm gonna create an array of messages now the APIs we remember such as messages in the rain and I'm just going to sing it the theory of emails because we still get this subtyping relationship right so instead of passing as an argument I'm just assigning it so it works that's all consistent makes perfect sense but hang on a minute roll if you've got an array of messages hear this message array does that mean you can put a text message into that slot is that possible why not because the elements in the array are just of type message text message is a subtype of message so let's see what happened is fewer hundreds so let's create a text message saying you guys are awesome ah there we go seems to be compiling which is so let's just ship it again and a complexity it allthe it'll definitely work fantastic fantastic we've forgotten here so yeah no race tour exception right at line 34 so that's exactly at the assignment level so that's very interesting because you know this array that we've created here and the elements of the array living on the hip on a heap or email message elements right but using this assignment hey we get a different view to disagree we're saying actually the element are just message which means we can assign some elements inside array but here is email messages and we're inserting text messages obviously that's completely wrong right in Java we really believe in static type safety and suddenly we've got a runtime error so that's problematic but to give a bit of credit to the you know language designers actually if you remember the dark days before generics vintage Java vintage Java how would you write a method you know that takes an array and needs to find an element inside an array right then you may want to pass an array of strings and our vintages an array of Richard you know so this property here lets us create a sort of flexible API that can take arrays of different types so that was necessary back in the days but now we've got generics Richards so our collections as well we can use all this to wants arrays anyway let's get rid of those pesky arrays yeah let's put a list in see what happens now right so we've got another message a call log oh that's overloaded to tape list so we've got a bunch of lists define here so let's pass messages okay so pass the list of message because the method low goal here expect a list of message so that's that's good let's let's ship it so first we're good cool cool but if we can do this with a list of messages can we do this with list of email messages it's a bit like dodgeball isn't it if you can dodge a wrench you can dodge a ball that's what we're talking about here ohyeah we can pass a list to print out a list of messages can we print out a list of email messages let's give it a shot so I've got a list of email message here we'll just pass this in and unfortunately we get a compiler error which says actually I don't have such a method here so we staffed and it kind of makes sense it doesn't it I mean we said that doing the this disco variance thing with arrays led to bad consequences who wouldn't want to allow people to do it for lists as well but perhaps we can think of something that lets us use it in a way that's safe without bearing the downsides and saying we have to use it everywhere precisely so what we'd like to do here is to use this subtyping relationship that we have between an email message and a message but have it also between a list of email message and a list of message where in a safe way so by default it will say that generics are invariant so this relationship doesn't exist what we're going to try and do now is to get this covariant relationship which we mentioned earlier and you can do this using this feature called one count and you can say question mark X tense message so you're saying ahead actually I will accept any list where the elements are a subtype of message okay so message defines sort of the bound okay and what this type is going to do is make sure that you can't actually use this new message list and add elements of a different type the compiler provides some fences so you can't do that just because it's a different type so if we run this code now we printed out our list of email messages Floris so that's nice but suppose you wanted to add some kind of back end to this sophisticated enterprise scale logging system that we've got maybe we'd say you want to add in a different way of printing things out so maybe something that prints out just the message on its own or prints things out generally how would we do that route so Richard I've got a exact interface the right interface for you for this introduced in Java 8 anyone using Java 8 today yes more and more people come to the dark side of the force so consumer is the interface that we really need because it defines something that takes an element and it's going to do something with it so it consumes those elements so terms of logging with different mechanism that sort of interface that we like to use yeah so we'll say it takes a consumer of message you know and put a class and we can replace this stuff here now to actually accept a given message okay so we've got different behaviors that we can inject here through a consumer to say how we'd like to to love the messages in the list now we've made that code more flexible well so we need to fix this one here because that's not compiling anymore because this method expects two arguments yep so just to make it more explicit we're going to say let's take a consumer here it's going to take a message and it's just gonna print the the message and that's lambda expressions if you're not familiar with it great feature introduced in Java 8 so lets me define a consumer here in a very concise way now I can pass this consumer as an argument to log all let's see what happens cool so it's just printing out the message it's done exactly what we expected it to do I've got a bit of a question for you here do I need to create a new consumer of message all over the place do I need to couldn't I just put like a consumer of object right because if you know how to print out an object you know how to print out a message because a message is a type of object how do we do that can we just say consumer object what's going on okay Richards I think you're saying you want you know let's say we've got a consumer objection which is going to call it print and let's just use just for the sake of this example we'll just use the print method so this is a method reference takes consumer objects so the elements are objects I'm just going to print them out what we like to do is to say well actually we've got a a consumer hair dyes no less specific works with any kinds of object and we just like to be able to use this consumer head to print the email messages unfortunately if we do this we get this error here that says actually I'm expecting a consumer of message and you're giving me a consumer object and carbon Java it should just work damn it should just work just what can we do to solve this problem well introducing the little brother little sister of the question mark extents called question mark super what question mark super is going to say is I'm actually accepting any super type of message including message itself so if you will previously we had two subtyping from this direction by saying a list of email message is a subtype of a list of message now we've got subtyping from a different direction we're saying actually a consumer of object is a subtype of a consumer of message that's where we can pass it as an argument and I could is compiling here so let's just let's just run it and get Hello by email so those why can't say hey the bottom line is you know it's all about subtyping it's all about creating those flexible api's and I can abstract the times that we working with and that's what what comes lets you do you get subtyping for generics we're in a type safe way fantastic so that cover subtyping and the question mark super here is you know the one that is a little bit more scary but it's really commonly used for functional interfaces that were used that were introduced in java 8 so for example predicates here really means a function that takes some element and returns a boolean so you can see that the type parameter c here with capital T is used as an argument to the test method so that means this predicate interface a can only be used with the question mark super by default it should be question mark super and you'll often hear academics talking about contravariance that's the sort of the dual four covalence contravariance is a technical word and comparator is another example here you can see that T appears as the types of the arguments of this method so that means this interface can only be used contravariant Li by default it should be the case so you can get the flexibility but this is really exciting as well things like question mark extends in question mark super won't really use that much before were they really but the introduction of lambda expressions means we've got a load of situations where things like question mark super is naturally very useful all over the place precisely and it's always useful to you know language feature is a really interesting topic you know how do we make use of them where do make use of them are they useful how can we improve on them and there's a lot of research actually looks at empirical analysis of those features and you know the the the java.lang to esteem is making use of those techniques to make sure that you know got relevant updates in the language and there's a paper here by chris ponen and at all which actually looked at millions and million lines of code of java code and what they found was actually quite fairly interesting but not so surprising it's actually 90% of generic uses were just for collections so list of string ArrayList of string hashmap string to string and set string you know covers 90% of generic uses so this is a really interesting story as well isn't it we've got all these features they have some valuable use cases perhaps some getting even more common but actually we don't use those features very often well do we so there is a different side to do story it sounds that actually those features are very useful from from a user point of view on the applications we write and then there's a whole bunch of other complex features which gets your flexibility believe more on the library design point of view right that should be living there so they'll shield it away from from us users and that sort of things that we we're going to talk about as well so that covers the present and we're going to now jump jump in the future so back to the future it's the year what we're going to talk about here comes with a very fancy Oracle legal slide saying don't believe us we don't actually know what's going to happen with the future but we've been look at the mailing less than talking with the team to get an idea of what's going on yeah yeah but instead of having some legalese here's a Back to the Future picture fantastic much much prettier cool so the first thing that we we talked about is the other use side variance so that's the world calls that you've seen so far and we call them use advance because they give you subtyping flexibility but you have to opt in as a user to actually make use of that so in your code you're gonna have to say question mark extends message if you want to be able to pass a list of email messages so use advanced because as a user you have to decide to make use of that feature if you want flexibility same thing for the consumer here you need to explicitly say question mark super message if you want to get the flexibility and this this kind of sucks right because it means that every single one of us all the time needs to use these features in our code to obtain that flexibility but couldn't we push this into those people who maintain libraries it doesn't really sound like they've got enough work to do maybe we can push some burden on onto their shoulders I think that they do have a lot of work going on with value types which we'll talk about in a sec but the general idea here is decoration site variants so that's as Richard saying is why don't we take this complexity living on the application code living with the users and push it down at the library level so we don't have to worry about it so here's how it could look like using some not made-up syntax this actually could be a possible syntax but what we're saying is that consumer takes the time parameter T and this parameter T needs to be used contravariant ly with question mark super as a default annotation so that means anywhere we see consumer for example Chris dream of message by default we could pass the consumer object will get that flexibility because the subtyping the variance annotations push at the library level and we could do something similar with each rater so iterator is only producing elements so the type parameter appears in a return position so I can only be used covalently so using this annotation here it means anyone who could pass an iterator of an email message for example but as a user you don't have this verbose annotations cluttering your code anymore so the correction site variance is the feature that that's done and it's a feature that is used in other programming languages like C sharp and Scala have adopted this feature actually Java is you know now it's own there's other academic language using use advanced with one of the only mainstream programming language that actually use you cite variants but that means the flexibility is pushed on it for the users then you get verbosity through due to the annotations but it's really powerful you can have a time that is both convent and control and if you really want to in practice that's not really the case so it's not really necessary decoration side variants though is the alternative where you push up the boosted down at the library level the complexity is pushed down there you still get flexibility but in certain situations you might have to split up you type hierarchy for example a list you can both write a list you can add elements to the list so the type parameter here appears in a contravariant position right as an argument but you'll also get element from a list so the type parameter appears as a written type so she won't have decoration side variants hey it's bit complicated you need to split the users in terms of read and write so comes with a bit of additional complexity from a design point of view but that's okay it's for the designers and it turns out this is a feature that is being explored for for Java as part of a Java enhancement proposal so here's the link for those of you who are interested in this it's currently being proposed for JDK 10 so that's not something to expect in the near future but again there's research that shows actually this is really useful so there's a paper headers published at PL di so a very good academic conference and what shows actually by looking at library code 27% of generic classes and 53% of generic interfaces could be having default variant annotation some of the consumer and competin each rater they could just have a default parameter we wouldn't have to always type those question marks in a user : so that's pretty massive actually that's actually showing that actually declarations and variants would have a beneficial impact on on Java code and not only that but existing code making use of wildcards 39% of those users could be totally inferred with the equation side variance so whole bunch of verbosity could be cleaned up using this feature and as Richard was mentioning with Java eight and functional interfaces that something that's becoming even more useful another thing that we might need to think Ransome's of upcoming java features that also interacts with generics is the proposed addition of value types which has been mooted Fino our java 10 type schedule who knows and the mantra with value types here is it codes like a class but works like an INT so what does that mean well classes and kind of objects inherently have certain forms of identity we can talk about having you know value like identity where we we've got an equals method and we can say two things are equal where their fields are equal where they're trying to represent the same value oh we can also say that they have reference like identity we've got that double equals and what we're saying is that's pointing to the actual same object in memory and suppose we were to imagine that we only had types that had value like equality so no concept of identity it's just a bag of values just a struct to values if you're familiar with C what does that mean well firstly it means there's a potential compactness wins so objects have headers headers eat some kind of memory they've got information associated there with locks they've got information they're associated with threads that lock could be biased to they've got a pointer to the class that owns them all sorts of things now potentially there's the opportunity to remove the header information that objects have now depending upon which JVM version or using 32 or 64-bit architectures whether your compressed OOP switched on or off you could be saving 8 to 16 bytes now doesn't say very much but if you're talking about an intercept an integer that's quite a lot of memory because you also have to take account of alignment rules on a 64-bit JVM without compressed oops switched on a boxed integer is taking up 24 bytes of memory a primitive int only 4 so that's a six times blow-up in terms of memory there but much much more importantly is improved sequential locality flatness in memory so one of the ongoing hardware trends that we've had is CPUs getting faster right that's fantastic but transistor counts which is what Moore's laws are regime defined in terms of do continue to double we've got multi-core machines we have got some performance improvements even though you need to go parallel to use those advantages but memory on the other hand has been speeding up at a much much much slower rate only nine percent per year over the last decade and what that means it says being increasingly large gap opening up your on your on your for ages between getting data out of your main memory and actually doing compute work if you look at computation you bounded tasks these days they're often much more bound by how fast you can get data out of memory now I know what you're saying it's ok you've got a CPU cache it'll prefetch data it'll pull it into memory it'll put into a a non die cache that's much faster fantastic stuff but in order to be able to prefetch that data into the CPU and not have your CPU sitting there stalled waiting on data from main memory it needs to predict where in memory those objects are so just think about an array of objects in Java kind of this this this guy we've got on the right just an array of our user objects we've got an array of what's really under the hood pointers pointing to a heap allocated user object which is at some arbitrary location heap which is pointing to say some ID and then a name and other arbitrary locations in heap that's a heck of a lot of pointer indirection you're CPUs cache prefetch I can't predict that random offsets are somewhere else in main memory but if what we say is we'll lay them out sequentially in memory then as we iterate over that we can nicely stream the data out of memory makes our cache prefetches job a lot nicer makes our code run a lot faster so there's a huge potential benefit there but in the context of generics there's yet more complexity because we said generics were originally implemented through arisia runtime we don't have necessarily the information to say hey layout an array like this layout an array like this so in order to have a generic type that lets you have a value type as a parameter like you know an ArrayList that's taking a value type as a parameter you need to think about generics a little bit more differently you need to be able to say to the compiler look you can put a value type here and it's okay to use it you need to be able to give it some guarantees you're never going to use that reference equality because reference equality doesn't make any sense you're never going to call synchronized on an instance of that generic type because you've got no object header you've got you've got nothing - you've got no monitor to lock on you're never going to use the condition variables weight or notify and that contract so the compilers may not be this syntax maybe the syntax but there's needs to be some kind of notion introducer saying this is any type it could be a reference type it could be a value type we're going to commit not using those features which are reference type only so there is a little bit more generics complexity cropping in but on the upside this also means we can do something which people have been clamoring to do for ages and ages and ages which is too primitive specialization so you have a list of int and that's genuinely a list of primitive in that's genuinely backed by a primitive int array under the hood and in fact if you look at the the Valhalla prototype the primitive specialization case even though it's kind of quite prototype implementation there's already work on there already and you can already use the primitive specialization examples already you can try nf eyeing your collection code and if you do that it'll work so if you want to explore this kind of stuff more there's a prototype on the Valhalla project for specialization also includes the value types and the value type generic changes I mean they're far from complete but it's a good prototype to play around with and there's also this state of the specialization document if you want to kind of learn more and go into more details about things this look there's a meaningless as well I'd ever had a mailing list the team is looking for feedback on how this is being used in practice who do do contribute to it if you've got time fantastic so we've also put a quick slide with some references up here all the source codes available on github and if you're interested in more kind of other slightly more exotic language generic features there's a bit of a list there that you can go and have a look at but um let's conclude first round yes I mean this is quite interesting so genrich's you know a feature introduced in 2004 and over time actually more and more libraries have been making use of generics so it's a feature dies hate to stay if you look at the whole collector's implementation in Java 8 you'll see genrich's all over the place because it lets us write code that's really expressive from a user point of view when the library point of view we need those sort of complex feature so jerax users has increased in scale and complexity that's something that we'll see in the future as well with value types in the combination of generics with value tablets which is saying so it's going to become more and more complex but it's a good idea that this feature actually most of the burden is pushed down to library designers and that could be done as well as declarations and values that we mentioned earlier so first user hopefully it should be all good and most of the complexity would be pushed down for library designers but you know the overall conclusion here is that static type safety something we all love in Java we get those compile errors which tell us we've got to fix things before we ship or programs so is a trade-off between simplicity and flexibility if we want to get more flexibility that means a type system the feature becoming more complex and that seems to be the general trend where things are heading so before we take questions from you guys just quickly want to mention a few things so richard has got a fantastic wholesome plural site if you want to learn more about generics so it's sort of four hours cost intensive or for you to recap on those things I run the Cambridge coding Academy which provides workshops for 14 years old plus to learn how to code and create own games it's all in Cambridge we've got summer schools as well so if you've got kids I want to send them to England over the summer check this website we both book authors both books are equally good equally good so if you interesting Java eight you can check this this stuff out and finally we also running bootcamp courses so if you interested in upscaling in Java 8 we've got a two day intensive course that covers all the features and all the best practices we're also running a boot camps in in Java that teaches you the sort of best practices for software development and also for c-sharp so if you're interested in this stuff check our website each rater learning calm and come chat to us afterwards as well so thanks for listening and we'll take questions Hey front row perfect we didn't shout about mics I don't have the number on top of my head so the question is how much are people using these suppress warnings when it comes to two general types I would encourage you read the paper by Crispin announcer as the first paper that we mentioned on general usage it's called adoption of generics and there's a section that talks about this stuff so you may want to to to read up on it yeah cool yeah fair enough there's probably a lot of code out there that just doesn't bother very very legitimate question right does anyone else have any questions I can't see like just shout if you have got your hand up or something maybe if you've got a question just come and ask us directly if you want talking private otherwise just shout now and we're doing this because there's the light so we complete blinder to hear no okay well thank you very much it's been been great to give the talk cool pleasure
Info
Channel: Devoxx
Views: 15,206
Rating: 4.8647342 out of 5
Keywords: Devoxx, DevoxxBE15, DevoxxBE
Id: LEAoMMEIUXk
Channel Id: undefined
Length: 55min 56sec (3356 seconds)
Published: Fri Nov 13 2015
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.