saturate is not a valid keyword / intrinsic-function in GLSL -- search the spec for the word "saturate"... However, it does (incorrectly) compile on nVidia drivers.
Yeah, reason #3289472 why OpenGL is a design trainwreck. Remember kiddos, adding a clamp instruction is fine, but adding a special-case, higher-performance one that can be implemented in terms of the former somehow breaks hardware compatibility(???)
This isn't OpenGL's fault at all -- this is nVidia's OpenGL driver purposefully accepting invalid GLSL code, in order to make developers think that AMD's GL driver is broken (and hopefully even ship their product with invalid code, so that AMD's correct driver appears broken to the consumer). That's some damn evil Microsoft-esque behaviour on the part of nVidia, and the only fault OpenGL (Khronos) has in this particular matter is that they're unable to hold IHV's accountable for these harmful tactics.
These are the same dirty tactics that gave us the browser wars, and browser incompatibility issues of the 90's...
Yes, you shouldn't use max in GLSL for this purpose either, but should clamp with a hard-coded 0.0 and 1.0, which will compile down to the special-case free instruction-modifier, equivalent to saturate in HLSL.
 Sorry, I down-voted your post where you recommend the use of saturate, because I misread this as advising the use of it in GLSL, rather than in HLSL. It was actually a very good post. Forgive me!