Monday, April 30, 2018

Color words in the Book of Mormon

I was listening to this fascinating RadioLab episode the other day that really opened my mind to the fact that the way we identify colors is a totally cultural phenomenon. An American can stare at a bunch of green squares and fail to see that one of them is completely different from the others because you've always been taught to categorize all those colors the same. Someone from the Himba tribe in Namibia can be shown a bunch of squares and fail to see that one of them is actually cyan, for the same reason. Your eyes are physically built the same way, but your linguistic paradigm has caused your mind to process the images you see in a completely different way.

And apparently researchers have found that ancient cultures develop words for colors in a fairly consistent order, starting with White and Black, then moving on to Red, usually Yellow, and so forth. Blue is pretty consistently the last color that ancient cultures developed a word for.

So this morning during scripture study, I got curious to see how this played out with colors in the Book of Mormon. I'll warn you ahead of time, this is a super rough, back-of-the-napkin type of analysis, and not scientifically rigorous at all, so take it with a grain of salt. But I did find some interesting patterns that I thought I'd share.

I downloaded the Gutenberg project's plain text files of the Book of Mormon, and two other texts to compare:

  1. The Bible: Since the Book of Mormon was purports to be a book of scripture written by people who left Jerusalem for the Americas around 600 BC, and since it was translated into language that mimics the King James Version of the Bible, you can't get around comparing the Book of Mormon to the Bible. It's 2-3 times as long as the Book of Mormon. If I had more time, I'd have liked to compare different sections of the Bible, since they were written at different times, and (in some cases) in different languages.
  2. Last of the Mohicans: This work of fiction was published a few years before the Book of Mormon was. It has about half as many pages. It deals with wars including European settlers and Native American people during the French Indian War (prior to the American Revolution), and the author (James Fenimore Cooper) lived in the same region of the United States as Joseph Smith during this time period.
Then I threw together a LINQPad script to parse all the words out of these books and look for any of the words that Wikipedia lists as common colors in English, and started digging in.

The first thing I had to do was throw out the words "Silver" and "Olive" because those are always used as nouns in the Book of Mormon, not as colors. Having done that, I found what some other people had already noticed: There are very few color words in the Book of Mormon. Of over 20 color words I was searching for, the Book of Mormon only had four: White, Red, Black, and Grey, and they appeared a total of 45 times.


James Fenimore Cooper, by contrast, used eight of these common color words, but managed to pack 274 of them into half the space.

 
The Bible, with as long as it was, had a still broader assortment of color words, but I suspect some of them (navy, lime) are probably not used as colors.


One thing that fascinated me is that Blue is not only present in the Old Testament (and apparently not in the New Testament), but actually very common. This totally bucks the trend laid out in the Radio Lab episode I listened to, and merited a little research. Apparently the color Blue was (and is) very important to the Jewish people, as some of the cloak tassels required by the Law of Moses are supposed to be dyed blue (tekhelet). Tekhelet was a dye made by boiling the blood of a certain species of sea snail. The process to make that dye was lost around 1300 years ago, and only recently rediscovered, but it definitely played a big role in Old Testament culture.

So, what happens when we put all of this in one chart?


The Bible and Book of Mormon are pretty on-par with each other when it comes to the most common colors, White and Red. Last of the Mohicans and the Bible see similar occurrences of Blue and Green. The Bible has a good dose of Purple, which doesn't show up at all in the other two texts. And, as we noticed earlier, Last of the Mohicans blows the other two books away with its use of White, Red, Black, Gray, and Yellow.

If you suppose the Book of Mormon is really what it purports to be (and I do), this points to a significant linguistic shift from the Book of Mormon peoples from the time they left Jerusalem. It's likely that they lost the ability to make Tekhelet, as well as the purple dyes (also apparently made from sea snails) that were an important part of the Temple decorations and High Priest's garments. The Bible frequently uses the color green to describe the lushness or vitality of plants; perhaps the Book of Mormon landscape made that distinction less important than it was in the area around Jerusalem.

On the other hand, if you suppose the Book of Mormon was just made up by Joseph Smith, then this is just an indication that he was not a very descriptive author. Colors don't show up very often in the other Standard Works, either.

On the gripping hand, this is a tiny corpus, and maybe we shouldn't try drawing any conclusions from such a rough-and-ready analysis. Maybe we need to bring in more books to get a better feel for the standard variation, and divide the scriptural books by author or time period for more nuance.

Take your pick.

Wednesday, November 01, 2017

Family History Work You Can Do in 15 Minutes

  • Family History Work You Can Do in 15 Minutes
    Children:
    • Ask your parents to help you choose a question from https://goo.gl/ECSdXj and ask one of your parents or grandparents to answer the question for you. (You can even call or facetime someone if you aren’t near enough to ask them in person.) You may find that you want to have several questions ready so you can hear more stories. :)
    • Start a journal. You can record it digitally or on paper. If you haven’t learned to write yet, ask someone to write while you tell them what to write. Or draw a picture and then have someone write down what the picture is about. Be sure to keep whatever you do in a safe place so you can someday share it with your own kids.
    • Do the monthly family history task in the Friend magazine. It’s called Family History Quest and you can do it in the hard copy of your magazine or online here.
    • If you have learned to type, you can try indexing. Go to https://goo.gl/Dsh17G to learn how. Learning will take about 15 minutes. Then come back another day and choose a beginning indexing project. They usually take about 15 minutes. You will probably want to stick with beginning projects until you get good at reading cursive.

    Adults and Teens:
    • Download the “Take a Name” app to a phone or tablet and link it to your family tree. (It will find names in your family tree that are ready to have their temple work done. All you need to do is print the cards and take them to the temple. The app may take 24 hours to find names, but it can do it in the background while you do other things. If you can, please give a one-time donation so the app makers can keep the app updated and bug free. This is not a Church affiliated app, though it is made by members of the Church.)
    • Go to https://goo.gl/ECSdXj and choose one of the questions, then record your answer to this question in a journal, in a computer doc, or in an audio version. If you want to preserve the answer for posterity, go to familysearch.org and click on memories and you can upload it (you can scan handwritten items or photos, or you can upload typed or audio files).
    • Go to https://goo.gl/ECSdXj and choose a question to ask an older relative. (Or go visit someone in the Legacy branch and ask them; you’ll make their day!) Be sure to record the information for posterity in either written, typed, or audio form. Then upload it to familysearch.org and link it to the person who told you the story. For an explanation on how to do that do a search for “upload memories to FamilySearch” on youtube and watch the video that most closely matches what you are trying to do (or ask your ward consultant for help).
    • Try indexing. Go to https://goo.gl/Dsh17G to learn how. Learning will take about 15 minutes. Then you can come back another day and choose a beginning indexing project. If you end up not having time to finish it right then, you can save it and come back later to finish. (Projects not finished after a week will be turned over to someone else to finish.)
    • Gather all your own family history documents (birth certificates, marriage certificates, etc.) and put them in one place.
    • Use the “My Family” booklet to record family stories and memories for yourself, your parents, and your grandparents. It’s available online; get the instructions for using it here; or you can buy a hard copy of it at the LDS Distribution Center (or online) for 50 cents. If you do the hard copy, then ask someone to help you transfer the information to familysearch.org when you’re done so the stories can be preserved and shared with posterity.
    • Use the “Find Your Family Names” pamphlet to get started on family research. It has three different tracks to use depending on whether you have no family history done, some done, or a lot done already, so it can be useful no matter what level of family history has already been completed in your family and no matter how much you know about doing family history. You can access that pamphlet online here or purchase a hard copy at the LDS Distribution Center (or online) for 50 cents.
    • Scan and upload family photos to familysearch.org (especially historical photos) and tag the people in the pictures. You can also doing this using the “Family Tree” (i.e. FamilySearch) app on your phone (you can even scan using your phone, so this can be a good option if you don’t have a scanner).
    • Go and look at your family tree on familysearch.org. (To sign up, all you need is the membership number on your temple recommend [or from your ward clerk], if you want to be able to do temple ordinances for ancestors. Signing up will only take you a few minutes and they will talk you through the process online. Or you can ask your ward consultant for help.) If you look at your family tree in portrait mode, you will see ancestors with record hints and you can start by looking at these and seeing what is helpful to you.
    • Go to https://www.familysearch.org/partneraccess and sign up for a free account with one (or more) of these other genealogy websites. I recommend starting with https://www.ancestry.com/. Signing up will only take a few minutes, then be sure to let them link to your family tree on familysearch.org. Come back in a day or two and see what “hints” have appeared (look for the leaf with a number by it at the top near your name, after you sign in). You can filter for a specific family or just browse starting at the top. They’ll walk you through what to do and you can spend as much time as you’d like each time you visit (they pretty much never run out of hints).
    • Download the “Family Tree” app (it’s the familysearch.org app) or just go to https://www.familysearch.org/photos/people and choose a person in your family. Once the person’s info is pulled up, click on the memories tab and look at the content that has already been uploaded. See what new things you can learn about that family member. If you have memories of your own you’d like to share (photos, audio, written accounts, etc), you can upload them using the app or your computer.
    • Play around a little with the “Family Tree” app or the familysearch.org website
      • Search for historical records.
      • Look for ancestors with tasks (the tasks are usually relatively simple and they walk you through it).
      • Look for ancestors ready for temple work. (Look for ancestors with a temple icon near them. Then click on it and see what is needed in order for you to take them to the temple. Some of them just need you to reserve their names and print their cards.)
      • Find out how you’re related to people around you who are also using the app (you both have to have the app open and agree to look for the relationship at the same time).
      • Record your own memories, etc.
    • Reconnect with relatives you haven’t seen for a while by phone, email, Facebook, etc.
    • Start a journal. Try to establish a regular time to write. Maybe on Sunday evenings or as a family during Family Home Evening
    • Tell your kids stories from your childhood and stories you’ve heard from your parents, grandparents, etc.
    • If a lot of your family history work has already been done and you don’t know what else to do, try going to puzzilla.org. It is a branch of FamilySearch and they will walk you through various options that can help you figure out where there is still work to be done.
    • Contact your ward consultant and ask them to help you figure out where to start. They’ll be happy to be able to magnify their calling!
    • Family history libraries are also a wonderful resource. They are staffed with knowledgeable people who are ready to help.

Sunday, January 24, 2016

Thank God for Clothing

Today I am grateful for clothes.


Clothing is something that people in First World countries typically have plenty of. My wife and I hate shopping, and we do as little of it as we can get away with. Yet somehow, it seems we've always got at least a few items to donate whenever a donation truck comes by looking for clothes. We are by no means extravagant--we typically shop at the same thrift stores that we donate our clothing to--but we definitely have far more clothing than we really need. I count myself very fortunate, because there are a lot of people in the world who make do with little or no clothing.

Even if we ignore the impact that clothing has on our outward appearance, let's consider the practical survival impact of clothing. Having a clean change of clothes is a crucial factor in avoiding lice and various skin diseases. When working, clothing can protect us from scratches and other wounds. Most importantly, in many climates, having proper clothing is a necessity for survival, as it protects us from cold weather that could otherwise be lethal.

If you dress in layers, clothing can be adjustable: you can remove some articles if you start feeling too warm, or add layers if you're feeling cold. You can save money and natural resources by adjusting your thermostat to a moderate temperature and using clothing to regulate your comfort level.

Clothing does not require batteries, a plug outlet, or fuel. In a major emergency, you may have to go without heating, power, or water, but your clothing will keep on functioning. How cool is that?

Tell me why you're thankful for clothing in the comments below.

Sunday, January 10, 2016

Thank God for Ovens and Stoves

This is the second in my series of gratitude-oriented posts. Several of my posts will be about modern appliances that are so common as to be taken for granted here in the United States. This one is about ovens and stoves.


Some people say that our ability to cook our food is what made it possible for us to be human--that without pre-processing meats and vegetables via an external heat source, we would never have been able to feed our brains the number of calories they require in a day. And over time, human beings have come up with a wide variety of ways to cook food.

Most cooking methods throughout history were smelly, dangerous, and expensive. In rural areas, people had to spend an enormous amount of time gathering and chopping wood. As more people moved into cities during the Industrial Era, many people still couldn't afford their own ovens--except when they paid a baker, their menu was limited to that which could be cooked in the fireplace, perhaps with a pot or spit hanging over the fire. The lucky ones would "slave over a hot stove" (literally the same stove that they used to heat their homes--it would have been very uncomfortable) all day to make food for their family. And it was not at all uncommon for people's stoves or chimneys to burn their entire house down.

Most people throughout history could never have even dreamed of being able to simply "turn the oven on" when they were ready to cook food. That's not even mentioning the other standard features of a modern range: a temperature control, timer, window, and adjustable racks; multiple stove-top burners with separate temperature controls--heaven!

If you live in a first-world country today, you most likely own a gas or electric range, or at least a little toaster oven. So let's spend a moment thinking about how much more difficult life would be without it. Let's also remember that many, many people in the world today still don't have that luxury. And let's thank God for this magnificent appliance.

Saturday, January 02, 2016

Thank God for Snow

One of my New Years Resolutions for 2016 is to spend more time feeling gratitude.
To this end, I will be writing a series of blog posts dedicated to highlighting things I am thankful for. This is the first of those posts.

Thank God for Snow

Snow
Thank God for Snow!

Snow comes at the time of year when we receive the least warmth and light from the sun. Covering the ground, its whiteness reflects the sunlight back up at us from all directions, brightening our day and spirits. Its crystalline facets glisten in the sunlight, giving us the impression of walking through a world blanketed with diamonds. What beauty!

Snow also comes at the coldest time of the year. Forming snow from the water in clouds is an exothermic process, releasing heat into the air, and keeping our winters from being quite as cold as they might otherwise be.

Snow serves as a natural insulator. Snow on your roof helps to keep the heat in your house from escaping into the sub-freezing outdoor temperatures. The layer of snow and ice on a lake protects the hibernating aquatic creatures beneath from the worst winter temperatures. When temperatures drop low enough, people and animals will fare far better in a snow cave, or in "robes beneath the snow" than they would exposed directly to the elements.

At high elevations, snow becomes a natural reservoir. As temperatures rise, it automatically releases water to the lower lands during the spring and summer months when it is most needed. This is particularly poignant to people like me, living in a desert valley at the foot of the Rocky Mountains, but it affects everyone downstream, all the way to the coast--not to mention those who buy food that was grown using that water.

Thank you for taking some time out of your day to read some of my reasons to be thankful. Why are you thankful for snow? Share your thoughts in the comments area below.

Thursday, February 05, 2015

Incremental LESS Builds with Gulp

I spent the last few days trying to get an incremental build running for our LESS files using Gulp. I had a really hard time finding a single resource with all the information I needed, and spent a lot of time in trial-and-error, so I thought I’d share the fruits of my labors here.

Background

Our company leverages LESS heavily for building themed, bundled CSS files. We were previously using Web Essentials to have these files get built for us. This was an imperfect solution, but we put up with it because it worked… until it didn’t. Once I realized that Web Essentials wasn’t working, I looked into some other options and determined that GulpJs seemed to be the best option.

Benefits

GulpJs offers some awesome benefits, only a few of which were available with Web Essentials.

  1. Having a command-line solution means we no longer have to commit the generated files into our repository, or include them in our Visual Studio project. This not only saves space, but helps us to avoid having to deal with as many merge conflicts. Minified files are particularly bad in version control systems, because most of the code changes you make will occur on a single line of code.
  2. Thanks to source-mapping, we can use pre-minified files in both development and production environments, while improving our ability to debug in either environment!
  3. Having an incremental build means that we don’t have to rebuild every LESS file every time any LESS file is changed. Instead, we’ll just update any CSS output that depends on that LESS file.
  4. GulpJs will keep track of all file changes, even those made outside of Visual Studio. This means, for example, that we can map our LESS files to our working directory in Chrome, make edits directly in Chrome Dev Tools, and have our changes appear almost instantly in the browser.

Working Solution

Here’s the gulpfile.js I finally ended up with. Realizing that much of this is not going to be at all obvious to someone without experience in gulp, I went pretty heavy on the comments:

/*
* This file defines how our static resources get built.
* From the StaticCommon root folder, call "gulp" to compile all generated
* client-side resources, or call "gulp watch" to keep checking source 
* files, and rebuild them whenever they are changed. Call "gulp live" to 
* do both (build and watch).
*/

/* Dependency definitions: in order to avoid forcing everyone to have 
* node/npm installed on their systems, we are including all of the 
* necessary dependencies in the node_modules folder. To install new ones,
* you must install nodejs on your machine, and use the "npm install XXX" 
* command. */
var gulp = require('gulp');
var less = require('gulp-less');
var LessPluginCleanCss = require('less-plugin-clean-css'),
    cleanCss = new LessPluginCleanCss();
var sourcemaps = require('gulp-sourcemaps');
var rename = require('gulp-rename');
var cache = require('gulp-cached');
var progeny = require('gulp-progeny');
var filter = require('gulp-filter');
var plumber = require('gulp-plumber');
var debug = require('gulp-debug');

gulp.task('less', function() {
    return gulp
        // Even though some of our LESS files are just references, and 
        // aren't built, we need to start by looking at all of them because 
        // if any of them change, we may need to rebuild other less files.
        .src(
        ['Content/@(Theme|Areas|Css)/**/*.less'],
        { base: 'Content' })
        // This makes it so that errors are output to the console rather 
        // than silently crashing the app.
        .pipe(plumber({
            errorHandler: function (err) {
                console.log(err);
                // And this makes it so "watch" can continue after an error.
                this.emit('end');
            }
        }))         
        // When running in "watch" mode, the contents of these files will 
        // be kept in an in-memory cache, and after the initial hit, we'll
        // only rebuild when file contents change.
        .pipe(cache('less'))
        // This will build a dependency tree based on any @import 
        // statements found by the given REGEX. If you change one file,
        // we'll rebuild any other files that reference it.
        .pipe(progeny({
            regexp: /^\s*@import\s*(?:\(\w+\)\s*)?['"]([^'"]+)['"]/
        }))
        // Now that we've set up the dependency tree, we can filter out 
        // any files whose
        // file names start with an underscore (_)
        .pipe(filter(['**/*.less', '!**/_*.less']))
        // This will output the name of each LESS file that we're about 
        // to rebuild.
        .pipe(debug({ title: 'LESS' }))
        // This starts capturing the line-numbers as we transform these 
        // files, allowing us to output a source map for each LESS file 
        // in the final stages.
        // Browsers like Chrome can pick up those source maps and show you 
        // the actual LESS source line that a given rule came from, 
        // despite the source file's being transformed and minified.
        .pipe(sourcemaps.init())
        // Run the transformation from LESS to CSS
        .pipe(less({
            // Minify the CSS to get rid of extra space and most CSS
            // comments.
            plugins: [cleanCss]
        }))
        // We need a reliable way to indicate that the file was built
        // with gulp, so we can ignore it in Mercurial commits.
        // Lots of css libraries get distributed as .min.css files, so
        // we don't want to exclude that pattern. Let's try .opt.css 
        // instead.
        .pipe(rename(function(path) {
            path.extname = ".opt.css";
        }))
        // Now that we've captured all of our sourcemap mappings, add
        // the source map comment at the bottom of each minified CSS 
        // file, and output the *.css.map file to the same folder as 
        // the original file.
        .pipe(sourcemaps.write('.'))
        // Write all these generated files back to the Content folder.
        .pipe(gulp.dest('Content'));
});

// Keep an eye on any LESS files, and if they change then invoke the 
// 'less' task.
gulp.task('watch', function() {
    return gulp.watch('Content/@(Theme|Areas|Css)/**/*.less', ['less']);
});

// Build things first, then keep a watch on any changed files.
gulp.task('live', ['less', 'watch']);

// This is the task that's run when you run "gulp" without any arguments.
gulp.task('default', ['less']);

Lessons Learned

Apart from those things mentioned in the comments file above, here are some additional notes that might come in handy.

  1. I had to install NodeJs on my local machine so that I could have access to npm, but I didn’t want to force all of our developers to do the same, so I ran npm install ... for all of the dependencies listed at the top of the gulpfile, checked in the node_modules folder to source control, and included a copy of node.exe in our project’s root folder so that the gulp command could be invoked by people without NodeJs installed on their computer. This uses several MB more disk space in our source control, but this is in a subrepository that’s set aside for hosting images, CSS, JavaScript libraries, etc., so it’s not such a bad thing.
  2. Because I didn’t want to change things too much, we’re using the pattern established by Web Essentials, to not build any LESS files that start with an underscore. We have several LESS files that are only used as references for other LESS files.
  3. Also to avoid changing things too much, I’m having the built files get put into a folder alongside their LESS counterparts. In the future, we may want to change this so that there’s only a single folder we have to “ignore” in Mercurial and Visual Studio.
  4. The gulp-progeny plugin needs to have a special regex option to accommodate parenthetical arguments in “@import (reference) _file.less“-type imports.
  5. I found it much better to leverage the Clean-CSS plugin for gulp-less rather than running the gulp-minify-css plugin separately. It involves fewer module files, runs more quickly, and (most importantly) preserves source-map information from the LESS transform.
  6. Update 2/6/2015: Once this solution made it to our main branch, the build server ran into a problem–it couldn’t load all the npm dependencies because some of them had such deep dependency trees that the file names were too long for a windows system. (Our continuous integration server loads things into a slightly deeper directory than what most of our developers use.) After a bit of research, I found that I could flatten the dependencies out using the flatten-packages module, which not only solves this problem but also reduces the number of files we have to keep in the repository!
  7. Update 2/9/2015: Gulp has some issues with its error management that make it so little errors in LESS files will end up silently crashing the gulp run. gulp-plumber was made to fix this problem, and I originally used it according to the directions on its npm readme. However, I later discovered that when you’re using gulp.watch() along with plumber, it needs a little extra configuration. This post almost got it right, but the name of the error handling function option needs to be errorHandler, not handleError. The code above now reflects this fix.

Sacrifices

I added gulp to our main build batch file, but our LESS files take a ridiculous amount of time to rebuild. In order to avoid having to do a full LESS rebuild with every recompile, I opted not to have gulp run when Visual Studio builds our projects. Developers are going to have to remember to run gulp (or have gulp live running) in order to see the correct version of all our styles.

Conclusion

I feel that the benefits of this move far outweigh the downsides. I’m really glad I was able to get the incremental builds working, and now that we’re already incurring the cost of having to run gulp live during development, I plan to incorporate a lot of our other bundling and concatenation efforts into our gulp file, which should simplify our workflows even more, moving forward.

Thursday, December 25, 2014

User-Facing Exceptions

User-Facing Exceptions

After Mark Seeman’s recent blog post, Exception Messages are for Programmers, Mogens Heller Grabe commented:

I usually introduce a special exception when I’m building software for clients: a DomainException! As you might have guessed, it’s a special exception that is meant to be consumed by humanoids, i.e. the end user. This means that it is crafted to be displayed without a stack trace, providing all the necessary context through its Message alone. This is the exception that the domain model may throw from deep down, telling the user intimate details about a failed validation that could only be checked at that time and place.

I totally understand Mogens’s reasoning here. An exception’s primary goal is to halt execution in an error state, but there are some types of exceptions that really want to provide a user-facing message at the same time. They are still exceptional, but they know something about the nature of the error that would be useful for the user to be aware of.

However, there are some problems with Mogens’s strategy:

  1. Using a specific exception type (e.g. DomainException) means that you can’t use different exception types based on the nature of the exception, or other information that you might want to associate with it. What if I want a WorkflowDoesNotExistException in one case, and a ServiceNotAvailableException in another, but I still want to provide a user-facing message with each?
  2. As Mark Seeman very powerfully argues, exception messages are for programmers. Their purpose is to provide enough information for developers to know what went wrong, how to reproduce the issue, and how to fix it. The exception message is included with the stack trace when you call ToString() on the exception. Co-opting the exception message to provide user-facing information gets in the way of its primary purpose.
  3. It’s good practice to catch exceptions and use them as the InnerException to a new exception with additional debug information, at various levels of the call stack. You can’t just catch DomainExceptions and treat them differently from your other exceptions, because they could be thrown at any level of your application, and subsequently wrapped in other exceptions.

IUserFriendlyException

Here’s my solution to the problems mentioned above. I’ve been using it for a couple of years now without any problems.

public interface IUserFriendlyException
{
    string UserFacingMessage { get; }
}

This solves the first problem by using an interface, which can be implemented by any number of exception types.

It solves the second problem by using a new property–UserFacingMessage–which can be provided in addition to (not instead of) your exception’s programmer-targeted Message. Your programmers still get the debug information they want, and users aren’t exposed to technical details they don’t care about.

A Note Regarding Internationalization: While I haven’t personally had to worry about producing different user-facing messages for different users, Mark Seeman correctly points out that this is an important issue to consider in many applications. Fortunately, you can use this same pattern for projects that use the ResourceManager to produce culture-specific strings.

public interface IInternationalUserFriendlyException
{
    string UserFacingMessageResourceKey { get; }
}

But what about the third problem? This requires a little more work. It’s a good idea to catch and log all exceptions at the Presentation Layer of your program, so that users don’t get ugly server error pages, or crashing applications. You don’t care what type of exception it is, and you typically don’t have anything specific to say to the user at this point.

private static readonly string GenericErrorMessage = 
    "We are really sorry, but something unexpected happened. " +
    "Please refresh the page and try again. " + 
    "If the problem persists, please report it to your administrator.";

public void OnException(ExceptionContext filterContext)
{
    Log.Error(filterContext.Exception);
    ShowError(filterContext, GenericErrorMessage);
    filterContext.ExceptionHandled = true;
}

But now if you have a user-facing message, you can provide that message instead.

public void OnException(ExceptionContext filterContext)
{
    Log.Error(filterContext.Exception);
    ShowError(filterContext, 
        filterContext.Exception
            .AndInnerExceptions()
            .OfType<IUserFriendlyException>()
            .Select(e => e.UserFacingMessage)
            .FirstOrDefault()
            ?? GenericErrorMessage);
    filterContext.ExceptionHandled = true;
}

The only tricky part is that you have to dig deeper than the top-level message. The code above uses this extension method:

public static IEnumerable<Exception> AndInnerExceptions(
    this Exception exception)
{
    while (exception != null)
    {
        yield return exception;
        exception = exception.InnerException;
    }
}

Conclusion

I’ve found this strategy to work well in those cases where an exception wants to communicate user-facing information. Hopefully you will, too. Do you have questions or comments? Leave them in the comments section below.

Saturday, November 01, 2014

Ten Things Beginners Must Know About JavaScript

Introduction

No doubt about it–JavaScript is absolutely essential for any web developer. Gone are the days when you could get by with a little CSS and HTML. Fortunately, it has so few rules that it’s dead simple to get started:
alert("Hello World."); // Shows the user "Hello World." in a dialog
That’s it! Many simple tasks can be accomplished with just a few lines of code. There’s no need to import packages, or declare namespaces. You write some code, and it runs. However, the very lack of structure that gives JavaScript its low barrier to entry also enables beginning developers to write unstructured, fragile code without realizing it. As an application grows, this unstructured code will come back to haunt you in the form of unexpected, difficult-to-find bugs.
In this tutorial, I plan to correct some of the common misconceptions and mistakes that cause undue pain for beginning JavaScript developers. Here are a few things every beginning JavaScript developer should know:

1. You can add properties to almost everything

JavaScript has only three primitive data types: String, Number, and Boolean. Everything else (if it’s not null or undefined) can have properties added to it.
Note: Even though String is a primitive type ("hi"), there is another incarnation of String in JavaScript which is an object (new String("hi")). See here for details.
You may have seen something like this:
var a = {}; // create a new object
a.b = 'hello';
In the above code, a.b meant nothing until I set a value to it. Now a has a property called b. But wait, it gets weirder.
var a = []; // create an array
a.b = 'hello';
Great, so now you’ve got an empty array, with a property on it called b.
Caution: Just because you can put properties on arrays doesn’t mean you should. As I’ll discuss later, the above code will change the behavior of for...in loops on that array.
How about this?
var a = function() {};
a.b = 'hello';
Yes, that’s right. a is now a function, with a property. Which brings me to my next point.

2. Functions are objects

More and more languages are getting support for treating functions as values, but depending on your background this may not be at all familiar to you.
function doIfTrue(isTrue, whatToDo)
{
    if(isTrue)
        whatToDo();
}
doIfTrue(true, function() {alert('hello');}); //  alerts "world"
doIfTrue(false, function() {alert('world');}); // does nothing
The function above treats the whatToDo parameter as a function. This sort of pattern allows developers to do some very powerful things like setting up event handlers with very little code.

3. for...in loops iterate over property names, not values

Developers coming from a Java or C# background are used to so-called “foreach” loops, which iterate over all the values in a collection. JavaScript doesn’t (currently) have an equivalent loop. The closest thing, a “for in” loop, has some important differences:
var arr = ['a', 'b', 'c'];
for(var i in arr) {
    alert(i);      // 0, 1, 2
    alert(arr[i]); // 'a', 'b', 'c'
}
As you see, the variable used by the for...in loop gives you the keys by which other values can be found, but you have to perform the extra step of getting the values off of the original object.
Why does JavaScript do this? The main reason is that for...in was not made for arrays: it was made for objects that have properties on them:
    var pairs = {'a': 'apple', 'b': 'banana'};
    for(var key in pairs) {
        alert(key);        // 'a', 'b'
        alert(pairs[key]); // 'apple', 'banana'
    }
Caution: Because a for...in loop iterates over the properties on an object, you’ll get strange behavior if you use the loop on an array that has extra properties added to it, For this reason, you should avoid using for...in loops on arrays–use simple for loops instead. They’re faster anyway.
Note: ECMAScript 6 will introduce for...of loops, which iterate directly over values.

4. Variable scoping

All developers, in every language, should avoid using global variables. But it’s easy to do by accident in Javascript because nobody’s forcing you to organize your code into modules.
var message = "hello world";
alert(message);
If the above code is run all by itself in the browser, it will create a new global property on the window object, called message. That means that if any other code on your site also has a similarly-declared variable called message, they’ll stomp on each other.
In Javascript, all variables declared with the var keyword are scoped to their declaring function. That means if you want to make sure your variables aren’t global, you should put them in a function, and then call that function.
(function() {
    var message = "hello world";
    alert(message);
})(); 
Developers with a background in other languages based on C syntax are used to variables scoped by curly braces ({}). In JavaScript, variables declared with var are “hoisted” to the top of the function they’re declared in. This code:
function sayHi() {
    if(true) {
        var s = "hi";
    }
    alert(s); // alert("hi") -- `s` is still within scope.
} 
… is the same as this:
function sayHi() {
    var s;
    if(true) {
        s = "hi";
    }
    alert(s);
} 
This also means that if you refer to a variable outside the scope of your function, you’ll use the value of that variable at the moment the code is run, not at the moment your function is created. This trips up beginners all the time:
 var thingsToDo = [];
 for(var i = 0; i < 2; i++) {
     thingsToDo.push(function() {alert('hello ' + i);}); 
 }
 for(var k in thingsToDo) {
     thingsToDo[k]();               // alerts "hello 2" twice.
 }
Remember that the variable i starts as a 0 value, but by the time it’s called (in the second loop) its value has been incremented to 2. To capture the value of i when you create the function, you have to create another function scope:
var thingsToDo = [];
function createHelloAlert(v) {
    // `v` only exists within this method call.
    return function() {alert('hello ' + v;} 
}
for(var i = 0; i < 2; i++) {
    thingsToDo.push(createHelloAlert(i)); 
}
for(var k in thingsToDo) {
    thingsToDo[k]();  // alerts "hello 0", then "hello 1".
}
Note: ECMAScript 6 will introduce a let keyword, which will allow you to declare a variable scoped to the curly-braces. This is known as Lexical Scoping.

5. Variables that aren’t explicitly declared can be global

Suppose you remember to wrap your code in a function, but forgot the var keyword:
(function() {
    message = "hello world";
    alert(message);
})(); 
When you set a variable’s value, and you haven’t declared it to be a variable for the current function scope via the var keyword, JavaScript assumes you mean this.propertyName. So the above code is the same as this:
(function() {
    this.message = "hello world";
    alert(this.message);
})(); 
If you’re a Java developer, you’re saying to yourself, “What’s this? No, really. What is this?” In other languages, this means the instance of the class that you’re looking at, but in JavaScript it means the object that your function got called on. If you’d done this:
var a = {
    foo: function() {
        this.message = "hello world";
    }
};
a.foo(); // `a.foo()` means foo's `this` is `a`.
alert(a.message); // outputs "hello world"
… then calling the foo method puts a value on a’s message property. But since our original code snippet is calling a function that doesn’t have anything in front of it, this is given a fallback value of window. You end up creating another global variable just by forgetting the var keyword.

6. Understand how .prototype works

JavaScript uses a special prototype property to solve the problems that other languages use classes to solve. Consider the following:
function Person(first, last)
{
    this.first = first;
    this.last = last;
}
var john = new Person("John", "Doe");
var mary = new Person("Mary", "Deer");
Person.prototype.full = function() {return this.first + " " + this.last;};
alert(john.full());
There are a lot of things happening here.
  1. We create a function, which will set properties on its this object when called.
  2. We create two separate instances of that function by putting the new keyword before our function calls. This ensures that john and mary refer to completely separate objects, each with their own first and last properties.
  3. We create a new function and assign it to the full property on our Person function’s prototype property. The prototype property exists on all functions, and allows you to define fall-back properties that should exist on every object created from that function.
  4. We call the full() function on john. JavaScript sees that the john object doesn’t actually have a full function on it, so it looks for a Person.prototype.full() function and calls that instead. Within that call, however, this still refers to the john object.

7. JavaScript never sleep()s

Many languages support the notion of threads, which allow you to have several procedures running at the same time. The problem is that multi-threading opens a huge can of worms: thread locks and other race conditions that even the best developers have a hard time grappling with.
JavaScript avoids these issues entirely by only allowing one piece of code to run at a time. This is great, but it requires us to write our code in a different way. Most languages create a layer of abstraction over operations where the program is waiting for something to happen. For example, in Java, you can call Thread.sleep(100), and the rest of your procedure won’t run until 100 milliseconds have passed.
When you’ve only got one thread to work with, you can’t afford to have it doing nothing for hundreds of milliseconds at a time–it would freeze up the UI and make a horrible user experience. So JavaScript almost never blocks execution. Instead it relies on asynchronous callbacks to let you say what should happen when an operation finishes. For example:
window.setTimeout(function() { console.log(a); }, 1000);
console.log('hello world');
var a = 'got here';
The above code will first create a “hello world” message (even though that line of code comes after the setTimeout() method), and then print “got here” one second later. Even if we changed the timeout to 0, we know that the a variable will be initialized before getting logged because no other JavaScript can run until this code has finished.
Beginners will often write code like this, and then wonder why a doesn’t have a value:
var a;
$.ajax(url, {success: function(e, data) { a = data; });
console.log(a); // BAD! This line will run before `a` gets set to a value!
Don’t fall into that trap.
There are a few caveats that I should mention.
  1. Not all functions that you pass into other functions are asynchronous callbacks. The following code works just fine, because doIfTrue() calls its whatToDo argument, synchronously, before it returns:
    var a = 'hello';
    doIfTrue(true, function() {a = 'world';});
    console.log(a); // prints "world"
    
  2. alert() is one of very few exceptions to the no-blocking rule–nothing happens until the alert window closes. Even the timeouts freeze! This is one reason that it’s usually best to avoid using alert().
  3. Web Workers can allow you to run CPU-intensive tasks on a separate thread, but they’re structured very carefully to avoid race conditions. Beginning developers rarely need to worry about such things.

8. Automatic type conversions

Like many languages JavaScript does some automatic conversions between types under certain circumstances. For example:
var s = 1 + ""; // yields "1" 
JavaScript takes this a little further than many languages, though, and you can leverage this fact to make your code very concise. For example, instead of if(a != null) {...}, you can just say if(a) {...}. Even though a isn’t a Boolean, JavaScript can tell you want to treat it like one, so it determines whether a’s value is “truthy” or “falsy” and acted accordingly.
Falsy JavaScript values include:
  • false
  • 0
  • empty strings ('' or "")
  • null
  • undefined
  • NaN
Everything else is Truthy.
Here’s another example:
var a = b || c;
If b has a truthy value like “Bob”, that’s the value that a will get. If b is falsy, a will get the value of c.
You can force a truthy/falsy value to become a true/false value by negating it twice:
var trueOrFalse = !!value;
Also, in equality comparison, x == y has some complex rules for converting different value types. This can yield weird behavior, like:
var a = "1" == true; // true: "1" -> 1, which is truthy
And you can use the === operator for strict comparison without automatic conversion.
var a = "1" === true; // false: different-typed values are not equal.

9. JavaScript is code–not data or markup

For simplicity, many online tutorials will mix JavaScript and HTML, like so:

Mixed HTML and JavaScript (bad)

<button onclick="return confirm('Delete this object?');">Delete</button>
This works fine for small tutorials, but it has some serious drawbacks when you’re writing real applications. It mixes the programmatic behavior of the UI elements (represented by JavaScript) into the structure and data that is (represented by HTML). HTML should not be deciding how it interacts with the JavaScript. Instead, separate your JavaScript code from the HTML, and let it decide how it interacts with the page.

HTML

<button data-confirmation="Delete this object?">Delete</button> 

JavaScript (with jQuery)

// Set a click handler for anything with a data-confirmation attribute.
$('[data-confirmation]').click(function() {
    var message = $(this).data('confirmation');
    return confirm(message);
});
As you can see, the JavaScript has now defined the behavior for any element with a confirmation data attribute. This approach, sometimes called “unobtrusive JavaScript,” has several advantages, including:
  1. It usually makes HTML code more concise and readable.
  2. It allows you to declare a UI concept in one place and reuse it throughout your system.
  3. If you decide to change your implementation details (e.g. “browser confirmation dialogs are ugly and inconsistent–we want to use a popup instead!”), you can do this in one place without touching your HTML.
If you’re rendering templates in the browser à la Angular or Polymer, this separation means putting HTML in one part of your file and JavaScript in another. If you’re using a server-side engine like JSP or Razor, you’re better off keeping the JavaScript code in static, cached .js files, away from all your dynamically-generated HTML tags.

10. JavaScript is not just for browsers

JavaScript has clearly come a long way since it was created (purportedly in ten days) in 1995. Now, technologies like node.js allow JavaScript to be run outside of any browser. Some common use cases for JavaScript as a general scripting language include:
  1. Writing server-side code in JavaScript. Ghost.org is just one example of a web application whose server-side code is JavaScript running on node.js.
  2. Building LESS files into CSS. Less.js is the fastest, most accurate LESS converter around, and it’s written in JavaScript. If you use LESS, but don’t want your LESS to get re-translated client-side on every page load, it’s a good idea to pre-build the CSS by invoking the lessc compiler via node.js.
  3. Managing build tasks. What if you want to run unit tests against your JavaScript every time you change a file, to make sure you didn’t break anything? Grunt.js, with its watch and Karma plugins can do that! Or you can configure Grunt to rebuild all those CSS files every time you change a LESS file.
If you’re developing web applications, you’re going to need to learn JavaScript. You might as well apply that knowledge to other aspects of your application too!

Conclusion

Like it or hate it–JavaScript is here to stay. It is currently the de-facto language for building any kind of rich user experience on the web.
JavaScript is powerful, and full of intricacies and nuances. The more you learn about JavaScript, the more you realize how little you actually know about it. But arming yourself with knowledge will help you avoid costly mistakes that are common for beginning developers.
Good luck.

About the Author

I’m a Software Architect with over 7 years of experience in building dynamic web applications. I have a passion for learning, and for helping other people learn. While earning over 60,000 reputation points on StackOverflow, I’ve seen a lot of the simple mistakes that vex JavaScript developers on a regular basis. If you have questions about JavaScript, or programming generally, feel free to reach out to me at https://www.codementor.io/j2jensen
Special thanks to Aaron Frost and the peer reviewers at CodeMentor for their valuable feedback as I crafted this article.

Saturday, September 27, 2014

Provident Funding: Providing you with a false sense of security

Update: 12/28/2016

I'm not sure when it happened, but I noticed that Provident Funding now supports mint.com integrations! They also seem to have changed at least a couple of the other issues I complained about here. Yay!

Original Post

As a software developer for web applications, I take a keen interest in Internet Security. One of the more interesting aspects of this field is that there are some practices intended to make a site more secure, which don't always actually improve security. At best, these practices are an unnecessary burden to the user. At middling, they'll give the user and the provider a false sense of security, and make them less likely to notice other, more important issues. And at worst, they'll actually cause a user to compromise his security more by creating workarounds to byzantine policies.

A classic example is password strength rules. For those with enough training in information technology, this simple comic is enough to explain why the password strength rules used by most websites have trained most people to come up with passwords that are hard to remember, but easy to hack.

And in fact, the whole concept of a password is fundamentally flawed: every time you log in, you have to enter your password. That means that any time you use a computer that might have had a keylogger installed, or any time you enter it while someone might have been looking at your fingers, or a video camera might have caught your fingerstrokes, your password is potentially compromised. The very act of entering a password represents a security vulnerability in and of itself. We just haven't figured out a better solution that's convenient enough to work for most people.

I think the standard minimum password length for most websites I've seen recently has been 8 characters, but they insist on you mixing numbers, symbols, and upper- and lower-case letters. The problem is that most people choose ways of adding these elements that are dead simple for a hacker and his tools to guess. So they hardly add any difficulty at all if someone is trying to guess your password. At the same time, 8 characters isn't really enough to prevent the types of attacks that these rules are trying to prevent. This topic is worth an entire blog post of its own.

But as bad as that is, there are occasionally even worse cases. For example:

  1. Until a couple of years ago, American Express's website limited peoples' passwords to 8 letters. You couldn't create a longer, stronger password even if you wanted to!
  2. I once asked the company handling HR for an employer to send me my username, because they'd used an auto-assigned username that I could never seem to remember. A kind lady there sent me an email with both my username and my password in it. And this was the company handling my paychecks! This was at least three strikes against that company all in one go: 
    1. It implies that the company stores passwords in a way that it's possible to retrieve them. 
    2. It means that the people working for this company have the ability to see these passwords (not just have them automatically sent to users, but actually see them.)
    3. Email is not secure, and should never be used to send passwords (except possibly a temporary, random password that you're required to change within a time limit.)
When people managing a web application are making decisions about their security policies, they need to think very carefully about them. Even policies that seem like they'll make things more secure might encourage worse security practices. For example, if you make users change their password every few months, they're most likely going to do one of the following:
  1. Stop using a decently unique password that they would have remembered through muscle memory, and switch to using an easy-to-guess pattern, so they don't have to keep trying to think up a new one every three months. Variants of spring/summer/fall/winter are very common in this case.
  2. Keep using the same basic password, but change it in a predictable way. (e.g. add 1 to a number at the end every time they have to change it)
  3. Put their passwords on a sticky note next to their monitor, at least for the first week or two. (Many people do this anyway, but they'll be far more tempted if they're constantly being forced to come up with new passwords.)
Any time you introduce a procedure that gives the illusion of added security, without actually causing things to be more secure, you create a false sense of security, which can be dangerous. I'd like to highlight some of these false security procedures that are practiced by Provident Funding, a loan servicer:
  1. They stopped allowing users to connect their Mint.com accounts to their Provident Funding accounts. They claim that this is to improve the security of their customers because they don't have any control over what happens to that information once it enters Mint.com.
    1. This might be a valid concern for their customers, but not for the company itself. After all, the company doesn't have power over what users do with their own information that they view on their website either. There's nothing stopping those users from downloading all their statements and sending them to Nigerian con artists, if that's what they choose to do with their own data. 
    2. They used to have this connection to Mint.com. Are they trying to say that they were not secure before?
    3. Mint.com is owned by Intuit, who also provides such products as Quicken and TurboTax. Do you really think that their security practices are going to be anything less than impeccable?
    4. Most users don't actively manage their loan accounts from month to month. In other words, if they could see that they're payments are on track each month using a read-only service like Mint.com, they'd almost never have to actually log in to Provident's website. By forcing users to log in more often, Provident provides that many more opportunities for bad-guys to capture your password. If a bad-guy gets access to Mint.com credentials, they can see what a user spends their money on, but if they get access to  Provident credentials, they can do more useful things like change billing addresses and who-knows-what-else.
  2. Provident forces users to change their password every six months. As mentioned earlier, the practical value of this practice is questionable. But it truly becomes a false security practice when they allow users to reset their password to the same value as before. The site acts like it's got a security procedure, but all it really does is force a user to enter their password a bunch of times. Remember what I said earlier about the very act of entering your password? Yeah.
  3. When changing their password, the user is required to enter their username and password again. I understand requiring the password, but the username is prominently displayed at the top of the page, so asking people to enter it again is completely useless from a security perspective.
  4. Provident's password requirements are pretty close to the same as most websites, as mentioned above, except that the symbol character must be one of the following: !@#$-_. So rather than making the password harder to guess, this actually makes the hacker's job easier: he no longer has to worry that every character might be any symbol--he can now assume that one (and for 99% of users it'll be only one) of the password's characters is one of only seven possible values. 
Now, I appreciate that in some areas, they do adhere to some real best-practices. They don't send your statements to you in an email, for example. But when it comes to false security practices like those above, I have to wonder:
  1. Do they know that these practices are useless, but feel it's important to give users a sense of security just to keep up appearances? If so, that's really annoying and a little dangerous.
  2. Do they actually think that these practices have some value? If so, they're inept when it comes to real security, and we have to wonder what true vulnerabilities they left open while they followed these red herrings.
  3. Are some of these "security practices" signals that they have some really bad practices underlying their entire site, which they've had to work around? For example, are they failing to encode parameters, so they disallow funny characters in your password because they're afraid of little Bobby Tables? Are they blocking Mint.com because they have no confidence in their technical ability to keep an integration endpoint up and running? If so, we have to wonder whether they've got the technical competence to keep our data safe from real security threats.
I brought up many of these issues in an email directly to Provident months ago, and didn't get a very satisfactory response. Since there appears to be no sign of policy changes at this point, I'm hoping a little public shaming will get the attention of someone who cares. Feel free to share with people who are interested in this sort of thing.

Tuesday, September 09, 2014

The Big Fat Fraud

The other day, on Radio West, I heard part of an interview with Nina Teicholz, author of The Big Fat Surprise: Why Butter, Meat and Cheese Belong in a Healthy Diet. For a while, I was fascinated as she recounted various ways that the medical and scientific communities had latched onto ideas about fat and cholesterol, ignoring evidence contrary to those ideas.

The Big Fat Surprise

Teicholz's claim is basically that trying to reduce fat in our diet has had the opposite effect from what was intended. This concept is unsurprising to me. When trying too hard to avoid any one kind of food in our diet, it's easy to replace that thing with even less-wholesome alternatives. I remember a man in a birthing class trying to figure out a good diet for his wife, who was a "vegetarian." It turns out that while she didn't eat meat, she didn't eat any vegetables either, which basically left nothing but processed carb-rich foods on their menu. A recent study showed that a low-carb diet is actually twice as effective as a low-fat diet when trying to lose weight, adding to a mounting body of evidence that we need to stop making fat the bogeyman it has been for some time. In general, it's best to eat natural, whole foods, with as little processing as possible:  Butter is probably more healthy than margarine. Whole milk is probably more nutritious than skim milk or soy milk. Many of the things Teicholz was saying gibed with other things I'd learned. And she came across as very smart, knowledgeable, and convincing.

Pretty soon, though, the things she said stopped "ringing true." I'm not sure exactly when it was. It might have been when she started bashing on plant-based foods. "The evidence behind 'mostly plants,'" she said, "turns out to be quite thin." I may not be a nutritionist, but I'm passably familiar with nutrition science and plant-based diets in particular, and I can say with some certainty that there's a sizable body of evidence showing the benefits of eating fruits and vegetables.

Then a nagging suspicion started forming in the back of my mind as she shared her experiences with trying to set up interviews with some researchers:
I would get on the phone with researchers, and they would say, "If you're taking the Gary Taubes line, I won't even talk to you."
In my experience, when otherwise logical, well-educated people are completely unwilling to talk to someone, there's a reason behind it that's a little stronger than mere institutional bias. How did this "Gary Taubes" earn such a bad reputation in the scientific community? Did he interview researchers, and then take their statements out of context? Did he present the researchers' findings as supporting evidence for claims that they didn't actually support? Is he guilty of pseudoscience--the scientific community's equivalent of blasphemy? And if Teicholz is "taking the Gary Taubes line," then is she doing the same thing?

I remembered that some people will say what other people want to hear, because they know that other people will pay money to hear it. This is just a secular version of what the Book of Mormon calls "priestcraft." One website I stumbled upon claimed to have proof that all the health experts were wrong, and the best diet actually consists mostly of bacon and beer (no joke!), and if you send a check to such-and-such address, they'd send you more information about it. Was Teicholz's book just another incarnation of the "eat drink, and be merry, and everything will be okay" story that charlatans have been selling since time immemorial?

Just another Fad Diet Book

So when I got home, I did a simple Google search: "big fat surprise critical review." And lo, there it was: a huge two part article on a blog titled The Science of Nutrition, which tears The Big Fat Surprise to shreds. In summary:
What makes this particular book interesting is not so much that it is bad (which it is) or that it is extravagantly biased (which it also is). No, what really fascinates me about this book is that the author excessively and shamelessly lifts other people’s material. Most notably Teicholz lifts from another popular low-carb book called Good Calories, Bad Calories (GCBC) by Gary Taubes.
You probably don't have time to read through the whole thing--I didn't. But please go ahead and read a page or two, and then scroll to the bottom to see just how much content there is. You'll get a general idea of just how Nina Teicholz went about misinterpreting evidence, failing to find original sources, taking statements out of context, and so on. As the author concludes:
The issues I bring up in this review are too substantial and too numerous to be ignored. If you were to remove all of the instances where Teicholz deeply distorts a study or publication, and you were to remove all conclusions that she draws from the distortions you would be left with nothing but a pamphlet.
Every few years, it seems, a new book is published telling people about some simple change they can make that will help them lose weight and feel healthier. And every time a bunch of people rave about it, until they forget about it, and end up the same weight they were before. And the only people who really benefited were the author and publisher of the book. Meanwhile, scientific study after study confirms that the only way to consistently lose weight and keep it off is to do what experts have been saying all along: eat a variety of whole, fresh fruits and vegetables, limit how much food you eat, and get plenty of sleep and exercise. Anyone who tells you otherwise is selling something.

Some words of wisdom

Mormons believe in a code of health representing the "will of God in the temporal salvation of all saints in the last days." Revealed in 1833 to the prophet Joseph Smith, the Lord's pronouncement began:
In consequence of evils and designs which do and will exist in the hearts of conspiring men in the last days, I have warned you, and forewarn you, by giving unto you this word of wisdom by revelation
The Lord warned against the use of alcohol, tobacco, and stimulants. It emphasized a diet rich in grains and a variety of fresh fruits and vegetables, even encouraging abstinence from animal meat except when necessary.

When I became a member of the LDS church, I decided to follow this counsel more fully than most Mormons do--for about six years I was a vegetarian. I definitely experienced the blessings associated with this scripture:
 18 And all saints who remember to keep and do these sayings, walking in obedience to the commandments, shall receive health in their navel and marrow to their bones;
 19 And shall find wisdom and great treasures of knowledge, even hidden treasures;
 20 And shall run and not be weary, and shall walk and not faint.
I'm still very fit, despite sitting at a computer way more than I should. But during those years after my baptism I was more healthy than at any other time in my life, and there were several times when I was amazed at how well I could "run and not be weary."

Since 1833, modern prophets have clarified, expanded on, and re-emphasized portions of this Word of Wisdom. For example, the prohibition of tobacco and alcohol has been extended to include illegal substances that didn't exist in Joseph Smith's time, and obedience to the Word of Wisdom is now a requirement to be worthy to enter the Lord's temples. We are also encouraged to use our own understanding to help keep our bodies healthy--for example, many Mormons avoid all forms of caffeine, rather than just coffee and tea.

At the same time, science has increasingly found the basic dietary guidelines from the original revelation to be good, sound advice. When I hear advice that directly contradicts counsel given by the Lord through His prophets, I'm going to choose the Lord's way. In the end, I think the Lord's wisdom will always be found to trump the knowledge of man.

Tuesday, December 18, 2012

Some Perspective

It seems like half the news items and half the posts on Google Plus for the past few days have been centered around the gun control debate. The shooting at Sandy Hook elementary has sparked a firestorm.

Gun control advocates say it's high time we addressed an issue that kills thousands of Americans every year. It's high time we stopped being afraid of the powerful NRA lobbyists, which have been known to spend as much as $100,000 on a single election. It is no longer enough to simply grieve while we accept the status quo. Homicide rates per capita in the United States far exceed those of other nations, especially those committed by firearms.

On the other side, Second Amendment enthusiasts are pushing to allow more guns in schools, in hopes that someone might be on hand to shoot back if this sort of thing ever happened again. Why punish the millions of law-abiding gun-owners, on account of the few nutcases? They argue that if someone wants to commit an atrocity, they'll either acquire guns illegally, or find some other means of harming people: our best defense against such attacks is an armed and trained citizenry.

This topic hits as close to home for me as it does for most Americans: a man was shot in front of our house this year with a gun that was purchased legally, but stored without sufficient safeguards. As much as anybody, I would like to know that my wife, three-year-old son, and soon-to-be-born baby will be safe from such things.

But I think we as human beings have a predilection for reactionism. Some dude makes a stupid movie, and the entire Muslim world is up at arms. Some dude tries to blow up a plane with a shoe bomb, and the entire nation takes off their shoes when we go to the airport. We human beings just love to react--and overreact--to sensational attacks.

Is this a good opportunity for us to talk openly about gun control? Absolutely. I'm ready. But how many other topics are we going to ignore while we wage this particular battle? We Americans largely ignore the enormous death tolls inflicted by wars and other conflicts outside our borders, and even the thousands of innocents that are killed by our own military. Beyond that, there are so many silent killers in the world that destroy lives bit by bit, one at a time, and they go largely ignored because they never have a spotlight moment. Here's just one example:



How many of the people calling for stricter regulation on guns are also calling for stricter regulations on alcohol, tobacco, and other drugs? In my personal experience, some of the most vocal advocates of increased firearm regulation are also the most vocal advocates of drug legalization. And yet, many of the same arguments have direct application in both areas. "We already tried prohibition: it didn't work." "People will just turn to the black market." "At least this way we can collect taxes." And so on.

There's a perception that people who smoke (or do drugs, etc.) are only hurting themselves, and the government should stay out of their business. Others would argue that "no man is an island," and that since society as a whole has to pay for the astronomical medical expenses of smokers, the government has a right and a duty to regulate such dangerous substances.

Aside from those arguments, let's just look at how many people die from second-hand smoke each year in the United States.
So while most of the 443,000 smoking-related deaths could be compared with suicides--in that the smokers are effectively killing themselves--smokers also kill 42,000 other people each year: more than all the firearm-related deaths combined.

Isn't it ironic that over eleven thousand people are murdered with guns every year, but it takes one guy walking into a school and killing twenty children and six adults to spark national outrage? Suddenly there's a hue and cry for background checks on gun buyers (even though the shooter stole the guns from his mother, who probably would have passed a background check). Then isn't it even more ironic that second-hand smoke kills nine hundred babies, every year, but any adult can buy as many cigarettes as they want at the local gas station?
So am I ready to reevaluate our nation's gun laws? Sure. 85 preschool-aged children killed per year is 85 too many. But let's not get so distracted jumping from one sensational news story to the next, that we forget to look at the big picture. Let's get a little perspective. Let's not allocate our precious time and energy, and our legislative human capital, in a way that is orders of magnitude out of proportion with reality. Let's take a proactive, or even a reactive--but not a reactionary--approach to legislation, politics, and everyday life.

Sources:
http://www.childrensdefense.org/child-research-data-publications/data/protect-children-not-guns-2012.pdf
http://www.cdc.gov/nchs/data/nvsr/nvsr61/nvsr61_06.pdf
http://www.ucsf.edu/news/2012/09/12759/secondhand-smoke-takes-large-physical-and-economic-toll
http://www.cdc.gov/tobacco/data_statistics/fact_sheets/health_effects/tobacco_related_mortality/