Developers often look at abstractions as being "the closer to the metal, the better," meaning that as abstractions become further removed from the lowest possible level, the more you give up in terms of performance and features. But abstractions work as a spectrum also. We'll look at how we can adjust our view of abstractions and what kind of examples we can use to better understand that abstractions have less to do with programming and more to do with where we deploy.
A New Kind of Abstraction
AI Generated Video Summary
Abstractions in software development build on top of other things and provide utility or make development easier. They can be low-level or high-level, and the smaller the abstraction, the closer it is to the lower level. Abstractions can operate in different environments and their level determines how the code operates and is approached. It's important to evaluate the abstractions used, their portability, and their distance from the low level.
1. Introduction to Abstractions
Let's take a break from technical topics and talk about ideas and abstractions. An abstraction builds on top of another thing, like a low-level library or API. It provides utility or a library that makes development easier. Abstractions can be low-level or high-level, and the smaller the abstraction, the closer it is to the lower level. They can also provide escape hatches to the low-level, like importing C modules in Python or returning valid JavaScript objects in JavaScript libraries.
Hello, everyone. I'm Mike Huggington. We've already had a full day of a lot of technical topics. Let's take a break from that and talk about ideas and abstractions.
As someone who came from a non-engineering background, I was taught that an abstraction is this thing that builds on top of another thing. The simplest example is we have this low level library, or low level API, and we just have all these kind of rough implementations of how to get things done. This could be assembly. This could be C for you. This could be a raw DOM API.
Well, people come together and they realize that that is not going to be very productive. They're going to be stuck having to maintain the nuances of a low level API. So they go ahead and they create an abstraction. They build on top of it. They provide either some kind of utility or some kind of library that can sit on top of API and give you a better time developing. People come along later, and they realize that that's a pretty good starting point. Let's go ahead and make something more. Let's make this a little bit more easier. Let's remove this method because it's not really used that often. There's a lot of footguns in there. Let's give you something that's going to be simpler, easier to understand and let you get to build whatever you want.
We sit with this level of abstractions, where we either look at them as being very, very low-level or very high-level, and the spectrum of very high-level to low-level, and this hierarchical spectrum is how we typically look at it. Now, with this hierarchical approach, we also have to consider that whatever is at the high-level might also include more code, whether that's runtime or just in general as a library. It might include limited feature set but still handle edge cases. So the smaller the abstraction, the closer that it is to the lower level, maybe, maybe not. In addition, the abstraction also could provide escape hatches to the low-level. Perfect example, not in JavaScript, but in Python, you can import C modules. You can write some C, import it into your program and have access when you need that escape hatch. Lua offers the same thing. There could be JavaScript libraries that instead of returning their own custom object, they return a valid JavaScript object, whether that's a date or something more. So these are the ways I was taught to think of abstractions and as time has gone on, I've realized that there's another way.
2. Understanding Code Abstractions and Their Impact
We need to consider where our code will live and its execution target. Abstractions can operate in different environments, such as the browser, server, or Cloud Functions. The level of abstraction determines how the code operates and is approached. It's important to understand that abstractions are not inherently better or worse, but rather offer different options and considerations. As developers, we should evaluate the abstractions we use, their portability, and how far removed they are from the low level.
We could think of them as a spectrum. It's not just about how far removed from that low-level API are we operating on, but where is this code going to live? What's its execution target? Is it going to be the browser, server? Are we going to be doing Cloud Functions? Perfect example, Node, Deno and the browser. Is this code going to operate in both the browser and Node? Maybe. Is it going to operate in Node and Deno? Probably not. How that code operates and how that code is approached is just another level of abstraction.
If we use a library that operates really well in the browser, chances are it could run in Deno but we don't know. So how far removed is it from that target? One that I'm really familiar with is the idea of cross-platform. We have one side the web and we have the one side native. Now, depending on where you are, where your team sits, you could be picking abstractions that are one degree removed from pure native or you could be picking abstractions that are one degree removed from just pure web. It doesn't matter if they're – don't look at them as if they're better or worse. Look at them as just being opposite ends of the spectrum.
This is stuff that we think about daily at Ionic where we think we have our abstractions sitting right at the middle. We give you access to the web, but we also give you access to native. Is that a middle ground? Is that better? Is that worse? The answer is kind of up to you, but it's just a different way of looking at what that code is. It's not necessarily better or worse. It's just going to give you the options. Understanding that code and abstractions are less about the performance impact, the actual level removed from low level. It's really about your code, performance size, and where is it going to live. We could have code that works in all of our devices right now, but in a few years, is it going to be able to work there? Are there going to be more platforms where this code can't run because it's using the wrong abstraction? As a team, evaluate what abstractions you are using, what their portability is, and also, how far removed are they from the low level? Those not discounting the hierarchy. I'm just saying, evaluate more on the spectrum.
Comments