PEP 309 (Partial Function Application) Idea

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Ronald Mai

    #1

    PEP 309 (Partial Function Application) Idea

    In my opinion, Ellipsis might be in the middle, not only in leftmost or
    rightmost, so a placeholder approach can be much more flexible and
    convenient.

    Here is a reference implementation:

    _ = lambda x: x.pop(0)

    def partial(func, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
    newkeywords = keywords.copy()
    newkeywords.upd ate(fkeywords)
    newargs = (lambda seq: tuple([(a == _ and a(seq)) or a for
    a in args] + seq))(list(farg s))
    return func(*newargs, **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keyword s = keywords
    return newfunc

    Here is example of use:
    [color=blue][color=green][color=darkred]
    >>> def capture(*args):[/color][/color][/color]
    return args
    [color=blue][color=green][color=darkred]
    >>> partial(capture )()[/color][/color][/color]
    ()[color=blue][color=green][color=darkred]
    >>> partial(capture , _)(1)[/color][/color][/color]
    (1,)[color=blue][color=green][color=darkred]
    >>> partial(capture , _, 2)(1)[/color][/color][/color]
    (1, 2)[color=blue][color=green][color=darkred]
    >>> partial(capture , 1)(2)[/color][/color][/color]
    (1, 2)[color=blue][color=green][color=darkred]
    >>> partial(capture , 1, _)(2)[/color][/color][/color]
    (1, 2)[color=blue][color=green][color=darkred]
    >>> partial(capture , 1, _)()[/color][/color][/color]
    IndexError: pop from empty list[color=blue][color=green][color=darkred]
    >>> partial(capture , 1, _, _)(2, 3)[/color][/color][/color]
    (1, 2, 3)

    Chris Perkins :
    [color=blue]
    > Random idea of the day: How about having syntax support for
    > currying/partial function application, like this:
    >
    > func(..., a, b)
    > func(a, ..., b)
    > func(a, b, ...)
    >
    > That is:
    > 1) Make an Ellipsis literal legal syntax in an argument list.
    > 2) Have the compiler recognize the Ellipsis literal and transform the
    > function call into a curried/parially applied function.
    >
    > So the compiler would essentially do something like this:
    >
    > func(a, ...) ==> curry(func, a)
    > func(..., a) ==> rightcurry(func , a)
    > func(a, ..., b) ==> rightcurry(curr y(func,a), b)
    >
    > I haven't though this through much, and I'm sure there are issues, but
    > I do like the way it looks. The "..." really stands out as saying
    > "something is omitted here".
    >
    >
    > Chris Perkins[/color]

  • Giovanni Bajo

    #2
    Re: PEP 309 (Partial Function Application) Idea

    Ronald Mai wrote:
    [color=blue]
    > Here is a reference implementation:
    >
    > _ = lambda x: x.pop(0)
    >
    > def partial(func, *args, **keywords):
    > def newfunc(*fargs, **fkeywords):
    > newkeywords = keywords.copy()
    > newkeywords.upd ate(fkeywords)
    > newargs = (lambda seq: tuple([(a == _ and a(seq)) or a for
    > a in args] + seq))(list(farg s))
    > return func(*newargs, **newkeywords)
    > newfunc.func = func
    > newfunc.args = args
    > newfunc.keyword s = keywords
    > return newfunc
    >
    > Here is example of use:
    >[color=green][color=darkred]
    >>>> def capture(*args):[/color][/color]
    > return args
    >[color=green][color=darkred]
    >>>> partial(capture )()[/color][/color]
    > ()[color=green][color=darkred]
    >>>> partial(capture , _)(1)[/color][/color]
    > (1,)[color=green][color=darkred]
    >>>> partial(capture , _, 2)(1)[/color][/color]
    > (1, 2)[color=green][color=darkred]
    >>>> partial(capture , 1)(2)[/color][/color]
    > (1, 2)[color=green][color=darkred]
    >>>> partial(capture , 1, _)(2)[/color][/color]
    > (1, 2)[color=green][color=darkred]
    >>>> partial(capture , 1, _)()[/color][/color]
    > IndexError: pop from empty list[color=green][color=darkred]
    >>>> partial(capture , 1, _, _)(2, 3)[/color][/color]
    > (1, 2, 3)[/color]

    Other implementations I have seen (boost::bind comes to mind) use ordered
    placeholders such as _1, _2, _3, etc to provide more flexibility in adaptation:
    [color=blue][color=green][color=darkred]
    >>> partial(capture , "a", _1, _2)("b", "c")[/color][/color][/color]
    ("a", "b", "c")[color=blue][color=green][color=darkred]
    >>> partial(capture , "a", _2, _1)("b", "c")[/color][/color][/color]
    ("a", "c", "b")

    I don't see mention of this in the PEP, but it's a nice feature to have IMO.
    --
    Giovanni Bajo


    Comment

    • bonono@gmail.com

      #3
      Re: PEP 309 (Partial Function Application) Idea


      Giovanni Bajo wrote:[color=blue]
      > Ronald Mai wrote:
      >[color=green]
      > > Here is a reference implementation:
      > >
      > > _ = lambda x: x.pop(0)
      > >
      > > def partial(func, *args, **keywords):
      > > def newfunc(*fargs, **fkeywords):
      > > newkeywords = keywords.copy()
      > > newkeywords.upd ate(fkeywords)
      > > newargs = (lambda seq: tuple([(a == _ and a(seq)) or a for
      > > a in args] + seq))(list(farg s))
      > > return func(*newargs, **newkeywords)
      > > newfunc.func = func
      > > newfunc.args = args
      > > newfunc.keyword s = keywords
      > > return newfunc
      > >
      > > Here is example of use:
      > >[color=darkred]
      > >>>> def capture(*args):[/color]
      > > return args
      > >[color=darkred]
      > >>>> partial(capture )()[/color]
      > > ()[color=darkred]
      > >>>> partial(capture , _)(1)[/color]
      > > (1,)[color=darkred]
      > >>>> partial(capture , _, 2)(1)[/color]
      > > (1, 2)[color=darkred]
      > >>>> partial(capture , 1)(2)[/color]
      > > (1, 2)[color=darkred]
      > >>>> partial(capture , 1, _)(2)[/color]
      > > (1, 2)[color=darkred]
      > >>>> partial(capture , 1, _)()[/color]
      > > IndexError: pop from empty list[color=darkred]
      > >>>> partial(capture , 1, _, _)(2, 3)[/color]
      > > (1, 2, 3)[/color]
      >
      > Other implementations I have seen (boost::bind comes to mind) use ordered
      > placeholders such as _1, _2, _3, etc to provide more flexibility in adaptation:
      >[color=green][color=darkred]
      > >>> partial(capture , "a", _1, _2)("b", "c")[/color][/color]
      > ("a", "b", "c")[color=green][color=darkred]
      > >>> partial(capture , "a", _2, _1)("b", "c")[/color][/color]
      > ("a", "c", "b")
      >
      > I don't see mention of this in the PEP, but it's a nice feature to have IMO.
      > --
      > Giovanni Bajo[/color]
      Since python has named parameter(and I assume this PEP would support it
      as well), is it really that useful to have these place holder things ?
      As when the parameter list gets long, named param should be easier to
      read.

      The only case I find it useful is for binary ops where I would like to
      either bind the left hand side or the right hand side but that can be
      handled easily with a "flip" function as in haskell.

      Comment

      • Giovanni Bajo

        #4
        Re: PEP 309 (Partial Function Application) Idea

        bonono@gmail.co m wrote:
        [color=blue]
        > Since python has named parameter(and I assume this PEP would support
        > it as well), is it really that useful to have these place holder things
        > ?[/color]

        Probably not so much, you're right.
        [color=blue]
        > As when the parameter list gets long, named param should be easier to
        > read.
        >
        > The only case I find it useful is for binary ops where I would like to
        > either bind the left hand side or the right hand side but that can be
        > handled easily with a "flip" function as in haskell.[/color]

        I'm not sure I'd like a specialized flip function, compared to the numbered
        placeholders solution.
        --
        Giovanni Bajo


        Comment

        • Ronald Mai

          #5
          Re: PEP 309 (Partial Function Application) Idea

          for a new function, named parameter might be a better choise, but for
          existing function, placeholder would be better, since you don't need to
          modify the exiting code.

          Comment

          • Ronald Mai

            #6
            Re: PEP 309 (Partial Function Application) Idea

            sorry, should be "existing"

            Comment

            • Ronald Mai

              #7
              Re: PEP 309 (Partial Function Application) Idea

              for a new function, named parameter might be a better choise, but for
              existing function, placeholder would be better, since you don't need to
              modify the existing code.

              Comment

              Working...