Abstractions are beautiful in science and engineering, but what are they? In my definition an abstraction is: an interface that hides complexity. This concept is very powerful for building complicated systems and machines, and underpins our modern world.
I said that abstractions are very powerful, and with great power comes great responsibility. Consider the example of a brake pedal in a car. It is such a powerful abstraction that it can decelerate a multi-ton hunk of steel from 70 miles per hour to stopped in a few seconds, with no concious thought from the operator. More interestingly, it is designed to work reliably no matter the human operator's strength or the conditions of the road. It's extremely simple to operate safely, all the operator has to do is extend the strongest muscle group in their body - their right leg - corresponding to the amount of deceleration they want. Press it more than your tires have grip on the road surface? No problem, antilock-braking-system kicks in to brake less. Have weak legs? No problem, the brake booster system is multiplying your force. Don't know how hydraulic fluids, brake calipers, pads, rotors, etc are implemented? Doesn't matter, just press your foot on the big pedal.
That's a beautiful abstraction, just imagine a world where we didn't have it. Note that an abstraction doesn't mean that it's the only way to interface with the parts that implement it. For example some cars have something called "brake-based torque vectoring", which is a cool phrase for braking with the inside wheels while cornering. If a car is turning right, by definition the left wheels need to go further (spin more, spin faster, etc) than the right ones, and one way to acheive that is to apply some braking to the right wheels. So another interface to the brake system is the steering wheel! But because both the brake pedal and the steering wheel are fantastic abstractions, you never have to know those underlying features to get what you want out of the car. Therefore we would call the brake pedal a "clean abstraction", because it doesn't need knowledge of the complexity hidden behind it to use.
By contrast engineers call something a "leaky abstraction" if you can't use much of the functionality without understanding at least some of how the complexity is managed. Think about something with lots of buttons, dials, levers, ways to interact with and configure it. Lots of modern software UI is like this (think about Excel's or Photoshop's many buttons), airplane cockpits are like this, sailboats are even like this (though with ropes and pulleys, and symbolic flags, wind direction, etc). In truth there's no binary distinction between clean abstrations and leaky abstractions, there's a spectrum of leakiness depending on the design tradeoffs involved.
This blog is often about the Software Engineering profession, and what I notice about one of the differences between very-good software engineers and not-so-good ones are that the good ones appropriately manage complexity with clean abstractions. What we're ultimately doing in the job is moving electrons around on atomic-scale wires in silicon chips, but the profession is built on a bunch of abstractions so that you can do very powerful things with very simple code. Those abstractions are hiding immense complexity. A lot of software complexity is managing parallel computing because of the race conditions, deadlocks, etc that are introduced. An example of a clean abstraction for this problem space is the Actor Model, as implemented in the Erlang programming language, which I have the pleasure of using at my job. An example of a leaky abstraction to solve the same problems is maybe the pthreads library for the C programming language.
The concept of designing clean abstractions scales down to day-to-day writing code. I'll leave that as an exercise for the reader.