<div dir="ltr"><div><div><div>Nope sorry I've misread your code, but it changes nothing.<br></div><div><br></div>for example with spam(args)->eggs()->cheese()<br><br></div><div>if instead you have:<br></div><div>args=something<br></div><div>spam = lambda: args<br><br></div><div>spam()->eggs()->cheese()<br></div><div>should be treaten as: cheese(eggs(spam())) or cheese(eggs(args)) or partial(cheese) circle partial(eggs) circle partial(spam) ?<br></div><div><br><br></div><div>I don't find this syntax convenient, sorry.<br></div><div><br><br></div><div><br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">2015-05-10 23:41 GMT+02:00 Koos Zevenhoven <span dir="ltr"><<a href="mailto:koos.zevenhoven@aalto.fi" target="_blank">koos.zevenhoven@aalto.fi</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  
    
  
  <div bgcolor="#FFFFFF" text="#000000">
    Hi Gregory,<br>
    <br>
    Did you look at the new version carefully? If I understand the
    problem you are describing (mentioned also by Steven), my previous
    version had that issue, but the new one does not. That is why I
    added examples with callable arguments :).<span class="HOEnZb"><font color="#888888"><br>
    <br>
    -- Koos</font></span><div><div class="h5"><br>
    <br>
    <br>
    <div>On 11.5.2015 0:23, Gregory Salvan
      wrote:<br>
    </div>
    <blockquote type="cite">
      
      <div dir="ltr">
        <div>
          <div>
            <div>
              <div>
                <div>
                  <div>
                    <div>
                      <div>In my opinion, this syntax make problems when
                        your arguments are functions/callables.<br>
                        And if you code in a functionnal paradigm it is
                        quite common to inject functions in arguments
                        otherwise how would you do polymorphism ?<br>
                        <br>
                      </div>
                      The only way I see to distinguish cases is to have
                      tuples, but syntax is quite strange.<br>
                      <br>
                      instead of : arg->eggs(b)->spam(c)<br>
                    </div>
                    my_partial = (arg, b)->eggs->(c, )->spam<br>
                    <br>
                  </div>
                  Then how would you call my_partial ?<br>
                </div>
                For example, if you have:<br>
              </div>
              def eggs(a, b, c)...<br>
            </div>
            def spam(d, e)...<br>
            <br>
          </div>
          my_partial(c, e) or my_partial(c)(e) ?<br>
        </div>
        <div><br>
          <div>
            <div>
              <div>
                <div>
                  <div><br>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="gmail_extra"><br>
        <div class="gmail_quote">2015-05-10 22:06 GMT+02:00 Koos
          Zevenhoven <span dir="ltr"><<a href="mailto:koos.zevenhoven@aalto.fi" target="_blank">koos.zevenhoven@aalto.fi</a>></span>:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Reading
            the recent emails in the function composition thread started
            by Ivan, I realized that my below sketch for a composition
            operator would be better if it did not actually do function
            composition ;). Instead, -> would be quite powerful as
            'just' a partial operator -- perhaps even more powerful, as
            I demonstrate below. However, this is not an argument
            against @ composition, which might in fact play together
            with this quite nicely.<br>
            <br>
            This allows some nice things with multi-argument functions
            too.<br>
            <br>
            I realize that it may be unlikely that a new operator would
            be added, but here it is anyway, as food for thought.  (With
            an existing operator, I suspect it would be even less
            likely, because of precedence rules : )<br>
            <br>
            So, -> would be an operator with a precedence similar to
            .attribute access (but lower than .attribute):<br>
            <br>
             # The simple definition of what it does:<br>
             arg->func   # equivalent to functools.partial(func, arg)<br>
            <br>
            This would allow for instance:<br>
             arg -> spam() -> cheese(kind = 'gouda') -> eggs()<br>
            <br>
            which would be equivalent to eggs(cheese(spam(arg), kind =
            'gouda'))<br>
            <br>
            Or even together together with the proposed @ composition:<br>
             rms = root @ mean @ square->map     # for an iterable
            non-numpy argument<br>
            <br>
            And here's something I find quite interesting. Together with
            @singledispatch from 3.4 (or possibly an enhanced version
            using type annotations in the future?), one could add
            'third-party methods' to classes in other libraries without
            monkey patching. A dummy example:<br>
            <br>
            from numpy import array<br>
            my_list = [1,2,3]<br>
            my_array = array(my_list)<br>
            my_mean = my_array.mean()  # This currently works in numpy<br>
            <br>
            from rmslib import rms<br>
            my_rms = my_array->rms()  # efficient rms for numpy
            arrays<br>
            my_other_rms = my_list->rms()  # rms that works on any
            iterable<br>
            <br>
            One would be able to distinguish between calls to methods
            and 'third-party methods' based on whether . or -> is
            used for accessing them, which I think is a good thing.
            Also, third-party methods would be less likely to mutate the
            object, just like func(obj) is less likely to mutate obj
            than obj.method().<br>
            <br>
            See more examples below. I converted my examples from last
            night to this IMO better version, because at least some of
            them would still be relevant.<br>
            <br>
            On 10.5.2015 2:07, Koos Zevenhoven wrote:<br>
            <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
              On 10.5.2015 1:03, Gregory Salvan wrote:<br>
              <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
                Nobody convinced by arrow operator ?<br>
                <br>
                like: arg -> spam -> eggs -> cheese<br>
                or cheese <- eggs <- spam <- arg<br>
                <br>
                <br>
              </blockquote>
              <br>
              I like | a lot because of the pipe analogy. However,
              having a new operator for this could solve some issues
              about operator precedence.<br>
              <br>
              Today, I sketched one possible version that would use a
              new .. operator. I'll explain what it would do (but with
              your -> instead of my ..)<br>
              <br>
              Here, the operator (.. or ->) would have a higher
              precedence than function calls () but a lower precedence
              than attribute access (obj.attr).<br>
              <br>
              First, with single-argument functions spam, eggs and
              cheese, and a non-function arg:<br>
              <br>
              arg->eggs->spam->cheese()   # equivalent to
              cheese(spam(eggs(arg)))<br>
            </blockquote>
            <br>
            With -> as a partial operator, this would instead be:<br>
            <br>
            arg->eggs()->spam()->cheese()     # equivalent to
            cheese(spam(eggs(arg)))<br>
            <br>
            <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
              eggs->spam->cheese  # equivalent to lambda arg:
              cheese(spam(eggs(arg)))<br>
              <br>
            </blockquote>
            <br>
            With -> as a partial operator this could be:<br>
            <br>
            lambda arg: arg->eggs()->spam()->cheese()<br>
            <br>
            <br>
            <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
              Then, if spam and eggs both took two arguments; eggs(arg1,
              arg2), spam(arg1, arg2)<br>
              <br>
              arg->eggs   # equivalent to partial(eggs, arg)<br>
              eggs->spam(a, b, c)   # equivalent to spam(eggs(a, b),
              c)<br>
            </blockquote>
            <br>
            With -> as a partial operator, the first one would work,
            and the second would become:<br>
            <br>
            eggs(a,b)->spam(c)     # equivalent to spam(eggs(a, b),
            c)<br>
            <br>
            <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
              arg->eggs->spam(b,c)    # equivalent to
              spam(eggs(arg, b), c)<br>
              <br>
            </blockquote>
            <br>
            This would become:<br>
            <br>
            arg->eggs(b)->spam(c)     # equivalent to
            spam(eggs(arg, b), c)<br>
            <br>
            Note that this would be quite flexible in partial 'piping'
            of multi-argument functions.<br>
            <br>
            <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
              So you could think of -> as an extended partial
              operator. And this would naturally generalize to functions
              with even more arguments. The arguments would always be
              fed in the same order as in the equivalent function call,
              which makes for a nice rule of thumb. However, I suppose
              one would usually avoid combinations that are difficult to
              understand.<br>
              <br>
              Some examples that this would enable:<br>
              <br>
               # Example 1<br>
               from numpy import square, mean, sqrt<br>
               rms = square->mean->sqrt  # I think this order is
              fine because it is not @<br>
              <br>
            </blockquote>
            <br>
            This would become:<br>
            <br>
            def rms(arr):<br>
                return arr->square()->mean()->sqrt()<br>
            <br>
            <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
               # Example 2 (both are equivalent)<br>
               spam(args)->eggs->cheese() # the shell-syntax
              analogy that Steven mentioned.<br>
              <br>
            </blockquote>
            <br>
            This would be:<br>
            <br>
            spam(args)->eggs()->cheese()<br>
            <br>
            Of course the shell piping analogy would be quite far,
            because it looks so different.<br>
            <br>
            <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
               # Example 3<br>
               # Last but not least, we would finally have this :)<br>
               some_sequence->len()<br>
               some_object->isinstance(MyType)<br>
              <br>
            </blockquote>
            <br>
            And:<br>
            <br>
             func->map(seq)<br>
             func->reduce(seq)<br>
            <br>
            -- Koos<br>
            <br>
            <br>
            <br>
            <br>
            <br>
            _______________________________________________<br>
            Python-ideas mailing list<br>
            <a href="mailto:Python-ideas@python.org" target="_blank">Python-ideas@python.org</a><br>
            <a href="https://mail.python.org/mailman/listinfo/python-ideas" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br>
            Code of Conduct: <a href="http://python.org/psf/codeofconduct/" target="_blank">http://python.org/psf/codeofconduct/</a><br>
          </blockquote>
        </div>
        <br>
      </div>
    </blockquote>
    <br>
  </div></div></div>

</blockquote></div><br></div>