Your lighting equation is physically correct. However, in real life, one almost never sees highly pure colors. (An exception is when lasers are involved.) That's probably why your intuition is that red * blue = violet - a more realistic red might be something like (1, 0.1, 0.1), and a blue (0.1, 0.1, 1). Multiply those and you get (0.1, 0.01, 0.1), which is indeed a (dark) violet.
Similarly, nothing is perfectly black. Even black plastic, paint or cloth has at least a little specular reflection. The specular albedo at normal incidence doesn't get below about 2% for most materials, and at grazing incidence it rises due to the Fresnel effect. (Super black is an exception - a special material that reflects only 0.4% at normal incidence.)
For a white material, the reflected light will be the light color, not completely white. However, you've got to watch out here as your brain plays tricks on you: it adapts to the overall color of the light around you, so that white objects tend to look perceptually white even when illuminated by colored light. This is why digital cameras have a white balance setting - photographs would look completely wrong without it. (Of course, this only works up to a point - illuminate a room with a red laser and things will look red, not white.) Games don't generally simulate this visual adaptation process, though; instead they just have light colors that are less saturated than in reality.
(By the way, a nitpick: your lighting equation should have saturate()
around the dot product, to avoid generating negative values on the dark side of an object.)