Cheng Lou - On the Spectrum of Abstraction at react-europe 2016

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so this morning I actually checked on the react motion repository and it has officially crossed 5,000 stars right thank you this was open source almost exactly a year ago at this very conference and I just want to thank all the contributors all the 44 contributors on the repository and all the countless number of people actually using England production and this is a project I'm very proud of thanks and also apparently it sounded mug now you have a Redux and you have react motion afterwards so you know guess guess we made it right we made it on the mug pretty cool that's just wasted one minute let's start for real today there's no cool demos there is no library to present there is no other nice things that I want to concrete javascript code that I want to show you so today is instead of that I want to talk about something that's been very close to my heart and I've been using javascript for a long time and as a matter of fact I've started using JavaScript when I even when I didn't even speak English what I did was well I was literally copy pasting until the braces and I was like this is a relevant snippet of whatever that code is when I was young and whoa this is lagging but all right and and what I'm trying to say is when I joined the react team working alongside react and on react for the last three years I've noticed a lot of phenomenon that doesn't happen normally in JavaScript community that I want to underline today some of them are bad some of them are good some of them you really only get to experience when you talk to the core developers on a daily basis just like I did luckily so I consider myself to be a very fortunate in that fortunate position and today I want to share these concepts with you these concept that has have stuck with me throughout the years and helped me reason about software in general not just writing a specific library but writing all libraries and it has also helped me other aspects of life of debating with people over stuff so I was thinking about a way to make good software software engineering decisions including designing good api's just every API possible and I wonder as a as a true engineer I want a reliable way of making good decision consistently and having more reliable discussions or over these kind of software a little bit of anecdote welcome well we're trying to fix this this is an anecdote that and that I've been telling my friends in object-oriented programming you have this concept of super class and subclass right everybody knows what object-oriented programming is and superclass is we all learned that in computers computer science 101 and have you ever wondered if if the subclass let's say the superclass is a and the subclass is is B and B has more properties than a B extends a why do we call a subclass a subset why is it a subclass and not a superclass has anybody thought about this it's a trap question by the way there's a very deep answer to that and the answer is another question what are you actually counting it works so what are you actually counting here are you counting the number of methods on a subclass or are you counting the number of instances and the answer is you're counting the number of instances and that's why a superclass is called a superset because in terms of numbers of instances it includes in the pool of its own instances all the instances of subclass even though it has strictly less properties in a subclass so you see if you count the round thing in software engineering you might think we're talking up indistinct terms and we're like making the same baseline assumptions but you actually you're actually talking past each other and in these kind of pathological cases you're completely in against each other in the sense sponsored by Rango Iowa I've been talking a lot this year today sorry about that and the slides finally work on the spectrum abstraction so today you saw these trees passed by right flashing by a crossfade I want to explain a little bit what these trees are these trees are something that I created myself in reality in real life they are actually grass probably directed acyclic graphs but for the purpose of this talk we're gonna use trees for for simplification at the top level you have something that's abstract right and the abstraction allows you to descend each level and get to the concrete use cases here which are green leaf nodes which are your actual products we're all software engineers our ultimate goal is not to create abstraction abstraction is the mean for us for computer scientists this is a end for them but for us that it's not a joke for us for us we're trying to aim for the green leaves here we're trying to aim for the concrete products and for in the context of yeah you could say react is that abstraction and the middle layer abstraction in white here could be something like a react plugging in a react echo system for example and your concrete use cases would be the app that you're actually creating and to start I wanted to clearly define a few terms so that we don't get these wrong when I use them in this talk or we have the concept of power here and when I talk about power is without any emotional attachment to it when I mean power it means the ability to drill down this level of abstraction and get to your concrete use cases for me this is power and when I use to talk about utility it's on the other end of the spectrum and it's attached to concreteness right something is immediately useful if I don't need to understand how what abstractions to master to make it work so a concrete product that you as a for example startup founder you deliver to your product it should be preferably devoid of abstraction level traverse it's a concrete product it just works that's what it means for me for me in this context useful so in this context we can also say react is not very useful but without any emotional attachment but by by saying react is not useful I simply mean that react is not ready as a product yet it's a product for the engineers to use to actually craft concrete products at the end and the bad part about software engineering about life in general is that if you want to drill down the levels of abstraction you have a cost right it's not free there's no free cost free cost abstraction so every time you drill up or down you pay a cost and our goal is to be able to cover all the green leaves with the least amount of red circles possible and with the least amount of cost can we all agree that this is our goal in general ok it's much easier to work with this way and so this is what's the last slide that was passing by I bet lots of people know what principle of least power is or for example the Pareto principle which is also very close to this it basically says if you want to cover all these concrete use cases and in this case of all the Leafs nodes I want to only cover 4 then I probably want to use the least powerful tool possible to achieve them because this there are less mental overhead right you pay a little bit of cost in the last circle there but you also abstract over these two so that you don't have to worry about the two concrete use case at the bottom and this is important this is for us and another example of this is libraries versus framework the often debated thing and if you think about libraries versus framework it's only a specialization of this paradigm where I say libraries are basically me choosing loads nodes lower in the tree and frameworks are me choosing those higher in the tree where I might have covered use cases that you absolutely won't need but that's ok because someone will need them and we can all refer as a community to this single tool and this is what the purpose of a framework is it's half social and half engineering and in this library case I've for example I don't need to take the right most nodes in the library because as a master of drilling up and down the hierarchy I already understand that this is not needed for me so there's a trade-off here lion framework you can see using very formal principles why this might be easier for newcomers a set a boilerplate that that are just there already oh sorry and right now also we have this problem in the JavaScript community of having people complaining having too many micro modules so how would you represent micro modules in this hierarchy well micro modules will literally be your red circles immediately surrounding the green leaf nodes right you have all the concrete use cases you can just npm install any concrete thing without learning even how they works but the problem is that there are too many of them and we create a new problem we're like the quantity is too much for us this is another problem but this essentially without saying this is bad or not this is how it's represented once this is represented we can debate all sorts of things with this this is a quote from me that someone should put on a mug also lots of problems in software engineering lots of the big problems arise from a bad understanding of where we should be in the levels of abstraction writing code is easy to say the least writing code typing on the keyboard is easy and if you get your abstraction wrong if you create your library wrong or if your target your product wrong no amount of editor refactoring can correct that you can only have yourself as helped and the consequence of this tree is because every nail Edge has a cost you you can potentially lose a lot of adopters if you're wrong on the wrong level of abstraction so for example when you're trying to promote a library or a startup product or your teacher teaching a concept to a student any concept in any domain what happens is if you're a way to concrete you end up not covering all the use cases all the green leaves that your customer or student needs and this is sub-optimal but if you end up too abstract what happens is that especially in the context of a start-up a competitive product is people have way too much mental overhead trying to understand what you're what you're trying to describe here and they lose interest at the end too so ideally you would circle just the perfect amount but certainly the perfect amount is probably an np-complete problem and we need to rely on our intuitions now as human beings and the other consequence of that is as you go more abstract and this is a very important point I want you to remember as you go more abstract you lose more and more of the situational specific properties all right and I want to define property as formally as I did with power and utility in this case properties here for me in the context of this talk means the things we want to optimize Maxim maximize as the engineers the unique features you can have when your product is not overly general so I will give you a very simple example let's say we have our programming a programming language it's JavaScript all right but I turn every token in JavaScript into a string a variable would be a string an object would be written down as a string and everything would be a string now this would be cool because it's one unifying concept right strings and there are programming languages that are built around nothing but stream manipulation but what do we lose here if you try to use a linter if you try to use a static analyzer they will all fail because they won't even catch the most basic of your typos because everything is a string now it's undistinguishable once you have this screen shrub ability in the lower level of abstraction this is where the sweetness happens it's when you have these kind of properties that arise from it it's not like a uniform mass of things you can actually see this is a function this is a this is an object this is an if statement right you have different tokens and now the struggle is to at which level of unity or Union uniformity you want another application of property is also for example Redux Redux limits your expressivity in a good way by saying no mutability immutability and immutability immutability if you put that on a ladder of abstraction where that would they be of course mutability would be higher right because mutability can do strictly more you can have immutability by simply not mutating right but this is not the point here the point here is to do things as 3/4 early as possible and you read us when we say no mutability what what property do we gain from that well one of the most interesting properties we gain is time traveling right time traveling is property of immutability immune uh time traveling has been implemented on top of mutability but it has been very hard right and it's not that popular so this is the benefit of going to a concrete level to exploit these properties but not too concrete because then you end up you you end up not covering out a use case you want so this is another quote I want you guys to remember we're not we're often as software engineers we seek more power because for us this is appealing this is where we use comes from this is where the elegance comes from but in practical daily engineering we're often not seeking for more power we're seeking for more principled ways of using our existing power because if we were seeking more powers than we will probably have stopped at go tooth right we have all the powers we need already we do we don't need to explore any other concept anymore with goat cheese and machine one and zeros we can already do everything it's all Turing complete anyways what's the point the point is to reduce our expressivity in the principled way so instead of goat cheese we now have four loops right and nowadays instead of four loops we have map filters reduce and so if you extrapolate that you can't think we have redux which is nice Redux is a reducer can we actually it restrain our expressivity even more and what would that give us would that give us something still powerful enough to fraudalie users what if instead of a reducer we have a mapper what's the property of a mapper that reduced doesn't have well in a mapper every item is independent of each other so we can paralyze them so it gives you very interesting opportunities for visualization and unordered visualization and won't go into detail what that means but it's just to simulate your your creativity to think think about having constraints and the property that arise from having these constraints so no it's not always about look look at all the powers I have look at what possible things I can do it's about actually having them right now right here without any cost of abstraction and this is very important I want to present a few case studies and these are all the products that we use in our everyday everyday engineering in JavaScript and instead of having these kind of debates and situational arguments let to say like this this library is better because look at its code style or something I die or look at its performance I want to talk about a very general way of why a library might be preferable to another one viewed under the lenses of levels of abstraction as we saw just early earlier and this way you can make sense of things that will come in the future which is very appealing first of all is grunt versus grow cope right and I don't actually personally have an opinion on this as my I myself I've stayed on grunts because I don't have time to learn all of that cope but I apparently go p-- is the one winning right now has anybody wondered why and yes you could say in some way it's because it's more idiomatic no blah blah blah so stuff like that but there are very good reasons why historically these kind of build system always come out as the winners versus declarative DSL that it's grunt against again no hard feeling against grunt it's just two paradigms declarative DSL work really well when your domain is well-defined and because they're on the levels of abstraction they are very tightly constrained things they are almost near your leaf nodes so you when you use the declarative build system and it does what you want it's very convenient but once it doesn't do what you want you have to twist yourself to do well to do what you won't wanted to do right and in this case why is the revelant for a relevant for a build system well it's because a build system traditionally it hasn't been as well-defined as for example a finite state machine in computer science where we say you know we've we're done this is what a state machine is this is a limit of expressivity of a state machine and this is the four floor of expressivity of state machine it's not well defined a build system if if you think about it a few years ago it used to do handle dependency management and now it doesn't it used to handle module bundling and now it doesn't and now we have transpilers and we don't know where to put this transpiring set so we put it into a build system and now build system handles all sorts of other tasks now so the role of the build system is basically to say everything I don't know where to put yet temporarily I'm gonna put it in the build system as a build step and this is important this means that the build system is a moving target and it means that my green leaves are like this all the time years after year they're like this and when the green leaves when the requirements are constantly changing do you want a declarative DSL or do you want to step up a level of abstraction and use functions that don't change over time you want functions you want functions because they're flexible enough to accommodate to whatever future use case you might have and you know there are future use cases that you haven't predicted yet this is why you want to stay at the level of function and ultimately if if another build system comes up and market itself as a declarative DSL first thing we are going to notice that if it ever wins temporarily it's because it's very concise it doesn't have and you don't have to learn anything because it's not a function that you have to reason about and master right it's just you put this configuration it's how in the documentation and it just works but ultimately you will see that it will you will AK expressivity a few years down the line I'm not saying which one is better right now I'm just saying the current situation in JavaScript probably does not favor a declarative DSL for build systems now react versus templates this is the subject I wanted to discuss for a very very long time because I've been the IRC sitting in the RSC and sitting in slack and then subsequently discord for over three years now and every time every time there's a veteran JavaScript are coming in to IRC one of their question is always are you actually putting HTML into my JavaScript you know it's like have I answered this before yeah I did but they keep asking a question and we keep giving them the same answer right we keep referring them to the same talks and they come out still and then this come out still defensive so today I want to resolve this attempt to resolve this once and for all so if you have such a friend who wonder why are you putting Java in where our JavaScript maybe you should refer them to this talk in this precise minute what are templates templates are data templates even if they have if statement inside on there are ad hoc if statements right templates even if they have loop statement inside them they are read as data by JavaScript right there are still data and our position within the react team is basically saying data is very nice data is much lower in the ladder of abstraction so it is what you want ideally but the situation of the web has changed javascript is used for more than just creating interactive forms if you only create interactive forms then yes probably we should actually go with templates if you're only writing blog posts engines probably should go with templates but no we're actually creating full fully fledged application now and they're all turing-complete so maybe just maybe we should step up a level of abstraction and this is a concession let me repeat this this is actually a concession we're not proud of saying we need an extra level of abstraction to get things done we're never proud of saying that but we're saying that because we do need this extra level of extra Civet e and so you can see it in the in the in the resulting situation where amber right now with a templating system they're slightly limit limit expressivity but they get a lot of nice performance benefit out of it because they are more concrete more properties more properties more optimizable more more of morphic situations that you can actually optimize and the glimmr engine is a testament to that and all the other template engine can't do that too and luckily react is not too far behind because even though we're a level above and we lose a few properties that amber can optimize we can actually close on decades of actual research on functions and how to for example do functional lifting and constant inlining as is done by a babel optimization most right now so we restored these kind of performances by coasting on existing research but theoretically we did lose a bit of power here we did lose a bit of properties here in exchange for power so it's all about data versus function and which level we should be on and this is why in the reacting we made a concession to use functions and not data and another interesting property of react is different on views and differing on model right react is definitely the former you write your functions and ironically at this part we chose to use data because we said now we need a performant different algorithm how do we get performance data why data because data is comparable data can be sorted in order data can can be can be made this thing can be made the same you can imitate reproduced data you can discard data for example and the virtual Dom is basically based on this assumption that we can do all these sorts of thing with data that you can't with functions if you have learned the theory of computation you know that function cannot be compared unfortunately so what happens is in react line we we differ on the views at the end we have this neck here that is all data base and we said this is where we're going to do all our optimizations whereas in contrast to your other frameworks that are accidentally or coincidentally also using templating engines they diff on the model diffing on the model is data except you have a whole chain of function and computation after the model you haven't gotten to the view yet you have so many steps and these computations because you cannot compare them you have you lose these properties right it's not data anymore so you have to restore these properties somehow and the solution we found is basically computed properties where you track each step of your computation to restore these properties but this is much less convenient of course I'm biased but I think this is what's actually happening and without giving another opinion of how this which one is superior I think this is the position we are on in terms of react against the other popular frameworks right now another one is mutability versus immutability this is also weird cuz from someone who has program in C for example where that come from a mutable of first languages why I like most of the mainstream languages they don't get it they don't get why immutability is important because they will always tell you you know what but I can do strictly more with mutability so why would I choose something that's less powerful and how do what do you tell them right you're like this is true you can do more you can write more programs than me using mutability that is true but this is not the point right and now you can actually get them a concise reply you can tell them it's not about the potential power of doing more it's about exploiting the properties that you gain by doing less and this is why immutability is important right now because you're doing less of it you gained this property redox time-travelling for example nice comparison should component update which has become a critical hooking the reactive lifecycle events all of that from doing less not doing more and now let's extrapolate or a future topic JavaScript CSS versus traditional CSS so there has been one good argument i i've heard against against inline CSS against javascript is that giving the layout algorithm the power of a full language is way too much we lose way too much properties and this is true this is undeniably true just check the debate of for example a grid-based layout or a constraint solver versus versus black box and CSS it's obviously less powerful and expressive as it currently exists so theoretically if we can do everything with CSS theoretically right implementation is another another detail let's say but if you can do everything with CSS definitely try to do things with CSS because it becomes much easier to reason about because there's literally not much to reason about anymore because there's no abstraction level to go up and down too so theoretically it's easier to analyze CSS and I personally have always wanted to see a CSS static analyzer which can analyze the boundary of your components and tell you for example if you translate this this text into German it will overflow something like that and this kind of properties it's very hard to get when you have the power of a full Turing complete language unfortunately we're not doing that and unfortunately as shown by pre-processors we we are on the wrong level up we are on the wrong level of expressivity here we did need functions after all we can't just use a declarative DSL anymore and this for me is at the heart of the argument of inline CSS is being able to use a real language so that we we can stop twisting ourselves around that dsl not because it's just more familiar JavaScript or we can we can use the existing bangla infrastructure of course these are all nice practical benefits but theoretically speaking it's all about the levels of abstraction here so a few concrete experiences that I that I've had over the years this is the last section first of all and this is an obvious one don't cover every use case what's the easiest way to gain performance do less work do less of these use cases shave off green notes if you don't need any shave out all the leaf nodes that's how you gain easy performance you can gain performance in other ways but this is one easy way to do it and this is an obvious advice again but now we can actually have and this is the attractive part of thinking in terms of level of abstraction is that we can have a clear justification to not cover every use case now because when you cover every use case you lose on opportunities of optimization and I don't mean just speed optimizations you lose on all the optimizations of mental overhead of composition of nicer nicer user experiences and you don't even know you're missing out you don't know they exist in the first place you want wäôre abstract right and true true to be told to to have an having worked with on the react team I realized that react actually loses out on lots of abstract optimizations because of the API surface that we need to support so yes we support a smaller API surface for the nicety of it for the conciseness of it but not just for that we support a smaller API surface area so that we can have ourselves some wiggle room for performance optimizations for mental overhead optimization and this is very important and of course don't constrain or over constrain yourself too much so that you don't have any wiggle room left right and so if you look at the text that take off this is regarding what you think of the these technologies something you might love some of them you might hate some of them mice impure than the others but the texts that do take off and do become popular they tend to be averagely powerful technologies they are not all powerful and they are not all constraining there's a reason behind that and this can be explained if you think a little bit more in terms of abstractions and the other one is sebastian has mentioned this before in another talk called minimal api surface that this part of the talk i think people didn't understand too well is it's okay to copy/paste code it's totally okay and this is a little bit controversial to say because though as engineers we want to not do it or do it twice right but sometimes if you think about this very simple tree here the cost of abstracting things away over weight the cost the benefit of actually having a single node right I can either circle two circles here or one circle some people will prefer circling the circle up there but you now you had incurred the cost of drilling down and every time I read your function I need to understand what's actually happening and this can have exponential effects so it's okay - sometimes copy/paste but then this again is up to your judgement now and this is also the phenomenon of NPM micro modules where people say everything I'm gonna write tries I'm gonna extract it away and now we have surprisingly j/s fatigue and we we seem we don't seem to understand why it's because consistently we're paying more cost to abstract things than to actually use them don't be swayed by elegance and elegance at once again is a very overloaded term sometimes it refers to things that are way too powerful and we say wow this is a single unifying principle for example monads macros these are so pretty and we as engineers we find them very nice because with one single thing we can tame so many concepts but you can bet and if you reason about this in terms of trees of abstraction you can bet that a single unifying principle is two generals to be popular and two general to be used in a more immediately usable way it takes time to master of course if you're the only person that needs to master it then it's all up to you but if you're making a library writing an app or something and you are imposing this on to the user then be aware of what you're trying to do here you might not be doing enough for the user you might be leaving user too much levels of abstraction to go through for the user him or herself and when in doubt use examples why do we need to use examples and now here is a good reason good very rational reason for doing so we use examples because examples on the tree of abstraction is on the very very very lowest level right you have your library which abstracts over things and examples are basically copy-paste up and passable templates they basically say instead of understanding the libraries right away here are your actual values that I can provide you and if you want you can understand this later by connecting the dots and this is why examples are helpful so when in doubt and when you're lacking lacking ideas of how to express your libraries correctly write a readme write a few examples write more documentation and this will make things much easier even if your code or your abstraction is leaking so in conclusion funny lis I put I can put this talk itself on the levels of abstraction right so this talk itself on the levels of abstraction will be extremely abstract would be very vague which ironically again by my own definition is probably the most useless talk of this conference but but but now you know that the definition is actually consistent right it is also by my definition and without any emotional attachment a very powerful talk in a sense that if you can master the levels of abstraction and drill down this these ladders yourself then you can potentially apply this paradigm just like I did to various use cases through a lot of these concrete use cases but only if you apply these things if you don't apply it if you just bike and you if you think in theory only about this level of abstractions then you won't be finding much use for this talk at all so I urge you to think about all these next time you write a library next time you write an app you start something new try to think in terms of abstractions and when you where you want to be before starting to actually code and execute thank you
Info
Channel: ReactEurope
Views: 46,691
Rating: undefined out of 5
Keywords:
Id: mVVNJKv9esE
Channel Id: undefined
Length: 35min 31sec (2131 seconds)
Published: Sun Jun 05 2016
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.