## J - 30 ##
    '`z'(]-32*1=I.)&.(a.&i.)1!:1]1

J is read right-to-left, so to break this down:

  1. Prompt user for input: `1!:1]1`
  1. Perform algorithm in code-point-space:  `&.(a.&i.)`
  1. Identify character range for each letter; the characters between codepoints "\`" and "z" are considered lowercase: `1=I.`.
  1. For each lower-case codepoint, subtract 32: `']-32* ...'
  1. Note that step (2) creates an implicit step (5): we started out by projecting from character to integer domain, so now that we're finished, we map those integers back onto characters.

Obviously this particular implementation only considers ASCII; but the approach could be extended to at least the basic multilingual plane in Unicode.