[Python-ideas] Before and after the colon in funciton defs.

Nick Coghlan ncoghlan at gmail.com
Sat Sep 17 03:01:13 CEST 2011


On Sat, Sep 17, 2011 at 7:30 AM, Ron Adam <ron3200 at gmail.com> wrote:
> (This idea may have been suggested before, because it seems too obvious
> to me.)
>
> How about if we remove the requirement that the colon be on the same
> line as the function name.

I don't see any benefit in offering a second way to spell docstrings
or decorators (the existing spellings are easy enough to remember),
but this suggestion did prompt an idea for potentially replacing uses
of the default argument hack: allow a sequence of 'implicit locals' to
be defined within square brackets after the parameter list. (This idea
may have come up before, but if it has, I don't recall the arguments
against it).

Running through the 3 at least arguably legitimate use cases for the
default argument hack:

Micro-optimisation:
    # Current Python (internal to functools.lru_cache with default
argument hack)
    def decorating_function(user_function, tuple=tuple, sorted=sorted,
len=len, KeyError=KeyError):
         ... # 60 line function

    # Proposal - explicitly implicit locals to clarify real calling signature
    def decorating_function(user_function) [tuple=tuple,
sorted=sorted, len=len, KeyError=KeyError)]:
         ... # 60 line function

(Note: in practice, the lru_cache usage of the default argument hack
doesn't really impact introspection, since the function is short-lived
- it is the decorating function returned by the lru_cache decorator
factory and hence only exists briefly as part of the function
definition. The signatures of lru_cache itself and of the decorated
function are not affected. I still like it as an example, since it
isn't hypothetical - the standard library really uses the default
argument feature this way).

Early binding in a loop:

   # Current Python
   adders = []
   for i in range(10):
      def f(x, _i=i):
          return x + _i
      adders.append(f)

   # Proposal
   adders = []
   for i in range(10):
      def f(x) [i=i]:  # Real calling signature is clear
          return x + i
      adders.append(f)

Algorithmic shared state (without a class):

    # Current Python
    def f(*, _cache=[]):
        # Consenting adults, please don't override _cache when calling!

    # Proposal
    def f() [_cache=[]]:  # Real calling signature is clear
        # _cache is an implicit local, not a keyword-only argument, so its safe

To prevent grammar ambiguity, the list of implicit locals would most
likely need to appear before the annotation for the function return
type.
The syntax within the list would be the same as those for arguments
with default values (while I don't have a use case for allowing
annotations, I don't have any reason to prevent them either, so
reusing the same grammar fragment seems like reasonable idea)
The implementation would also be basically the same as for arguments
with default values (a list of names stored as an attribute on the
code object and a dictionary on the function object to populate them)

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia



More information about the Python-ideas mailing list