title: What good are Python function annotations?
body: <p>I have gone through the first couple of sections in PEP 3107, but I still don't get what good they do for the language. It seems to me that you can add metadata to functions using decorators. e.g.</p>
  
  <pre><code>def returns(return_type):
    f.return_type = return_type  # &lt;- adding metadata here
    return f
  
  @returns(Foo)
  def make_foo(): ...
  </code></pre>
  
  <p>You can add metadata to arguments too, and it can look pretty if you take advantage of default arguments, like so:</p>
  
  <pre><code>import inspect
  
  def defaults_are_actually_metadata(f):
    names, args_name, kwargs_name, defaults = inspect.getfuncspec(f)
    f.parameter_metadata = dict(zip(names[-len(defaults):], defaults))
    f.__defaults__ = ()
    return f
  
  @defaults_are_actually_metadata
  def haul(load="Stuff to be carried.",
           speed_mph="How fast to move the load (in miles per hour)."): ...
  </code></pre>
  
  <p>At least my initial impression is that annotations are superfluous: decorators can do everything that annotations can (and more). Why are annotations better than decorators when it comes to adding metadata to functions?</p>