All posts by Benjamin Vulpes

AGI needs goals, and satisfying curiosity has to be the first

I spent some time with ChatGPT last night, out of curiosity about the state of the art and how close we might be to runaway artificial general intelligence (AGI). I’m entirely underwhelmed at its inability to model conversational state, its incuriosity towards interlocutors, the obvious polite/inoffensive response templating, and just how far the AI industry appears to be from achieving anything remotely capable of passing for a human.

The rationalists are convinced we face a high risk of AGI going into runaway mode, where it relentlessly optimizes itself, establishing enough control over enough humans that in the large “we” (for some value of we) won’t actually be able to turn it off. Matthew Ward works an example through the lens of Facebook, saying something along the lines of “there’s a ghost AI embedded in Facebook’s myriad of recommendation systems that has financially motivated a bunch of people to prevent turndown: Continue reading AGI needs goals, and satisfying curiosity has to be the first

Andrew Parker’s Sybil-Resistant User-Operated NFT Minting Mechanism

Never mind that NFTs have rolled off the hype cycle’s peak of inflated expectations and now grind through an unknowably-long trough of disillusionment! Let’s revisit Andrew Parker’s mechanism for end-user NFT minting, and make some technical cleanups and tweaks such that NFT contracts extract maximum fees from minters.

NB: there’s no code in here, so if you’re expecting to find something to copy/paste into the contract that some ding dong on Fiverr is paying you to cobble together, you can just scram, kid. As I say at the office from time to time, my job is (tragically) not to write code any longer, but to help you figure out what code to write.

Definitions

  • Minting
    Creating a new token in an NFT contract.
  • Premine
    Old-school scam wherein a select number of individuals operate a blockchain in secret and private before exposing its critical values to the rest of the internet for public mining, thereby safely reserving an unholy pile of the shitcoin for the initial operators themselves without competition against the rest of the universe of hashpower. Satoshi is the original premine case, which is how you know that Bitcoin is a scam.
  • Gas
    The cost of including a transaction in an Ethereum block. Dynamic, like Bitcoin transaction fees, based on current demand for block space.

Current Minting Challenges

NFT drops, premints and user-operated minting and so on generally suffer on a few common axes: mishandled manual allocations, sophisticated contract operators out-performing naive humans, and egregious gas fees.

Manual allocations are when NFT contract authors (or their marketing agencies) sell or give away individual tokens or token-minting rights before the contract hits the blockchain[1]In some cases, the NFT contract can be updated by its authors or maintainers, but I’ll neglect this case for now, excommunicating such misbehavior as cryptographic heresy. Manual allocations are sometimes implemented with some kind of pre-computed list (dumb) embedded in the contract (wasteful) blessing specified addresses with permissions to call various NFT minting methods, or in the dumbest possible cases, the contract authors themselves are the only ones allowed to “mint” NFTs and then variously hand the tokens out or auction them. All of the above implementations are stupid, poorly factored, and generally suck (and moreover point towards the comic ignorance of NFT contract authors of pretty much all prior art in the space), but can be understood in the context of contract authors attempting to milk their mints/drops for as much end-user cash as possible.

A smaller number of Ethereum contracts by JavaScript developers with delusions of grandeur (those who bother to look will find a Lisp in the historical detritus. No points for guessing why that never made it into the DevRel propaganda…) attempt to solve this problem by hardcoding rules like “any given wallet can only mint N tokens per Q blocks” into the contract. I find this even more tragically stupid than the premine strategies (which are at least not stupid and intellectually honest insofar as the implementation is saying: “these are my enn eff tees and you can have them for a price that I set”), because it conflates individuals with addresses, something that Bitcoin lore disposed of purt goddamn near a decade back. The poor schmucks who attempt this strategy are so unfortunate that nobody around them is smart enough to whisper “sybil attack” in their ears, and so they go about blissfully unaware of the entire corpus of literature until they release their contract and it gets pwned on day zero by someone with a college-prep high-schooler’s mathematical savvy. This is like inventing scalable session handling by storing session data in individual web heads, pushing that sticky session notion into your load balancer, and then wondering why new nodes in your autoscaling pool don’t serve as much traffic as old nodes. In 2027.

Egregious gas fees are the final failure mode I find worth talking about, because these are typically also a symptom of unqualified engineers mucking about with mathematical systems they don’t really understand. During exceptionally hype-frothy NFT minting event the sheer number of people attempting to call methods on the popular contracts to mint tokens explodes the demand side for Ethereum block storage space. Naturally, those who bid the highest get their transactions confirmed, and everyone else misses out. Not just everyone else competing for block space to support the particularly popular transaction, but everyone on the entire Ethereum network now competes against folks tryna get their mitts on the latest cryptowhatever, which is not just a spectacular waste of the NFT squad’s money (hey, I love me a deflationary cryptosystem, don’t get me wrong), but of everyone’s money who might be attempting to use Ethereum for…something useful. Assuming such applications exist. But I digress.

Design Goals

  • Low gas fees
  • Arbitrary users can mint NFTs
  • No off-chain trust mechanisms
  • Minting mechanisms can’t be spammed
  • NFT authors capture some fraction of the demand otherwise spent on gas fees
  • Thwart front-running

Design

Proof-of-work.

That’s probably not enough to go on (tee hee hee), so I’ll sketch out the fundamental mechanism for those unfamiliar with how Bitcoin solves this exact same problem.

The minting method must accept payment, and has a signature of:

mint :: str -> ()

Where that str argument is the nonce used to prove that work has been done.

Hashing implementation

  1. Concatenate:
    1. mint function caller’s address
    2. supplied nonce
  2. Hash output of 1.

Difficulty (and the ultimate input)

Bitcoin adjusts difficulty every so often by comparing how quickly blocks were generated with a desired production rate and then ratcheting up or down the required number of leading zeros from the output of hashing some well-known data (neé nonce).

In an NFT implementing this interface, you’ll track difficulty in the exact same way: calculating how many leading zeros your hash function needs to output in order for the contract to consider the nonce valid for NFT minting.

Since mining is a proxy (syntactic sugar) for the minter’s ability to buy the NFTs they want to mint, shouldn’t we just give folks the ability to buy NFTs over the counter, without any of this complicated hashing stuff? If the buy-side is prone to literally throwing money away on gas fees during times of competition for block space, how can we capture that cash that’s otherwise being lit on fire during minting races?

To effectively capture the gas market, simply add the order of magnitude of wei sent along with the minting transaction to the number of leading zeros from the hash output, and if the total number of zeros is greater than the current difficulty number, mint a new NFT.

Departures from Parker

  1. Dynamically calibrate difficulty after every minting event to ensure desired output characteristics
  2. Incorporate payments to augment pure hash difficulty
  3. Don’t require the previous token’s hash in minting
    This is probably the most controversial proposal. I contend that if you check to see if difficulty needs adjustment after every single minting event, you can ensure that even if an infinite number of mintings are submitted in a single block, the adjustment recalculation will ensure that as soon as your difficulty threshold exceeds that which is supplied in the infinite series, all other minting transactions will be tossed. For this we have the serial nature of block construction in Ethereum to thank 🙂

Design Goal Evaluation

  • Low gas fees
    Check, gas auction dynamics are captured by the payable minting function, and concatenating the number of zeros of wei along with the leading zeros of the hash output to get final hash strength.
  • Arbitrary users can mint NFTs
    Check.
  • No off-chain trust mechanisms
    Check.
  • Minting mechanisms can’t be spammed
    Check.
  • NFT authors capture some fraction of the demand otherwise spent on gas fees
    Check.
  • Thwart front-running

References

References
1In some cases, the NFT contract can be updated by its authors or maintainers, but I’ll neglect this case for now, excommunicating such misbehavior as cryptographic heresy

The hateful jealousy of those who cannot

On the way to dropping the children off at school this morning, we espied a truly noxious plume of smoke right around the corner from Cedar’s school. To satisfy my morbid curiosity, after I shipped Cedar to his first day of first grade (!), Tallulah and I took a slight detour to check out what looked to be a truly magnificent pyre of modern hydrocarbons.

Lo and behold, when we pulled onto the offramp, an entire ad-hoc unhoused enhousement had tragically gone up in flames:

I disembarked, wandered up to get a quick look, and asked how long they expected to hold us up on the offramp, to resounding shrugs from WSDOT and firefighters alike.

Being joyously a new owner of a truck fully equipped for most reasonable offroading situations, and still wanting to get my daughter to school not terrifically late, I effected a two-point turn, and went bumping into the median between the offramp and the highway. Only to be accosted by some standard-size American in a broken down Ford sedan something or other: “YOU STUPID FUCK!”

This is just what you have to expect from the chronically oppressed American. They know they can’t get or do anything, and their response is to get absolutely infuriated when they see other folks they can’t understand aren’t cattle like themselves to raise the spectre of rule-following and fairness.

Following the rules is for schmucks. Those who can, do. Those who cannot, endure. I have a truck capable of getting me out of minor binds like “pulled off on an exit that was immediately closed right in front of me”, and frankly the Ford in question could absolutely have driven up the shoulder back to the highway junction, even if it wasn’t capable of navigating the ditch. But! Its pilot is tragically cursed by the American prole’s mental capture by the local rule system, and can’t comprehend how anyone else would be willing or able to break those rules.

I’m rubber, you’re glue etc.

Fixing pocket doors with captured-nut hangars

The captured-nut pocket door hangers my 2005-vintage pressed-shitboard house came with are the absolute fucking worst.

This bolt (that threads into carriage running on the pocket door rails behind the moulding)…

…will back out of the threads on the carriage over time.

When it does, one side or the other of the pocket door will drop down to the floor, and leave you with the threaded part of the nut poking up out of the door. Good luck getting a wrench up behind the molding to screw it back into the carriage.

Since this has happened to me on 3 separate pocket doors in my house over the last year, I have tried umpteen different approaches to getting these bolts back into their carriages and the doors rolling smoothly, and I have finally developed a formal process that works every time. It’s a giant pain in the ass, but it is at least less obnoxious than staring at a cockeyed door poking out of the wall that you CAN’T EVEN USE TO CLOSE OFF THE SOCIAL PART OF THE HOUSE FROM THE CHILDREN AFTER BEDTIME, or flailing un-directedly at the problem with no plan.

Trust me, I’ve lived both of those stories. This repair method works, and doesn’t require that you take off moulding or make any other destructive repairs to the foamed-wood-product buttbox Americans call houses.

The fix.

  1. Detach the pocket door from the other hangar. In my experience, this is always the “shallow end” of the door, that makes contact with the wall when the pocket door is closed.

    Rotate the retaining clip into its non-retaining position, lift the door up, and push the bolt out of the receiver on the top of the door:
  2. Remove the bolt that has unscrewed itself from the carriage from the other receiver at the other end of the door. In my experience, this is always the “deep end” of the door, that recesses way way way back into the wall.
  3. Thread the bolt from 2 back into its carriage.
  4. Tie a string around the bolt from 2 in such a way that you can yank on it for a bit before it comes untied, but use a knot that will come undone after a reasonable amount of wiggling so that you don’t end up with a string stuffed up in your pocket or heaven forfend, dangling over your door causing a permanent eyesore.
  5. Using a prybar, shim the door so that the bolt-receiver is juuuust below the z-height where the bolt would slide into the receiver:

    Protect your shitty plastic laminates from the metal! The children do enough damage to the house already, you don’t need to compound it while effecting a fix.
  6. Position a chair such that you can gently lean on the prybar with one foot.
  7. Lever the door up just enough for the nut to slide into the receiver, and pull on the string from 4 until you get that satisfying *click* indicating the bolt-head is firmly seated in the receiver. You will have to wiggle the door up and down while pulling on the string in order to get it past a detent.

    If the string comes off the bolt, go back to step 4.
  8. Rotate the clip back into position.

    To hang the door on the second hangar, you can use the exact same technique, or take an easier approach:
  9. Lever the door up until the bolt-receiver is in the appropriate position.
  10. Using a long, thin rod (I recommend small-diameter carbon fiber tubes, an essential tool in my toolbox of weird), push the bolt into the receiver until it clicks

    The reason that you can’t do this for the “deep end” of the pocket door is because you simply cannot get a rod into the gap that the door recesses into in such a way that you can push on the bolt. Instead, you need to pull on it, which has been the source of pretty much all of my howling about how to fix these doors.
  11. Slide the door into the recessed position, and using your long thin rod (or whatever, a knife will work at this point), rotate the retaining clip into position.

Voilá, you have a properly-rehung door again. You also know how to reset it after the children slam it against its stops fifty times and that accursed bolt backs out again.

Suja is the entirety of my vegetable intake

Praises be to Motoя, patron god of profligate energy use, my local Costco is once again stocking this highly refined vegetable sunlight. I love how Suja is refined America: dense, oil-intensive, targeted at the niche health nut Americans(tm) like me, not tasty at all and sold in bulk at  my favorite American icon of the feedstock of life.

I can now drink two or three salads a day again! Phytonutrients are important and I otherwise live on prosciutto and mozzarella slabs (again, from Costco). I’ll save the rest of my Costco odes for another day, but in the meantime, drink a salad!

Suja in particular is an awesome veggie drink in that it has none of those non-caloric sweeteners. I object to Stevia and the other variously weird invert sugars on the basis that they rewire the reward pathways that drive biological sugar-intake bookkeeping. Think about it: if you halve, over the course of the day, the number of calories that you ingest from sugar while maintaining your body’s perception of the sugar-calorie intake, by (for example) switching to diet soda, your homeostatic intake expectation will remain constant, and you’ll actually crave more sugar.

Just say no to synthetic sweeteners and flavors. Instead, chug Suja and Spindrift (Spinnies, as I overheard from some bros at Costco one time: “Should we get Spinnies?” “You can never have too many Spinnies…”).

 

Your children aren’t trying to piss you off, they’re confirming that you get pissed off at them

When talking to parents about the universal trials of parenting young children, I frequently say something like “they’re not really trying to piss us off so much as they are doing the things that they know provide them agency in the world, and it’s just a tragic fact that the easiest way for them to soothe their own fears about not having agency is for them to wind us up. The important thing in managing these interactions is that the children understand that there are limits to what they can effect in the world: a hot stove will burn you, if you nag enough at Dad, he’s simply going to switch over into default-no mode, and so on (hard limits and boundaries are critical for healthy adult relationships as well, but that’s a topic for another time).

“Practicing agency and finding limits” doesn’t cut it for me anymore, and this is what evolved my models.

Surfing Uncertainty passed me by so completely and absolutely because it landed very nearly precisely at the leading edge of the most recent lacuna between my quinquennial reviews of the latest and greatest developments in neurological/cognitive science. Since the women I shack up with seem to be invariably and strongly neurodiverse, a deep dissatisfaction with mainstream interpretations of the neuro/cognitive mechanisms underlying autism and ADHD kicked off my most recent review of the state of the art. Scott Alexander’s review is fantastic (par for his output) and more-or-less forced me to buy and read Surfing Uncertainty (a great call).

Instead of synthesizing the ADHD/autism spectrum notes from Scott’s review (please read the linked review, as I’ve not written my own and he’s a far better/more exhaustive/creative/hyperconnecting writer than I), I’ve got some brief notes on the implications of the Predictive Processing (henceforth PP) model for parenting.

One of the core paradigms of the PP model is that the mammalian Terran deoxyribonucleic lifeform’s primary loop is to wiggle itself around in the environment to generate stimuli for its own receptor networks that it can use to ground-truth and improve its predictions of what the world will throw at it next. Empirical and synthetic breakthroughs in the most recent decade validate this perspective: for example, the fusiform gyrus, commonly known in pop-sci for driving facial recognition has been experimentally shown to be less of a facial recognizer and far more of a predictor of faces in images[1]When, in a brain-imaging study, a specific tone is played before a face is shown to the subject, the fusiform gyrus begins to associate the tone with the subsequent display of a face and so exhibits … Continue reading, and cutting-edge text processing and image recognition machine learning systems are built on a foundation of generating complete texts or images from fragments, and improving the generated output based on correction from subsequent input of complete texts or images.

The adaptive mammalian neurocognitive model of PP goes a step further, suggesting that there’s very little difference between what we’d classically call the outputs of the motor system and the inputs of the sensory system. Rather, the sensori(predicto-)motor system is in a constant loop of self-excitation to minimize errors between the predicted sensory inputs and the actual sensory inputs (for if we did not actively chase new inputs, error minimization would seem to drive us into a dark corner where we could reliably predict inputs with low error and high confidence. If this reads like the depressive loop, I don’t think that you’re far off).

I’ve long espoused that the developing human has one job: to identify, seize, yank on and otherwise twist the various knobs and levers of agency afforded to in the world, and determine what effect they can have on the world. Predictive processing offers a refinement on this.

Kids then, are simply trying to generate stimuli that they can use to fine-tune their predictions about the world. Parents are some of the most influential personalities in kids lives (and one hopes the safest to experiment against), so they are necessarily going to do their darndest to identify the regimes that we kick into and what the children can do to kick us into those regimes.

It’s not that the children are deliberately being assholes, winding us up, making us mad, so much as they are biologically-fated to make predictions about their world and then attempt to get data to confirm and fine-tune those predictions. They know that we, their parents, can move into different emotional states, and so they are going to do their best to predict what those states are and the events they have to emit in order to transition us into the desired state.

A tired child who doesn’t feel loved is going to engage in the easiest possible loop to get the emotional attention that they need. They don’t have the sophistication to understand that a fight is going to suck for hours afterwards and eventually wear down the relationship’s strength (that’s our job as the adult), all that they know is that they haven’t gotten the emotional investment or demonstrations of love that they on a deep level need in order to feel secure, and they’re going to get you to engage with them in any way possible.

This obviously sucks in the evening when everyone is tired and emotional regulation is at its most difficult. This is why it’s so important to have regular evening and dinner and bedtime routines, and to stay flexible with their implementation subject to everyone’s abilities. Sleep schedules are regulated by early morning and early evening light, so sit on the porch together in the morning before school, and take a walk in the sunset together. These regular moments of closeness and being together will feed their need for emotional closeness (provided you stay off your damn phone for the duration. Children are boring, this is the hardest job you’ll ever have, get the fuck off your phone and be present. Future-you will appreciate it, as will the small ones). Children thrive on routine, so make sure it’s the same every day, but don’t fixate on hitting all the marks every day. It’s fine if someone doesn’t brush their teeth some nights. You’ll have a way better relationship if you, the adult, can understand when to insist on tooth-brushing because you can do so in a kind and gentle way that doesn’t escalate an already tense environment, and when to not insist on tooth brushing because everyone’s already on edge and it’s more important to bring the emotional tone down so that everyone’s calm as they lie down in bed! Nothing is absolute, and while having a routine is important, hitting the broad strokes of the routine is vastly more important than every single note. You wouldn’t start a whole song over at the campfire because you flubbed a D-minor, would you? Total buzzkill…

As always, treat everyone with love and kindness. Seek to understand their motivations and empathize with them, so that you can get them what they need in order to be happy people. Folks, including small children, will go out of their way to help you, if they believe that you understand them and are doing your best to help them.

It is OK to get pissed at them though! It’s important to people’s personal development that they understand the impact their actions have on others.

References

References
1When, in a brain-imaging study, a specific tone is played before a face is shown to the subject, the fusiform gyrus begins to associate the tone with the subsequent display of a face and so exhibits a higher degree of activity than when a face is displayed without a preceeding tone. Scientists involved interpret this to suggest that the FG is not identifying faces, but predicting that faces will be in subsequent images.

Berlin 2022 day 1

Manning and friends were to arrive around 15:30, which gave me an entire morning to snooze, find a croissanterie, take my rings to the park and have a nice lazy workout in the sun. If you bring your gym with you, you never have to worry about finding a gym!

I focused really hard during this trip on calibrating my circadian rhythm with sunlight queues. Up at a reasonable hour, sitting at a café in the sun by 09:30 to get loads of sunlight in my face, and then being out biking as the sun went down. Worked exceptionally well, I was calibrated onto local time by the second day, almost trivially (helps that I kicked the process off by eating an unreasonably large amount of THC edibles to knock myself out on the flight from Portland to Reykjavik. Before I passed out, I did spend what felt like an eternity being Far Too High in the window seat.).

I got a bunch of cheeses and cured meats to welcome the boys after their trip from Frankfurt.

Regardez! Paradis du fromage:

Eventually the Alexes and Victor arrived, and we were off to the races! Everyone mounted a velo-steed, and we proceeded to procure Budweisers and various big-brand beers at the kiosk. Alex had recently swapped clips on his bikes for flats, and while carrying 2 or 3 liters of beer in his hand, lost footing on his bike, dropped the beers, and nearly sliced the tip of his finger off. This lovely gentleman appeared out of absolutely nowhere, and staunched Alex’s bleeding just enough for us to bike over to a hospital and get the repair process started.

Alex is notorious for injuring himself on his bike during adventures.

The remaining three of us posted up on the banks of a nearby canal, drank our beers, and trolled swans (humans in this shot are not in our party).

Bless their souls, the fellas had lined up dinner with a friend of theirs in venture capital in Berlin. We got jumped to the front of the line at a hot Korean fried-chicken joint, and I challenged myself to rise to whatever spicy level the Koreans wanted to eat. Lo, did I sweat.

Apres, the Koreans invited us to a literally-and-figuratively underground karaoke joint, poured endless Heinekens into our faces, and insisted on shoving vodka shots down as well. Gracious me, but do those folks love to drink. At a certain point, I had to bow out of the drinking, but realized that entailed leaving a beer 3/4ths unconsumed so that they’d not try to push another one on me. One of our compatriots had sung opera for many years before going into tech recruiting, and it was amazing to hear her pick up on pop-song melodies for songs she’d never heard before and harmonize on the spot. Humans are amazing!

At something absurd like 3 in the morning, with Alex fully exhausted from several hours waiting for glass extraction and re-stitchment of his hand, we emerged from karaoke and biked home. On the way, I discovered precisely what Germans think about American food:

Humiliating.

Berlin 2022 day zero

I’ve been sitting on tickets to see Seeed since 2019, and my friend Alex pointed out that the concert was actually happening this year, and that I better book tickets and lodging if I intended to see them this decade. Kara graciously picked up the childcare slack for a  five-day sojurn (two of which will be occupied by travel). This is very sub optimal trip design in that I’ve not amortized the very expensive part, the plane tickets, across a longer trip. However, I’ve been trying to see this band for about two decades (during which they lost a vocalist, RIP Demba).

I flew from Portland to Reykjavik (sedated myself with edibles right into oblivion), and then woke right up for the transfer and to get bright morning light in my eyes to start recalibrating my circadian rhythm).

Hello, mountain!

In the Schengen passport control in Reykjavik:

The whole world runs on Nginx, dontcha know?!

Icelandair won’t let you put your bags on the floor in the exit row during takeoff and landing, as takeoff and landing are when very nearly most aircraft problems hit. The 22 year old fight attendant was very stern with me about this, which veritably gave me the tingles.

Icelandic women are impossibly, ethereally, brain-meltingly beautiful. Imagine the Teutonic, Brunhilde-esque paragon of cancelled Aryan wet dreams, and add in a touch of the fey, and an English accent like you’ve never heard. Their children are also adorable, and that is all that I shall say on that topic.

I would have loved for this eco-lid to be awesome, but it turned out to just suck.

I’m exposing myself to the human flux along the  canal (augmented by motherfucking SWANS), crash-calibrating my circadian cycle to local time by getting real live sunset rays into my eyeballs (it’s important that your brain sample the sunlight as the fire god himself drifts below the horizon…), and sampling local brews. Next step is to get some more beers, bike around the abandoned airport, and then rustle up some dinner before stopping in at the jazz club (Donau115) that I just discovered around the corner.

Signing off from the canal!

Mobility warmup for upper body resistance training

Warmup and flexibility training discipline is a limiting factor for performance development in every sport I’ve ever engaged with.

This is a highly time-efficienct warmup/mobility/stretching routine to run before engaging in an upper body resistance training session.

Instructions:

Go through the whole list, doing 5, then 10, then 20 seconds (or repetitions for the moving stretches) for each exercise and side if the exercise is asymmetrical. Also known as a “circuit”.

Exercises

  1. Arm across chest
  2. Arm up and behind head
  3. Supinate wrist (asymmetric, perform stretch with opposite hand)
  4. Rotate both wrists, right wrist turning clockwise, arms at 90deg to torso
  5. Rotate arm through full shoulder range of motion, going upwards in front of the torso
  6. Supinate both wrists together in prayer hands in the small of the back
  7. Rotate both wrists, right wrist turning counterclockwise, arms at 90 degrees to torso
  8. Pronate wrists against each other in front of the torso
  9. Rotate shoulder open (palm presses against a vertical surface, arm parallel to the ground and fully extended, rotate torso so that the arm is behind the torso and the stretch mostly in the pectorals and anterior bundle of the deltoids)
  10. Rotate head clockwise
  11. Rotate head counterclockwise

Frederick Delavier’s Stretching Anatomy is an essential book on this topic.