Tuesday, August 31, 2021

Why I Don't Yet Own an Electric Car

I'd really like to own an electric car. I'd like to fuel my vehicle at home. I'd like to routinely leave the house with a "full tank." I'd like to escape the tyranny of oil changes. I'd like to spare myself and the world noise from engines and emissions from tailpipes. I'd like to be part of the future of automobile travel.

So why am I still driving the gas-powered Nissan Rogue I bought two years ago?  I hate that car. Why don't I just dump it and go electric?

Given my past posts about the luxury-car pricing of electric vehicles (here and here), it'd be reasonable to assume that that's what's holding me back. I used to believe that myself. A recent test drive of a VW ID.4 taught me otherwise.

When the ID.4 was announced, it looked to be the first all-electric AWD compact SUV that wouldn't cost an arm and two legs. I put down a deposit on Day 1.

Before the ID.4, I didn't think very carefully about the features I wanted in an electric vehicle. EV price tags told me everything I needed to know: they were too expensive. Because the ID.4's price didn't constitute an automatic veto, I had to think about what I really wanted in a car--about features so important, I would reject cars lacking them. 

Most of the things I insist upon are so basic, it's hard to find cars that don't offer them. A power driver's seat, for example. However, there are two things I care about that are less than ubiquitous. The first is the ability to view the area around the car as if seen from above. This capability goes by many names, including bird's eye view and surround view. On my Rogue, it's called the Intelligent Around View Monitor. It's my first car with this capability, and though I hate the car, I've become so fond of this feature, I'd consider it an unacceptable step backwards to lose it. The ID.4 doesn't offer it, and when I performed the thought experiment of asking myself if I'd accept an ID.4 as a replacement for my Rogue for free and realized I'd turn it down, I recognized that a 360-degree camera was a non-negotiable feature for me.

That rules out not just the ID.4, but also Tesla's Model Y. For a car with as much tech as they pack into Teslas, it's surprising that they don't offer an all-around view capability. (My understanding is that Tesla has announced that this is coming as part of their self-driving option, but they haven't yet released it.)

My second must-have feature is a moonroof: an openable window in the top of the car. I've been hooked on these since a car I bought in 1995 happened to come with one. I think they're great, but modern automotive designers seem to think they can be replaced by giant glass roofs. None of Ford's Mach-E, VW's ID.4, Tesla's Model Y, Jaguar's i-pace, or Hyundai's IONIQ 5 offer a moonroof, but all offer a fixed glass roof. No moonroof equals no purchase for me, so this criterion eliminates all those cars.

That leaves only one candidate EV: the Volvo XC40 Recharge. It's a compact SUV, it's got AWD, and it offers a moonroof and a 360-degree camera. It's a hoot to drive, too, based on one of the most enjoyable test drives I've ever taken. (The sales rep made copies of my and my wife's driver licenses, threw us the keys to the demo car, and told us to drive it wherever we wanted for as long as we wanted.) Its infotainment system was particularly impressive, supporting the kind of natural language interactions I'm accustomed to having with my phone (and that are unavailable on the ID.4). 

Unfortunately, the XC40 Recharge has an EPA-rated range of only 208 miles. That's a problem, because one of the things I want to be able to do is take a day trip that's about 210 miles long. Any gas-powered car can do that, so I didn't even think about it when looking at EVs. It made me realize that I have a third non-negotiable feature: the ability to make a 210-mile trip on a single charge. Because EPA estimates are just that (estimates) and because nobody's going to drive a car to the point where it's completely out of fuel, I'm not going to seriously look at any EV with an EPA range under 235 miles. That knocks the XC40 off the board. 

The resulting board has nothing on it. There are zero compact SUV EVs offering AWD, a surround-view camera, a moonroof, and an EPA range of at least 235 miles.

Currently, it's not the cost of EVs that's keeping me from buying one, it's the failure of  EVs to offer the features I consider essential. I'll thus keep doing for a few more years what I've already done for what seems like an eternity: watching and waiting for the EV industry to produce a car that checks all my boxes. 


Friday, June 11, 2021

My Electric Car Search a Year Later: Modest Improvements

Exactly one year ago I wrote about my fruitless attempts to find non-luxury-priced fully electric (i.e., not hybrid) cars in three categories. Repeating my search a year later, this is what I found:

  • Little convertibles: nothing has changed. There was nothing then (at any price), and there is nothing now (at any price).
  • Used electric vehicles (EVs) with a range of 130+ miles for no more than $10,000: again, no change. I was unable to find a used EV with a range of at least 130 miles, no more than 50,000 miles on it, and a price of no more than $10,000. Upping the price limit to even $14,000 didn't help. Used EVs with even moderate range remain expensive.
  • Compact SUVs: Here, things have changed. Thee new models are available, and the price premium for getting into a compact SUV EV has dropped. For details, keep reading.

Changes in the Electric Compact SUV-scape

Last year, the only EVs in the compact SUV category were the Jaguar I-Pace and the Tesla Model Y. Since then, the field has expanded. How much it has expanded depends on how you define SUV. For my purposes, an SUV offers all-wheel drive (AWD), and that knocks cars like the Nissan Leaf, the Chevy Bolt and Bolt EUV, the Kia Niro EV, and the Hyundai Kona Electric out of the running. In addition, I don't count EVs that have been announced, but that you either can't currently order in the United States or for which no MSRP for the USA has been published. That rules out the Hyundai IONIQ 5, the Kia EV6, and the Nissan Ariya. 

That leaves three new contenders for the models from Tesla and Jaguar:

  • The Volkswagen ID.4.
  • The Ford Mustang Mach-E.
  • The Volvo XC40 Recharge. 

In my post last year, I focused on the cost of EVs compared to non-luxury ICE (internal combustion engine) equivalents, so that's what I'll do here. I'm not going to address differences in feature sets.

I went to the web sites for various non-EV compact SUVs and looked up the MSRPs for the cheapest AWD configurations I could find. Here are the results:

The average MSRP for these vehicles is $27,369. That's the price against which I'll compare EV prices. 

I'll apply the federal and state government incentives to EV MSRPs. That has the effect of reducing the MSRP by $10,000 for every manufacturer except Tesla. For Tesla, the reduction is only $2500, because Tesla no longer qualifies for the $7500 federal tax credit. However, Tesla buyers continues to get a $2500 EV rebate in Oregon, and since I live in Oregon, I'm knocking that amount off the MSRP for Tesla (as well as for everybody else).

That yields this:

The price premiums for Tesla and Jaguar keep them firmly in the luxury territory they were in last year. Volvo's 65% premium is somewhat less, but it's still well beyond the 55% price premium threshold for luxury cars that I derived in my last post. These EVs are luxury goods.

For the EVs from VW and Ford, the situation isn't as clear. They demand notable price premiums of 23% and 34% compared to ICE SUVs, but those premiums are well below the 55% average premium associated with luxury compact SUVs. A closer look at the data in my last post, however, shows that the average luxury car price premium at the bottom of the price ranges is 64%. That makes 23% and 34% look even better than they did when put up against the 55% category average. I think it's safe to say that for the VW ID.4 and the Ford Mustang Mach-E, the entry-level MSRPs fall below the luxury level. No compact SUV EV did that last year. This year, two do. That's a noteworthy development. 

The MSRP Problem

Unfortunately, MSRPs are a problematic basis for cost comparisons, because MSRPs are a lousy indication of pricing in the real world. They're suggested retail prices, and for most brands, dealers are free to mark them up or down as they wish. In addition, it's conventional at most dealers to haggle over prices. After MSRP adjustments and haggling, the price paid for a new car is often significantly different from the manufacturer's suggested price. When I bought a Nissan Rogue in 2019, for example, what I ended up paying was some 16% below MSRP. 

My understanding is that new car pricing is currently pretty firm, so it could be that these days you really do have to pony up MSRP (or more) at many dealerships. That's the thing about MSRPs. Sometimes they're higher than the prices people generally pay. Sometimes they're lower.

Demand for many EVs exceeds supply, and that puts dealers in a strong position during negotiations. When I talked to a local dealer about the Volvo XC40 Recharge, I was told there was at least a six month wait for delivery, and final pricing would be discussed only when the car was on the lot. I got essentially the same story at a local VW dealer regarding the ID.4. When I checked out a Kia Niro EV a few years ago, I saw that the dealer had added some $10,000 to the sticker price as a "market adjustment." It would not surprise me if MSRPs for EVs understate how much it actually costs to buy one.

My analysis of EV pricing versus ICE pricing is thus based on MSRP data that are of limited value. It's nice that those data show EV pricing in the compact SUV segment beginning to extend below the luxury level, but it's best to keep the customary grain of salt close at hand.

Beware Bottom Feeding

An additional weakness of my analysis is that I'm looking only at bottom-end MSRPs, i.e., the MSRP for the least expensive variants of the cars being considered. It's often impossible to find such cars on dealer lots. Few buyers want a bare-bones version of the car they buy, and even fewer dealers will resist the urge to add optional equipment to the cars they get from manufacturers. (This phenomenon doesn't exist for carmakers without a dealership network, e.g., Tesla.) Cars with bottom-end MSRPs are rarely sighted in the wild, so even if such MSRPs corresponded to the prices people pay (which they often don't), they would almost certainly convey information about only a small fraction of automobile purchases.

Still, my goal isn't to determine whether EV buyers do pay luxury prices for their vehicles, it's to determine whether they must. A year ago, manufacturers' pricing meant that they had to. This year, thanks to Ford and VW, that isn't the case. That's progress.

Wednesday, June 2, 2021

The Luxury Car Price Premium

Last June I blogged about how electric vehicles (EVs) were luxury goods. I'm gearing up to write a post discussing what's changed in the intervening 12 months, and it occurred to me that last year I asserted that an 80%+ price premium for EVs over their internal combustion engine counterparts puts them into luxury territory, but I didn't justify the claim. Doing so would require knowing what luxury cars cost, broadly speaking, compared to their non-luxury counterparts. I didn't know what the luxury car premium was. I decided to find out.

For the TL;DR among you, here's the executive summary:

  • For compact SUVs, it costs about 55% more to step up from a non-luxury vehicle to a luxury one.
  • For compact sedans, it's more like 75%.
  • For midsized sedans, it's around 90%.

If you care about methodology and details, read on.

Several carmakers have premium brands. Toyota has Lexus, for example, and VW has Audi. I think a reasonable way to calculate the luxury car price premium is to look at how comparable cars from carmakers with luxury-and non-luxury brands are priced. Given, say, a compact sedan or SUV, how much higher is a Lexus priced compared to a Toyota or an Audi to a VW?

I used the following brand pairs:

Non-Luxury Brand   Luxury Brand
Toyota   Lexus
VW   Audi
Hyundai   Genesis
Nissan   Infiniti
Honda   Acura

At Consumer Reports (paywall), I looked up price ranges for models of these brands in three categories: compact SUVs, compact sedans, and midsized sedans. For the bottom and the top end of the price range for comparable models (e.g., Toyota RAV4 vs. Lexus NX or Hyundai Elantra vs. Genesis G70), I calculated the price premium for the pair. I also averaged the bottom prices and the top prices for all the models in each category, and I calculated an average category price premium. Here are all the data:

Finally, I took the calculated results and rounded them a bit for the executive summary above. I rounded the computed 56% average price premium for compact SUVs down to 55%, for example, and I rounded the computed 92% average price premium for midsized cars down to 90%.

The data show that last year's 80%+ price premium for EVs (compared to non-EVs) put them squarely into the luxury car realm. There are a lot more EVs available this year, however, so things may have changed. In my next post, I plan to discuss whether they have.

Wednesday, June 24, 2020

The National Youth Science Camp

This month, the National Youth Science Camp (NYSC) took place for the fifty-seventh time. The camp is a remarkable institution that, in my view, remains too poorly known and too little appreciated. I attended in 1977, and my blogging about it more than 40 years later should give you some idea of the regard in which I hold it.

The Road to NYSC

My involvement with the camp began in 1976 with a remark by Dorothy Cunningham, a senior at my high school. She told me she'd been chosen as one of the top two graduating science students in the state and that as a result, she'd be attending a science camp in West Virginia all expenses paid. At least that's what I think she told me. We're going back over four decades here, and I didn't take notes. The gist of what I'm telling you is correct. The details may not be.

One point I know I got right was the all expenses paid part. That's not something I'd forget. At 17, my reaction was "Free vacation? Sign me up!" I suspect I was also thinking, "If she can do it, I can, too!" Ah, the brash ego of youth. Dorothy graduated number one in her class. I was a good student, but when I finished high school a year later, it wasn't me at the tip of the academic iceberg.

Fortunately, I didn't know that, and even had I, the brash ego of youth would probably have disregarded it. (Sometimes ego works in your favor.) I let my biology teacher know that I wanted to be considered for the following summer's NYSC, and he helped me do whatever had to be done to apply.

There was paperwork. I don't remember any, but there must have been. An application form, if nothing else. During my senior year in high school, paperwork was pretty much a leitmotif. Paperwork for college applications. Paperwork for scholarship applications. Paperwork for college admissions exams. This was the 1970s. None of this online nonsense. Paperwork meant paper.

At the time, I was under the impression that each state chose the top boy and the top girl in science in that year's high school graduating class, so when I was chosen for the camp, I was able to internally gloat that I was the best male high school senior in science in the state of Oregon. Take that, Dorothy, Cunningham--I'm as good as you!

I probably wasn't. Setting aside that she topped her class, and I didn't, she would have had to overcome the obstacles to scientific success that young women faced at that time. I was spared such obstacles, and in fact I didn't even recognize their existence until decades later. Kudos, Dorothy.

West Virginia offered two camp positions to the governor of each state, and different states selected their delegates in different ways. In 1977, some states, such as Oregon, chose one girl and one boy, but not all states did this. (Whether Oregon did it by happenstance or as a matter of policy, I don't know.) Probably no state made an attempt to identify the "best" graduating high school science students. The only state in which I was one of the two best science-oriented high school graduates was my state of mind.

That kind of realization is what happens when the brash ego of youth morphs into the weary realism of middle age.

Given fifty states and two free passes to the NYSC for each state, West Virginia was ponying up for 100 free vacations for science-oriented high schoolers, 98 of whom were not from West Virginia. And all expenses paid meant all expenses paid. Regardless of whether you lived in next-door Ohio or in far-off Alaska, West Virginia flew you to camp and flew you back home afterwards. That was a big deal in 1977. The air travel industry hadn't been deregulated, so flying wasn't cheap. To this day, I look back on West Virginia's program as an astonishing largesse.

What motivated such generosity? For that matter, what motivated the camp in the first place?

It was a state pride thing. 1963 marked 100 years of West Virginia statehood, and a big celebration was organized. The overriding theme was science (thank you, space race), and when the original goal of luring the annual Boy Scouts jamboree to the state proved untenable, West Virginia created its own jamboree-like event: a three-week camp experience combining science-oriented presentations, outdoor activities, and a brief trip to Washington, DC, for a shot of politics (e.g., a luncheon with US senators) and a dollop of sightseeing.

The camp went so well in 1963, the state decided to make it an annual event. It's been held almost every summer since, the lone exception being 1983, when primary funding was shifting from the state to a nonprofit set up for the purpose.

NYSC 1977

On one of my first days at camp, one of the other boys remarked that he had performed the Millikan experiment in high school. I was stunned. The kid had measured the charge on an electron while a teenager! There was no way I could compete with that. I was out of my league. Way out of my league. One of the top Oregon high school seniors in science be damned, I was lucky to be breathing the same air as this guy.

I eventually came to understand that the league we found ourselves in had a broader range of skills and experiences than I had expected. I fit in fine. 100 freshly-minted high school graduates from all the United States yields a wider variety of teenagers than you might suppose. Or at least than I had supposed. The more people you meet from different backgrounds, the more you recognize how much people's lives vary, even in groups as seemingly homogeneous as American high schoolers. The NYSC nudged me down the road of recognition that the more you learn, the more you appreciate how much you don't know. That realization is useful in science, but it's useful in life, too.

Most days at camp followed a routine. We awoke to a recording of The Rhododendron Song, which until I wrote this blog post I assumed was the state song of West Virginia. It's not. It's not even a state song. (They have four.) Instead, it's a well-known West Virginia camp song, provenance unknown. Both the song's tune and its initial words are as indelibly etched in my brain as if they'd been burned there with a branding iron:
I want to wake up in the morning where the rhododendrons grow...
It's a fitting song for a state where the rhododendron is the state flower.

After rising to the Rhododendron Song and scarfing down breakfast, the day's events began. The NYSC being a science camp, there was a calculated mix of science-oriented activities and camp-oriented ones. An important part of the science program was presentations by outside speakers, and what looks to me now like an exhausting series of topics probably looked to me then like one nifty treat after another. Space exploration, atomic energy, mining, immunology, entomology, genetics, satellite imagery...you can hit a lot of topics in three weeks.

Two presentations stand out in my memory. The most important was
"A Study of Forest Fires Utilizing Computer Modeling Techniques" by Steve Kessel. 
I liked fire as much as any other stereotypical teenage boy, but that wasn't what got my attention. It was the computer modeling.

In 1977, not many people (and certainly not many young people) had experience using computers. Personal computers didn't really exist yet. The Apple II didn't go on sale until the month the 1977 NYSC took place, and the IBM PC was still four years in the future. Computers at this time were big, expensive machines cloistered in special machine rooms. They had staffs to look after them. You saw computers in movies and on TV, but not in real life.

I was an exception. Thanks to  the foresight, initiative, and dedication of Kathy Reed, my mathematics teacher in seventh and eighth grade, I had programming experience that preceded the science camp by several years. I had never considered using computers to model things like wildfire behavior in forest ecosystems, but Steve Kessel's talk planted a seed in my mind that never went away. It germinated after I finished my bachelor's degree in biology and was pursuing a master's in computer science. The result--directly traceable to Steve's talk at the 1977 NYSC--was software that modeled behavior of a particular virus, Bacteriophage Lambda. (Details here, if you must know.)

The second presentation whose influence outlasted my time at camp was quite different. From what I understand, it was an attempt on the part of the camp's organizers to stir the pot a bit:
"The Scientific Case for Creation" by Gary Parker.
The stirring didn't have the effect they'd hoped for (it generated little discussion amongst the campers), but I was intrigued. I wasn't a creationist then, and I'm not a creationist now, but I felt that part of the scientific method was looking at evidence in different ways, and the creationist way of looking at the evidence for evolution was certainly different. Over the next couple of years, I read some creationist publications, and I spent time trying to determine whether speciation had ever been observed to take place. I ultimately lost interest in creationist challenges to the observations underpinning evolutionary theory, but I still think that applying a skeptical eye to accepted wisdom is an important component of the scientific toolbox.

Not all presentations were by outside experts. Some campers gave short seminars of their own. One was entitled "Helium-Neon Laser Caused Photo-oxidation in Isolated Mesophyll Chloroplast of C3 and C4 Plants," which I'm sure intimidated me as much then as it does now. Even I gave a talk. I could no more compete with helium-neon lasers as with the Millikan experiment, but the seminars didn't have to be technical, and I had bragging rights to something rather exotic by the standards of the time: I'd spent time in Iceland. The previous summer I'd been an exchange student to that country, so I offered a little travelogue called "Iceland on 973 Kronur a day."

The National Youth Science Camp put science front and center, but the camp part was an equally important component of the experience. There was plenty of hiking and backpacking and gathering 'round the campfire at night, but I'd done those things with my family, so they didn't make a huge impression on me. What did were the things I'd never tried before and might never have tried at all had it not been for the NYSC.

One was rock climbing, which I discovered requires a lot more hand and wrist exertion than I had imagined. I haven't found the need to do any rock climbing since, but my tiny exposure to it in West Virginia at least gave me a better appreciation for the enormity of Alex Honnold's accomplishment in Free Solo.

Many outdoorsy activities, including rock climbing, were conducted in small groups. You don't take a hundred inexperienced teens, at least some of whom think they're invulnerable (thank you, brash ego of youth), rope them up, and turn them loose on sheer rock walls en masse. Instead, you take a few to scale cliff faces, and you divide the others into different groups, thus affording them the opportunity to test their invulnerability in other ways.

Spelunking was such a way. I was excited as we donned our caving suits and put on our headlamps. What would we see?, I wondered, as we slipped into the earth. What I most vividly remember is what we didn't see. Some distance into the cave, our guide had us  extinguish our head lamps so we would know what true darkness--the absolute absence of light--was like. You don't forget your first encounter with utter blackness. At least I haven't. I don't know if this kind of experience is still possible, given the panoply of devices with glowing LEDs I'm sure campers carry with them these days, but it made a lasting impression on me.

Wriggling about underground was not my thing. It was interesting to do once, but it's dirty, cold, and physically demanding, and, based on my single experience with it, most of what's underground is brown or grey and just not that exciting to look at. However, I wouldn't have those impressions had I not given it a try at the NYSC. I'm grateful that I was able to.

Whitewater kayaking, on the other hand (another first for me), was fabulous fun. You don't so much sit in a whitewater kayak as wear it. It responds to every move of your body. I loved it. I also loved that before they'd allow you to get more than a few feet from shore in completely calm waters, you had to prove that you could get out of the kayak if it overturned. Proof involved pulling off the spray skirt and doing a somersault out of the kayak while upside down and under water. I left camp determined to whitewater kayak again. I never did, though in recent years I've done a little flatwater kayaking. It's not the same. I still hold out hope that I might revisit whitewater kayaking, but being now in my 60s instead of my teens, I'd probably shoot for water a little less white. I don't feel quite as invulnerable as I used to.

Beyond scientific presentations and outdoor activities, the NYSC also featured excursions to places such as the National Radio Astronomy Observatory, Washington, DC, and the site of the civil war Battle of Camp Allegheny. I'll spare you the details. By now, I hope you understand why I believe the camp is a unique undertaking.

NYSC 2020

This year's camp was virtual. SARS-CoV-2 (the virus that causes COVID-19) made on-site activities like spelunking, white water kayaking, visiting Washington, and waking up to the Rhododendron Song impossible. However, it didn't prevent the camp from offering an online-based program of lectures, directed studies, and interactive seminars on a raft of topics, including missions to mars, paleontology, colorectal surgery, electric vehicles, radio astronomy, 3D printing, machine learning, sleep, tapirs, and COVID-19, COVID-19, COVID-19. It made me wish I was 18 all over again, though perhaps this time with slightly less raging hormones.

The International Youth Science Camp

At some point, the National Youth Science Camp went international. It's had delegates from foreign countries since at least 1988, and in the ensuing thirty-plus years, over 400 campers from more than two dozen countries have taken part in and contributed to the NYSC experience. If contemporary camps have an impact on today's delegates akin to that of 1977's on me, the ripples emanating from West Virginia's 1963 centennial splash will continue to propagate for many, many years.

Monday, June 15, 2020

Blog problem should be fixed now

If you tried to access my blog post last week about how electric cars are currently luxury vehicles, you may have had the page hang trying to access alexgorbatchev.com. The problem should be fixed now. I used to rely on some scripts at that site to format code on my blog, but I have now eliminated the dependency.

I apologize for the accessibility hiccup.

Thursday, June 11, 2020

Electric cars are currently luxury goods :-(

Unusual circumstances led me to buy three cars in the past 12 months. I've been interested in buying an electric vehicle (EV), so in each case, I figured it was my chance to take the plunge. Alas, I ended up with three ICE (internal combustion engine) vehicles. The types of cars I wanted either didn't exist as EVs or they cost so much more than their ICE equivalents, I couldn't justify the extra expense.
This was a great disappointment to me. I understood that EVs would involve some sacrifices in cost, range, and amenities, but EVs are an established and growing market with models from over a half dozen serious manufacturers. I expected the EV-ICE gap to be reasonably small. I found that it's not.

Let's run through the details.

Car 1: The Compact SUV

Last year, my wife and I decided to replace our 2010 Subaru Forester with a new compact SUV. Compact SUVs are part of the largest segment of the US automobile market, compact crossovers. In 2019, more than forty models competed for market share. If you wanted an EV, however, you had only one option: the Jaguar I-Pace.

There may have been hybrids to choose from. I don't know. I rule those out on principle. I think it's silly to build a car with two means of generating power. So much more to maintain. So much more to break down. A hybrid's not an EV. It's an ICE car with an electric subsystem desperately chanting, "I think I can!" I'm not on board.

So...the Jaguar I-Pace. MSRP starts at about $70,000. In my state, government incentives knock $10,000 off that, but even if you could knuckle a dealer down another 15%, you'd still be looking at an entry point of some $51,000. Perhaps that's not unreasonable for a luxury SUV, but we weren't looking for a luxury car. We were looking for a car.

We ultimately bought a Nissan Rogue. It satisfied our two primary requirements (all-wheel drive (AWD) and a moonroof), and during our search, it looked likely that we could get it within our informal budget of $30,000. In the end, we paid less than $28,000.

The Rogue runs on gas. Upgrading from gas to electrons would have cost at least $23,000.

EV fans point out that EVs have lower maintenance and fuel costs, but those factors don't come close to covering a $23,000 up-front difference. Some claim that EVs tend to hold their value better than ICEs, but (1) nobody knows what resale values for today's EVs will be in the future and (2) my wife and I tend to keep our cars at least a decade. Actual purchase price means much more to us than theoretical resale value.

Earlier this year, another EV entered the compact SUV arena: Tesla's Model Y. From a financial perspective, the Model Y is the I-Pace all over again. The AWD Model Y starts at about $52,000 after taxes, fees, and government incentives. That's $24,000 beyond what we paid for the Rogue. Had the Model Y been available when we were shopping, we'd still have ended up with the Rogue.

Whether I-Pace or Model Y, moving from a gas-based powertrain to a battery-based one would have cost tens of thousands of dollars--a price premium of over 80%.

I thought a lot about how much of a premium I was willing to pay to shift from gas to electricity. I finally decided it was about 25%. I want to buy an EV, but I don't want to go broke doing it. Given that the Rogue ran around $28,000, that means my budget for a comparable EV would have been about $35,000. Both the I-Pace and the Model Y (had it been available) would have been at least $17,000 over budget. That's a lot of money. And neither car offered a moonroof.

Car 2: The Little Convertible

After nearly 30 years of listening to me whine about having a convertible, my wife told me to shut up and buy one. Talk had always been of a Miata, but when opportunity knocked, I looked forward to investigating my electric options. There weren't any. Smart's Fortwo convertible had been discontinued in North America a few months before I went shopping, and its laughable 57 mile range ruled it out, anyway.

In desperation, I looked into used Tesla roadsters. That car is more targa than convertible, but I figured I might be able to live with that. In 2019, Tesla roadsters were at least seven years old and started around 50 grand. New Miatas were easily had for well under 30. 'Nuff said.

Car 3: The Used Subcompact Hatchback

My wife recently decided we needed a little hatchback runabout. The car would get only occasional use, and never for long trips. Its range when fully fueled needed to be only 130 miles. "A perfect case for a used subcompact EV like a Leaf!" I thought. With a ceiling of 50,000 miles on the car and a budget of $10,000, I figured we'd have lots of choices.

We had zero choices. There are plenty of Leafs available, but when you throw in the constraint that the rated range has to be at least 130 miles, everything goes away. Leafs up through 2017 are rated at only 107 miles, and newer used Leafs start north of $17,000. Looking beyond Leafs doesn't help. Fiat 500es can be found for under $10,000, but the range is only 84 miles. Used Chevy Bolts have more than enough range, but they start at $19,000. We found nothing that came close to the range and price we were looking for.

We ultimately ended up with a Chevy Spark. Four years old, 25,000 miles, under $9000. Runs on gas, but range is 315 miles. If there's an EV that approaches those stats, I'd love to know about it.

EVs are currently luxury goods

For people with a luxury brand budget, my 25% premium for an EV may put them in a place where there are choices. For people like me who generally shop mid-trim non-luxury brands and want a comparable EV for no more than about 25% more than an ICE vehicle, those choices are absent.

Even the off-menu $35,000 Tesla Model 3 fails the test. Stripped to its essence, the Model 3 is a compact sedan that happens to be electric. The Toyota Corolla is also a compact sedan, but it runs on gas. MSRP for the bottom-end Corolla is $19,600. At $35,000, the most affordable Model 3 demands a 79% premium over the Corolla. (It also requires that you live with half the range: 220 miles for the Tesla, 435 for the Toyota.) There's a reason why Consumer Reports categorizes the Model 3 as a luxury compact car, while the Corolla  is simply a compact car.

To my dismay, nothing I've read suggests that in the next couple of years, EVs will make the transition from luxury items to mainstream consumer goods.  It's a disheartening conclusion. I'd be delighted to be proven wrong.

Saturday, September 7, 2019

A C++ Hall of Fame

Rock & roll has a hall of fame. So do toys. Fresh water fishing and towing each have one, and there's one for pretty much every kind of sport. I think C++ should have one, too.

CppCon, which starts in about a week, provides a natural setting for discussions about a C++ Hall of Fame. To get things rolling, I present the following proposal, on which I welcome comments. I won't be at CppCon, but I'll send a final version of the proposal to The C++ Foundation before the conference begins. Let me know what you think! (If there are a lot of comments, don't be surprised if I don't respond to each one.)

Proposal for a C++ Hall of Fame ("HoF")


The success of C++ is based on the efforts of many contributors, but a few have done especially significant work. A C++ HoF would allow the C++ community to formally recognize and honor contributors whose efforts have been unusually important.


The HoF will be run by a Steering Committee, whose size and makeup will be determined by the Standard C++ Foundation. Duties of the Steering Committee will include overseeing the nomination, selection, and induction of HoF members, as well as maintaining the HoF itself.

The Steering Committee will establish a Selection Committee, whose role will be to solicit, accept, and evaluate nominations for HoF membership. The Selection Committee will determine who is included in the HoF.

Membership in the Steering and Selection committees need not be disjoint. Membership may even be the same, but it may be preferable for some Steering Committee members to work only on HoF activities unrelated to nomination or selection of new HoF members.

Eligibility for HoF Membership

HoF eligibility will be determined by the Steering Committee.  I suggest that, initially, only people (living or dead) or teams (i.e., groups of collaborating people) are eligible for membership in the HoF. In the future, eligibility can be broadened (e.g., to permit companies and organizations), but I think it’s reasonable to begin with a people-only HoF.

To reduce conflicts of interest, no one involved in HoF administration is eligible to be selected for membership in the HoF. However, existing HoF members may serve as administrators, and former administrators are eligible for the HoF.


The nomination process will be determined by the Selection Committee.  I suggest an initial “anybody can nominate anybody” policy and a generous nomination period. If this proves unwieldy, more restrictive policies can be adopted.


Each year, the Selection Committee will choose no more than five nominees for inclusion in the HoF. Selection is an honor. Choosing too many new members would dilute the effect.

The primary criterion for selection is that the nominee has made one or more unusually significant contributions to the success of C++. Such contributions may have been made in the areas of design, specification, implementation, application, explanation, popularization, or any other aspect of C++ that the Selection Committee deems appropriate.

The Selection Committee may consider negative factors outside the realm of C++ when determining whether a nominee is worthy of HoF membership. If a nominee is guilty of a heinous crime, for example, the Selection Committee may take that into account when deciding whether to select the nominee for the HoF.


The Steering Committee will determine how inductions are to take place. I suggest that CppCon schedule an induction ceremony as part of its program, during which new inductees are awarded a membership token (e.g., certificate, trophy, gaudy ring) and given time to make public comments marking the occasion.

The first group of HoF members will be selected before CppCon 2020. This will make it possible for them to participate in an induction ceremony during the conference.


The Steering Committee will determine what form the HoF will take. I suggest beginning with a HoF web site (cpphof.org?) that showcases each member and summarizes the contributions that led to their inclusion.

Saturday, January 19, 2019

Adventures in UX disasters: The Pioneer AVH-2440NEX dimmer control

To provide a display for the backup camera I recently had installed on my car, I had a Pioneer AVH-2440NEX head unit installed in my dashboard. The display was distractingly bright at night, so I set out to dim it. The unit supports automatic night dimming, so I figured this would be easy. It is, but only after you've endured a UX hazing ritual of the kind that's distressingly common in the software industry.

On the AVH-2440NEX (and related models), there is a display setting called Brightness. It does not control the brightness of the display. It controls the blackness of the display. The brightness is controlled by the Dimmer setting. Dimmer has a range of 48 values, 1 to 48. Larger Dimmer settings decrease the dimness of the display, because Dimmer controls the display's brightness.

Values for Brightness (which do not control the display's brightness) are -24 to 24.

To summarize: The display brightness is controlled by a setting called Dimmer, which has a range of 48 values starting at 1, with higher values decreasing the dimness. The display blackness, in contrast, is controlled by a setting called Brightness, which has a range of 49 values that start at -24.


Think of all the professional developers--UX designers, programmers, QA people, managers--who had to sign off on this before it shipped to customers. I don't understand how they could collectively believe that this is a reasonable (much less intuitive) design for mainstream consumers.


Saturday, September 1, 2018

The Errata Evaluation Problem

I no longer plan to update my books to fix technical errors.

It's not that I'm too lazy to do it. It's that in order to fix errors, I have to be able to identify them. That's something I no longer trust myself to do.

If you write books and you're anything like me, you make mistakes. You can read and reread 'til your eyes bleed, test 'til your heart gives out, proofread 'til doomsday, and cajole the most exacting technical experts into reviewing your manuscript 'til they stop answering your email, and still you'll publish stuff that's wrong. Some of it will be laughably wrong. I don't know why. That's just the way it is. At least that's the way it's been for me.

Since originally publishing Effective C++ at the end of 1991, I've done my best to fix errors in my books as soon as possible after I found out about them. When I found out about a bug in printing n of a book, I normally worked with my publisher to fix it in printing n+1.

I most commonly find out about bugs from readers. They send email describing what they think is a problem, often including what they believe is a fix. If you look over my books' errata lists (links are at the bottom of this page), you'll see hundreds of problems I've addressed in response to reader reports. I'm grateful for every report I've received. Each time I updated a book to include fixes stemming from reader reports, I've updated the book's acknowledgements to include the names of the readers whose reports have improved the new printing.

In my experience, most bug reports are valid. But some are not. Sometimes readers assume that the compiler they use is Standard-conformant, but it's not. Sometimes they are unaware of or misunderstand provisions in the Standard. Sometimes they make mistakes copying the code out of the book before running their tests. Their best efforts notwithstanding, readers, like me, are fallible.

So when I get a bug report, the first thing I do is evaluate whether it's valid. Given the technical nature of my books, the complexity of C++, and the finickiness of my readers, this is often  challenging. Separating valid bug reports from (sometimes subtly) invalid reports requires I be at the top of my game. Otherwise, I risk rejecting legitimate bug reports or, worse, editing my books to incorporate invalid revisions.

Having retired from active involvement in C++ over two and a half years ago, I'm no longer at the top of my C++ game. That's been true for a while, but until recently, I've remained confident in my ability to assess incoming bug reports. Recently, however, a report came in where, having thought about it for a while, I realized that I just didn't know whether it was valid. Rather than give myself a crash course in C++ to the point where I could make an accurate determination, I decided to throw in the towel. I sent this to my reader:
As you may know, I retired from active involvement in C++ at the end of 2015, and in the ensuing two and a half years, I’ve forgotten enough details of the language that I am no longer able to properly evaluate bug reports regarding the technical aspects of my books. C++ is a large, intricate language with features that interact in complex and subtle ways, and I no longer trust myself to keep all the relevant facts in mind. As a result, all I can do is thank you for your bug report, because I no longer plan to update my books to incorporate technical corrections. Lacking the ability to fairly evaluate whether a bug report is valid, I think this is the only responsible course of action.
From now on, if you send me a bug report about technical material in my books, you'll probably get the same response.

This applies only to the technical material in my books. It just so happens that my brain here is only mostly dead. For the time being, I figure I can still evaluate the accuracy of reports about incorrect fonts, missing words, improper formatting, etc. So if you find an error of the non-technical variety, let me know. Heck, if you find what you believe is a technical error, go ahead and send it to me, if you want to. Just don't be surprised if what you get in response looks a lot like the reply above.


Saturday, June 16, 2018

Minor Change to Blog Charter

Until today, this blog has been about "Scott Meyers' Professional Activities and Interests." I've just removed the "Professional," so now the blog is about "Scott Meyers' Activities and Interests." In theory, this means I can now blog about anything, though in practice, you're unlikely to notice much change. I'm not planning anything dramatic. In fact, I'm not planning anything at all. I just thought it'd be a good idea to relax the blog's thematic constraints.


Monday, June 11, 2018

Interesting Book: The Modern C++ Challenge

I recently became aware of a nifty new book about C++, The Modern C++ Challenge. Today I saw that the ebook is available for $10, which strikes me as quite the bargain.

Before I tell you why I think the book is interesting, let me dispense with some caveats. First, I haven't read the entire book, I've only looked at parts of it. Second, I haven't looked closely enough at the source code to evaluate it. (Because the book uses some C++17 features and my involvement with C++ ended with C++14, I wouldn't really be able to fairly evaluate it, anyway.) Finally, I got the book for free when Packt sent me a (digital) copy.

Two things struck me when I looked inside the book:
  • The "Modern" in The Modern C++ Challenge is as modern as you can get: C++17 (with the occasional mention of C++20).  To run the solutions to the problems in the book, you'll need a C++17-conformant compiler.
  • The "C++" in The Modern C++ Challenge is broader than just the language proper and its standard library. The list of software used by the book includes over a dozen third-party cross-platform libraries, including Boost, Asio, Crypto++, Curl, NLohmann/json, PDF-Writer, PNGWriter, pugixml, SQLite, and ZipLib.
The book itself consists of a series of programming problems ("challenges") and sample solutions. Some are simple, such as Problem 1:
Write a program that calculates and prints the sum of all the natural numbers divisible by either 3 or 5, up to a given limit entered by the user.
Others are more difficult, such as Problem 22:
Write a small library that enables expressing temperatures in the three most used scales, Celsius, Fahrenheit, and Kelvin, and converting between them. The library must enable you to write temperature literals in all these scales, such as 36.5_deg for Celsius, 97.7_f for Fahrenheit, and 309.65_K for Kelvin; perform operations with these values; and convert between them.
All in all, there are 100 problems in a variety of areas, including string processing, dates and time, concurrency, cryptography, and networking.

Because the book isn't afraid to lean on third-party libraries, some of the problems ask you do to things that the standard library can't touch. For example, here's the last problem in the book:
Write a program that can identify people's faces from pictures. At a minimum, the program must detect the face area and the gender of the person. This information should be printed to the console. The pictures must be loaded from the disk.
Wow. Unless there have been big changes to the STL since C++14, there's no "gender_from_image" functionality in the standard library. I wouldn't know where to start. The book's solution begins with some really useful information:
This is yet another problem that can be solved using Microsoft Cognitive Services. One of the services available in this group, called Face API, provides algorithms for detecting faces, gender, age, emotion, and various face landmarks and attributes, as well as the ability to find face similarities, identify people, group pictures based on visual faces similarities, and others.
This is representative of what I view as a strength of the book: the ability to introduce you to libraries and APIs beyond standard C++ that you may not be familiar with. I think that's an important contribution to C++ and its effective application, and between that and the use of features new to C++17, I think it makes the book worth looking into.

The Modern C++ Challenge is currently available for ten bucks for the digital versions of the book and for $35 for the digital and print combo platter. I think that's very reasonable pricing, and, no, I don't get anything for encouraging you to look at the book, nor do I get a kickback of any kind on sales. I just think the book looks really interesting.


Thursday, May 31, 2018

CppCon Workshop on Giving Good Technical Presentations

On Sunday, September 23 (the day before the official beginning of CppCon), Andrei Alexandrescu and Kate Gregory and I will be leading a workshop on how to give good technical presentations. Between the three of us, we've made hundreds (thousands?) of presentations on countless topics to pretty much every kind of audience. We certainly don't know everything that works (or doesn't), but we know some things, and we're eager to share what we've learned.

The workshop is really three workshops in one. Most of the day will be spent in breakout sessions, with Kate, Andrei and me each running a session in our own way. Each workshop participant will spend one breakout with each of us.  The details will vary, but each session will feature a short presentation by each workshop participant, so if you're part of the workshop, by the end of the day, you'll have received personalized suggestions from each of us on what you did well and what we think would help you do better.

For details about the workshop, consult its web page.

This is an interactive workshop, so attendance is limited. Half the slots have been set aside for the conference to offer to first-time CppCon speakers. The other half are open to anyone who wants to improve their technical presentation skills. If that includes you, I encourage you to sign up for the workshop.


Wednesday, May 16, 2018

Effective Modern C++ in Simplified Chinese!

In mid-2015, I was told that translations of Effective Modern C++ into both traditional and simplified Chinese had been authorized. About a year later, the traditional translation showed up on my doorstop (as I noted here). It's been nearly two more years, but the other shoe has finally dropped: EMC++ is now available in simplified Chinese.

Like the original English edition of the book (but unlike most translations), the simplified Chinese version uses multiple ink colors. Readers should thus benefit from the information that conveys.

I'm pleased to welcome this translation into the Effective Modern C++ family. In theory, this makes the information in it accessible to over a billion additional people, so I'll be looking for O'Reilly to find a way to sell it to nearly all of them :-) If you'd like to be a customer, I'm told the place to buy the book--or at least a place to buy it--is here.


Saturday, May 5, 2018

New ESDS Book: More Effective C#, Second Edition

Addison-Wesley released Bill Wagner's new edition of More Effective C# last August, but I didn't find out about it and get a copy until a few days ago. The series editor is always the last to know!

If you're a C# programmer, I encourage you to give the book a close look. It's easy to do that, because Bill and Addison-Wesley have made unusually generous excerpts available at the book's web site (in the "Sample Content" tab): Chapter 2 (16 Items) is available as a freely-downloadable PDF, and Chapter 3 (8 Items) is available online. Together, that's nearly half the book you can read before you put down any money!


Monday, September 18, 2017

Brief Appearance at CppCon

This year's CppCon includes two panel discussions devoted to technical training, and I'll be on the one on Monday, September 25. Other members of the panel will be Giuseppe D'Angelo, Stephen Dewhurst, Kate Gregory, and Anthony Williams. The moderator will be Jon Kalb, who's also an experienced trainer. Together, we've probably indoctrinated many thousands of developers in the ways we believe to be right and just in the battle between programmer and machine.

Most people would probably date my work with C++ to the initial publication of Effective C++ in late 1991, but I'd been training professional programmers for several years before that, and since retiring from C++ involvement at the end of 2015, I've given a few more presentations on non-C++ technical topics (most recently a couple of weeks ago). All told, I have close to 30 years' experience training professional software developers, so I'd like to think I know a thing or two about it. To find out if I do, I encourage you to attend the panel session.

Monday will be the only day I'll be at the conference, so if you want to hunt me down to say hello, that'll be the day to do it.


Wednesday, July 5, 2017

Sales Data for EMC++: Print Books, Digital Books, and Online Access

O'Reilly President Laura Baldwin's recent blog post explaining O'Reilly's decision to discontinue selling individual books and videos through their web site (while continuing to publish books and videos for sale through other channels) inspired me to take a look at the sales data I have for Effective Modern C++. I wrote that book with both print and electronic publication in mind, assuming that by the time it came out, demand for digital formats would be at least as strong as demand for print products.

That has not proven to be the case. I have data for the first 35 months of the book's existence (through May 2017), and since initial publication, sales of digital editions make up only about 41% of the over 50,000 units (i.e., copies of the book) sold. Here's a chart of print sales versus ebook sales by month:
Because it takes more time to print books than to make them available on the Internet, the digital versions were downloadable four months before the print books came out. That's apparent at the left side of the chart. Since then, print sales have beaten ebook sales almost every month. Most of the time, it hasn't been much of a contest.

These data exclude sales of foreign language translations of the book. My royalty statements don't break down sales of translations into print and digital formats.

It's clear that buyers of EMC++ have a pretty strong preference for the paper version. This is consistent with sales data for my other books (Effective C++, Effective STL, More Effective C++), but those books were initially published before digital books took off, and they were never designed for digital consumption. The fact that print sales dominates for them is not a surprise.

O'Reilly is getting out of the retail book and video sales business in order to focus on its online subscription service, Safari. Baldwin states that that side of the business has the most customers and is growing the fastest. I don't doubt her. But what does that mean for me?

Here's the royalty source data for Effective Modern C++, broken down into "Online" sources (which includes Safari) and "Other." Included in "Other" is all sales of complete books, regardless of format. Ebook sales are thus "Other", not "Online".
As you can see, the online component of my royalties (including Safari) is generally under 10% each month. Summed over the course of the book's existence, the online contribution to my total royalties is only 5.7%.  There appears to be a slight upward trend over time, but it's hardly something that sets an author's heart aflutter. From a royalty point of view, sales of complete books is at least ten times as important to me as online access.

What do the data for Effective Modern C++ have to say about the trends in publishing Baldwin describes in her post?  Very little. A key observation in her post is that "digital enabled new learning modalities such as video and interactive content," and my book is an example of neither. She refers to how O'Reilly has long recognized that they aren't really in the book-publishing business, they're in the knowledge-spreading business. Books are one way to spread knowledge, but they aren't the only way, and from the perspective of a publisher, they are a way that's less and less important.

The charts above demonstrate that regardless of the general movement in the information-dissemination business towards digital, non-book-like, subscription-based models, complete books--especially print books--are, at least in the case of my readership, very much alive and kicking.

Friday, June 30, 2017

O'Reilly's Decision and its DRM Implication

On Wednesday, I got mail from Laura Baldwin, President of O'Reilly, announcing that "as of today, we are discontinuing fulfillment of individual book and video purchases on shop.oreilly.com. Books (both ebook and print) will still be available for sale via other digital and bricks-and-mortar retail channels...[and] of course, we will continue to publish books and videos..." So O'Reilly's not getting out of the book and video publishing business, it's just getting out of the business of selling them at retail. For details, check out Laura's blog entrythis story at Publishers Weekly or these discussions at Slashdot or Hacker News.

To me, the most interesting implication of this announcement is that O'Reilly's no-DRM policy apparently resonated little with the market. Other technical publishers I'm familiar with (e.g., Addison-Wesley, the Pragmatic Programmer, Artima) attempt to discourage illegal dissemination of copyrighted material (e.g., books in digital form) by at least stamping the buyer's name on each page. O'Reilly went the other way, trusting people who bought its goods not to give them to their friends or colleagues or to make them available on the Internet.

I don't know what motivated that policy. Perhaps it was a belief that trusting buyers was the right thing to do. But I can't help but think they took into account the effect it would likely have on sales. After all, publishing is a business.

Piracy is a double-edged sword. On the one hand, it means you receive no compensation for the benefit readers get from the work you put in. On the other hand, pirated books act as implicit marketing, expanding awareness of you and your book(s). They can also reach buyers who want to see the full product before making a purchasing decision or who wouldn't become aware of your book through conventional marketing efforts.

My feeling is that most people who choose pirated books are unlikely to pay for them, even if that's the only way to get them. As such, I'm inclined to think the marketing effect of illegal copies exceeds the lost revenue. I have no data to back me up. Maybe it's just a rationalization to help me live with the knowledge that no matter what you do, there's no way you can prevent bootleg copies of your books from showing up on the Net.

My guess is that a component of O'Reilly's no-DRM policy was a hope that it would distinguish O'Reilly from other publishers and would attract buyers who felt strongly about DRM. Whether it did that, I don't know, but O'Reilly's decision to stop selling individual products at its web site suggests that DRM (or the lack thereof) is not an important differentiator for most buyers of technical books and videos.

Wednesday, May 17, 2017

Interview with Me (in Hungarian)

Last month, I was invited to give a presentation at NNG in Budapest. During my visit to NNG, I was asked to talk with some people from HWSW, and the resulting interview has now been published. If you're comfortable with Hungarian (or with the results of a translation from Hungarian into whatever language you prefer), I encourage you to take a look.

In reading the interview, it may be helpful to know that the talk I gave at NNG was a shorter version of the presentation I gave at DConf earlier this month, "Things that Matter."



Tuesday, March 14, 2017

Keynote at DConf in Berlin on May 5

The folks behind the annual conference for the D programming language offered me a soapbox for my most fundamental beliefs about software and software development, so on Friday, 5 May, I'll be speaking in Berlin at DConf about

Things That Matter

In the 45+ years since Scott Meyers wrote his first program, he’s played many roles: programmer, user, educator, researcher, consultant. Different roles beget different perspectives on software development, and so many perspectives over so much time have led Scott to strong views about the things that really matter. In this presentation, he’ll share what he believes is especially important in software and software development, and he’ll try to convince you to embrace the same ideas he does.
Because this isn't a C++ talk, I sent the DConf organizers a more general bio than I usually use. It may include some things about me you don't know, so perhaps you'll find it interesting:
Scott Meyers started programming in 1971, and he started teaching programming in 1972. He’s best known for his Effective C++ books, but he’s also worked on constraint expression for programming languages, program representations in development environments, software simulations of bacteriophage lambda, general principles for improving software quality, and the effective presentation of technical information. In 2009, he received the Dr. Dobb’s Excellence in Programming Award, and in 2014, an online poll likened his hair style to that of the cartoon character, He-Man.
If you're working with or interested in D, I encourage you to consider attending the conference. If so, be sure to stop by and say hello after my talk!


Friday, February 3, 2017

By the Numbers: The Great Foreign Edition Book Giveaway

A couple of months ago, I offered to give away foreign editions of my books, asking recipients only that they reimburse me for the postage. Here are some numbers associated with the giveaway.
  • 112: Books I had to give away.
  • 70: Books I gave away. (There were no requests for the others.)
  • 65: People who requested books.
  • 37: People I sent books to. (It wasn't possible to satisfy all requests.)
  • 13: People whose requests overlooked the requirement to include a mailing address. (Such requests were moved to the bottom of the priority list. Some still got satisfied, because they were for books for which no higher-priority requests came through. In those cases, I pinged the requesters for mailing addresses.)
  • 21: Countries to which I was asked to send books.
  • 13: Countries to which I sent books. (It still wasn't possible to satisfy all requests.)
  • 26: Requests for Effective Modern C++ in Russian (the most frequently requested book).
  • 1: Copies of Effective Modern C++ in Russian I had to give away.
  • 5: Maximum number of books sent to any single requester. (These books were in Japanese, but the mailing address was in Sweden, and the request came from someone with an email provider in Italy, so it appears that an Italian in Sweden requested books in Japanese :-}.)
  • 905.65: Total cost of postage for books I sent (in US dollars).
  • 75.4: Percent of this cost I've so far been reimbursed.

Tuesday, January 31, 2017

Updated Versions of EC++/3E and EMC++

New printings of Effective C++, Third Edition and Effective Modern C++ have recently been published by Addison-Wesley and O'Reilly, respectively. Both printings include fixes for all the errata that had been reported through December, though a couple of bug reports for EMC++ have since trickled in, sigh. For EC++/3E, the new printing is number 17. For EMC++, it's 10.

If you purchased digital copies of these books from the publisher, you should be able to log in to your account and download the latest versions. (O'Reilly customers should have received a notification to this effect. AW doesn't seem to tell people when new printings are available for download.)

If you purchase print copies of these books, I encourage you to make sure you're getting the latest versions. I have copies of the latest printings, so I know they exist in print form.

I hope you enjoy the latest revisions of these books. They should be the best versions yet.


Wednesday, December 28, 2016

New ESDS Book: Effective SQL

SQL finally gets the effective treatment. That's an accomplishment, because despite an official ISO standard for SQL, there's enough variation among common offerings that the authors of Effective SQL felt obliged to test their code (e.g., schemas, queries, etc.) on six different implementations. They also point out syntactic and semantic differences between "official" SQL and the SQL you're probably using. 

Pulling off that kind of feat calls for lots of experience, both with SQL and with explaining it to others. Authors John Viescas, Doug Steele, and Ben Clothier have it in spades. They're pushing a century of IT experience (!), and they've published more than a half-dozen books on databases, SQL, or both. It's hard to get better than that.

If you work with SQL, you owe it to yourself to take a look at Effective SQL.


Tuesday, December 27, 2016

New ESDS Book: Effective C#, Third Edition

The third incarnation of Bill Wagner's best-selling Effective C# has flown off the presses, and a copy has landed on my desk. Apparently it's flying off the shelves, too, because it's currently Amazon's #1 new release in the category of Microsoft C and C++ Windows Programming. If you'd like the book to land on your desk as well as mine, you might want to place your order quickly.

This revision of Effective C# is part one of a two-park comprehensive update Bill is undertaking for both his C# titles (the other being More Effective C#). For details on the motivation for the updates and his thinking about them, check out Bill's recent blog post.

Happy C#ing!


Effective Modern C++ in Portuguese!

The latest addition to the Effective Modern C++ family goes by C++ Moderno e Eficaz and targets readers of Portuguese. My understanding is that the book's been out for a few months, but my copy arrived only a few days ago.

Like most foreign translations of EMC++, this one uses just one ink color, so if you're comfortable with technical English, I recommend the four-color English (American) edition. However, if Portuguese descriptions of C++11 and C++14 features is your preferred cup of tea, this is the brew for you!


Sunday, November 27, 2016

The Great Foreign Edition Book Giveaway

One of the nicer author perks is seeing your books appear in translation. In my 2003 Advice to Prospective Book Authors, I wrote:
Few things evoke quite the level of giddiness as seeing a copy of your book in a foreign script. I, for one, cherished my books in Chinese, and I continued to cherish them even after I found out that they were actually in Korean.
My publishers generally send me at least one copy of each translation they authorize. I often receive several copies, however, and over the years, I've amassed  more copies of my books in foreign languages than I have use for. Look!—these are the extra copies I currently have:

Instead of letting these books gather more dust, I've decided to give them away. Want one? Just ask. I'll autograph it for you and throw it in the mail, and all I'll request in return is that you cover the cost of postage.

I'll describe the details of how the giveaway works in a moment, but first let me show you the available inventory. Most books are in a language other than English, but what I'm technically giving away are foreign editions, so a few have the same text as the US book (i.e., they're in English). Such editions are generally printed on cheaper paper than their US counterparts, and like almost all the books I'm giving away, they use only one ink color, even if the US version uses multiple colors.

Here's what I've got:

Things to bear in mind:

  • For books with two ISBN lines, each line represents a distinct ISBN for the book. The upper one is the older ISBN-10. The lower one is the newer ISBN-13. (ISBN-10 vs ISBN-13 is the publishing equivalent of IPv4 vs. IPv6.)
  • Sometimes there are multiple versions of the same translation, e.g., there are two entries for German and for Japanese translations of Effective C++, Third Edition. In such cases, the only difference is typically the cover design. As far as I know, the substance of all translations of a particular book into a particular language is the same.
  • In the table, "Chinese" is ambiguous, because there are two versions of printed Chinese: traditional and simplified. To find out which Chinese is meant, use your favorite search engine to look up a book's ISBN.
  • I've tried to list accurate languages for the books, but, not being able to read most of them, I may have made a mistake here and there. If so, I apologize, and I hope you'll bring the errors to my attention.
  • The first two editions of Effective C++ are either old or really old. Both are out of date. They might be suitable for a C++ museum, or maybe you could employ them as research material for that Scott Meyers biography you've been working on (ahem), but the programming advice in these editions is not to be trusted. I'll send them to you if you ask me to, but before you make a request, think carefully about why you're doing it. It shouldn't be to improve your C++.

How the giveaway works:

  • If you'd like a book, send me email letting me know what you want and the address to which I should send it. If you'd like more than one book, that's fine, just list the books in priority order. (I'll ignore book requests posted as comments to this blog, sorry.)
  • I'll let the requests roll in for about two weeks (until about December 9), then I'll decide who gets what on whatever basis I want. My general plan is to assign higher priority to earlier requests and to issue everybody one book before issuing anybody more than one (i.e., to use a pseudo-FIFO pseudo-round-robin algorithm), but my plan might change. If your request includes an unusually good reason to satisfy it, I'll increase your priority. (An example of an unusually good reason would be that you'd like books to stock a library, thus making them available to many people.)
  • At some point (by December 16, I hope), I'll let you know whether I can satisfy your request. If I can, I'll put your book(s) in the mail, let you know how much the postage is, and request that you send me that much by Paypal. As it happens, I've gone down this road a couple of times in the past, and some of the promised payments never materialized. Nevertheless, my faith in the basic honesty of C++ software developers endures. I'd appreciate it if you wouldn't do anything to change that.
Soooo...who wants a book that I can't read, that's out of date, or both?


Monday, November 21, 2016

Help me sort out the meaning of "{}" as a constructor argument

In Effective Modern C++, one of the explanations I have in Item 7 ("Distinguish between () and {} when creating objects") is this:
If you want to call a std::initializer_list constructor with an empty std::initializer_list, you do it by making the empty braces a constructor argument—by putting the empty braces inside the parentheses or braces demarcating what you’re passing:
class Widget {
  Widget();                                   // default ctor
  Widget(std::initializer_list<int> il);      // std::initializer_list ctor
  …                                           // no implicit conversion funcs

Widget w1;          // calls default ctor
Widget w2{};        // also calls default ctor
Widget w3();        // most vexing parse! declares a function!    

Widget w4({});      // calls std::initializer_list ctor with empty list
Widget w5{{}};      // ditto  
I recently got a bug report from Calum Laing saying that in his experience, the initializations of w4 and w5 aren't equivalent, because while w4 behaves as my comment indicates, the initialization of w5 takes place with a std::initializer_list with one element, not zero.

A little playing around showed that he was right, but further playing around showed that changing the example in small ways changed its behavior. In my pre-retirement-from-C++ days, that'd have been my cue to dive into the Standard to figure out what behavior was correct and, more importantly, why, but now that I'm supposed to be kicking back on tropical islands and downing piƱa coladas by the bucket (a scenario that would be more plausible if I laid around on beaches...or drank), I decided to stop my research at the point where things got complicated. "Use the force of the Internet!," I told myself. In that spirit, let me show you what I've got in the hope that you can tell me why I'm getting it. (Maybe it's obvious. I really haven't thought a lot about C++ since the end of last year.)

My experiments showed that one factor affecting whether "{{}}" as an argument list yields a zero-length std::initializer_list<T> was whether T had a default constructor, so I threw together some test code involving three classes, two of which could not be default-constructed. I then used both "({})" (note the outer parentheses) and "{{}}" as argument lists to a constructor taking a std::initializer_list for a template class imaginatively named X. When the constructor runs, it displays the number of elements in its std::initializer_list parameter.

Here's the code, where the comments in main show the results I got under all of gcc, clang, and vc++ at rextester.com.  Only one set of results is shown, because all three compilers produced the same output.
#include <iostream>
#include <initializer_list>

class DefCtor {

class DeletedDefCtor {
  DeletedDefCtor() = delete;

class NoDefCtor {

template<typename T>
class X {
  X() { std::cout << "Def Ctor\n"; }
  X(std::initializer_list<T> il)
    std::cout << "il.size() = " << il.size() << '\n';

int main()
  X<DefCtor> a0({});           // il.size = 0
  X<DefCtor> b0{{}};           // il.size = 1
  X<DeletedDefCtor> a2({});    // il.size = 0
  X<DeletedDefCtor> b2{{}};    // il.size = 1

  X<NoDefCtor> a1({});         // il.size = 0
  X<NoDefCtor> b1{{}};         // il.size = 0
These results raise two questions:
  1. Why does the argument list syntax "{{}}" yield a one-element std::initializer_list for a type with a default constructor, but a zero-element std::initializer_list for a type with no default constructor?
  2. Why does a type with a deleted default constructor behave like a type with a default constructor instead of like a type with no default constructor?
If I change the example to declare DefCtor's constructor explicit, clang and vc++ produce code that yields a zero-length std::initializer_list, regardless of which argument list syntax is used:
class DefCtor {
  explicit DefCtor(){}             // now explicit


X<DefCtor> a0({});           // il.size = 0
X<DefCtor> b0{{}};           // il.size = 0 (for clang and vc++)  
However, gcc rejects the code:
source_file.cpp:35:19: error: converting to ‘DefCtor’ from initializer list would use explicit constructor ‘DefCtor::DefCtor()’
   X<DefCtor> b0{{}};
gcc's error message suggests that it may be trying to construct a DefCtor from an empty std::initializer_list in order to move-construct the resulting temporary into b0. If that's what it's trying to do, and if that's what compilers are supposed to do, the example would become more complicated, because it would mean that what I meant to be a series of single constructor calls may in fact include calls that create temporaries that are then used for move-constructions.

We thus have two new questions:
  1. Is the code valid if DefCtor's constructor is explicit?
  2. If so (i.e., if clang and vc++ are correct and gcc is incorrect), why does an explicit constructor behave differently from a non-explicit constructor in this example? The constructor we're dealing with doesn't take any arguments.
The natural next step would be to see what happens when we declare the constructors in DeletedDefCtor and/or NoDefCtor explicit, but my guess is that once we understand the answers to questions 1-4, we'll know enough to be able to anticipate (and verify) what would happen. I hereby open the floor to explanations of what's happening such that we can answer the questions I've posed. Please post your explanations in the comments!

---------- UPDATE ----------

As several commenters pointed out, in my code above, DeletedDefCtor is an aggregate, which is not what I intended. Here's revised code that eliminates that. With this revised code, all three compilers yield the same behavior, which, as noted in the comment in main below, includes failing to compile the initialization for b2. (Incidentally, I apologize for the 0-2-1 ordering of the variable names. They were originally in a different order, but I moved them around to make the example clearer, then forgot to rename them, thus rendering the example probably more confusing, sigh.)
#include <iostream>
#include <initializer_list>
class DefCtor {
  int x;
class DeletedDefCtor {
  int x;
  DeletedDefCtor() = delete;
class NoDefCtor {
  int x;    
template<typename T>
class X {
  X() { std::cout << "Def Ctor\n"; }
  X(std::initializer_list<T> il)
    std::cout << "il.size() = " << il.size() << '\n';
int main()
  X<DefCtor> a0({});           // il.size = 0
  X<DefCtor> b0{{}};           // il.size = 1
  X<DeletedDefCtor> a2({});    // il.size = 0
  // X<DeletedDefCtor> b2{{}};    // error! attempt to use deleted constructor
  X<NoDefCtor> a1({});         // il.size = 0
  X<NoDefCtor> b1{{}};         // il.size = 0
This revised code renders question 2 moot.

The revised code exhibits the same behavior as the original code when DefCtor's constructor is declared explicit: gcc rejects the initialization of b0, but clang and vc++ accept it and, when the code is run, il.size() produces 0 (instead of the 1 that's produced when the constructor is not explicit).

---------- RESOLUTION ----------

Francisco Lopes, the first person to post comments on this blog post, described exactly what was happening as regards questions 1 and 2 about the original code I posted. The only thing he didn't do was cite sections of the Standard, which I can hardly fault him for. From my perspective, the key provisions in the C++14 Standard are
  • ([over.match.list]), which says that when you have a braced initializer for an object, you first try to treat the entire initializer as an argument to a constructor taking a std::initializer_list. If that doesn't yield a valid call, you fall back on viewing the contents of the braced initializer as constructor arguments and perform overload resolution again.
  • 8.5.4/5 ([dcl.init.list]/5), which says that if you're initializing a std::initializer_list from a braced initializer, you copy-initialize each element of the std::initializer_list from the corresponding element of the braced initializer. The relevance of this part of the Standard was brought to my attention by Marco Alesiani in his comment below.
The behavior of the initializations of a0 and b0, then, can be explained as follows:
X<DefCtor> a0({});  // The arg list uses parens, not braces, so the only ctor argument is
                    // "{}", which, per ([over.ics.list]/2) becomes an empty
                    // std::initializer_list. (Thanks to tcanens at reddit for the 
                    // reference to

X<DefCtor> b0{{}};  // The arg list uses braces, so the ctor argument is "{{}}", which is
                    // an initializer list with one element, "{}". DefCtor can be
                    // copy-initialized from "{}", so the ctor's std::initializer_list
                    // param contains a single default-constructed DefCtor object.
I thus understand the error in Effective Modern C++ that Calum Laing brought to my attention. The information in the comments (and in this reddit subthread) regarding how explicit constructors affect things is just a bonus.

Thanks to everybody for helping me understand what was going on. All I have to do now is figure out how to use this newfound understanding to fix the problem in the book...