Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #110043 > unrolled thread

Method Chaining

Started byLawrence D’Oliveiro <lawrencedo99@gmail.com>
First post2016-06-16 19:02 -0700
Last post2016-06-17 17:02 -0700
Articles 20 on this page of 27 — 10 participants

Back to article view | Back to comp.lang.python


Contents

  Method Chaining Lawrence D’Oliveiro <lawrencedo99@gmail.com> - 2016-06-16 19:02 -0700
    Re: Method Chaining Steven D'Aprano <steve@pearwood.info> - 2016-06-17 12:39 +1000
    Re: Method Chaining Michael Selik <michael.selik@gmail.com> - 2016-06-17 04:23 +0000
      Re: Method Chaining Lawrence D’Oliveiro <lawrencedo99@gmail.com> - 2016-06-16 21:37 -0700
        Re: Method Chaining Ned Batchelder <ned@nedbatchelder.com> - 2016-06-17 01:13 -0700
          Re: Method Chaining Lawrence D’Oliveiro <lawrencedo99@gmail.com> - 2016-06-17 01:38 -0700
            Re: Method Chaining Jussi Piitulainen <jussi.piitulainen@helsinki.fi> - 2016-06-17 11:45 +0300
          Re: Method Chaining Steven D'Aprano <steve@pearwood.info> - 2016-06-17 19:28 +1000
            Re: Method Chaining Michael Selik <michael.selik@gmail.com> - 2016-06-17 13:34 +0000
              Re: Method Chaining Lawrence D’Oliveiro <lawrencedo99@gmail.com> - 2016-06-17 15:26 -0700
                Re: Method Chaining Michael Selik <michael.selik@gmail.com> - 2016-06-17 22:45 +0000
                Re: Method Chaining Michael Selik <michael.selik@gmail.com> - 2016-06-17 23:10 +0000
            Re: Method Chaining Rustom Mody <rustompmody@gmail.com> - 2016-06-17 09:48 -0700
              Re: Method Chaining Lawrence D’Oliveiro <lawrencedo99@gmail.com> - 2016-06-17 15:25 -0700
              Re: Method Chaining Pete Forman <petef4+usenet@gmail.com> - 2016-06-18 13:04 +0100
                Re: Method Chaining Joonas Liik <liik.joonas@gmail.com> - 2016-06-18 17:05 +0300
                  Re: Method Chaining Pete Forman <petef4+usenet@gmail.com> - 2016-06-18 16:42 +0100
                Re: Method Chaining Rustom Mody <rustompmody@gmail.com> - 2016-06-18 08:35 -0700
                  Re: Method Chaining Pete Forman <petef4+usenet@gmail.com> - 2016-06-19 11:16 +0100
                Re: Method Chaining Ethan Furman <ethan@stoneleaf.us> - 2016-06-18 13:47 -0700
                Re: Method Chaining Joonas Liik <liik.joonas@gmail.com> - 2016-06-19 14:56 +0300
                Re: Method Chaining Ethan Furman <ethan@stoneleaf.us> - 2016-06-19 08:01 -0700
                Re: Method Chaining Michael Torrie <torriem@gmail.com> - 2016-06-19 09:14 -0600
                Re: Method Chaining Ethan Furman <ethan@stoneleaf.us> - 2016-06-19 08:56 -0700
                  Re: Method Chaining Rustom Mody <rustompmody@gmail.com> - 2016-06-19 09:03 -0700
          Re: Method Chaining Lawrence D’Oliveiro <lawrencedo99@gmail.com> - 2016-06-17 15:22 -0700
            Re: Method Chaining Ned Batchelder <ned@nedbatchelder.com> - 2016-06-17 17:02 -0700

Page 1 of 2  [1] 2  Next page →


#110043 — Method Chaining

FromLawrence D’Oliveiro <lawrencedo99@gmail.com>
Date2016-06-16 19:02 -0700
SubjectMethod Chaining
Message-ID<74831a84-7b05-4242-b4c0-4a90d147717b@googlegroups.com>
Some kinds of objects often receive a whole lot of method calls in sequence. In these situations, it is handy if each method call ends with “return self”, so that you can chain the calls together. This is particularly common with graphics APIs, for instance.

Example from <http://default-cube.deviantart.com/art/Truchet-612095093>, concisely expressing a complex drawing sequence:

    (g
        .move_to((p1 + p2a) / 2)
        .line_to(p1 + (p2 - p1) * frac)
        .line_to((p1 + p1a) / 2)
        .stroke()
        .move_to((p2 + p2a) / 2)
        .line_to(p2 + (p1 - p2) * frac)
        .line_to((p2 + p1a) / 2)
        .stroke()
    )

Another example <http://default-cube.deviantart.com/art/Pattern-Dash-576369003>, where an object requires setup calls that cannot all be expressed in the constructor:

    pattern = \
        qah.Pattern.create_linear \
          (
            p0 = (0, 0),
            p1 = (pattern_length, 0), # base orientation is parallel to X-axis
            colour_stops =
                (
                    (0, Colour.from_hsva((0.475, 0.9, 0.8))),
                    (1, Colour.from_hsva((0.975, 0.9, 0.8))),
                )
          ).set_extend(CAIRO.EXTEND_REPEAT)

In <http://default-cube.deviantart.com/art/Shadow-Mask-533143786>, a temporary drawing context is created, used to create the image pattern, and then discarded, without even having to give it a name:

    mask = qah.ImageSurface.create \
      (
        format = CAIRO.FORMAT_RGB24,
        dimensions = dimensions * scale
      )
    (qah.Context.create(mask)
        .set_matrix(Matrix.scale(scale))
        .set_source_colour(primary[component])
        .set_operator(CAIRO.OPERATOR_SOURCE)
        .rectangle(spot)
        .fill()
    )

[toc] | [next] | [standalone]


#110044

FromSteven D'Aprano <steve@pearwood.info>
Date2016-06-17 12:39 +1000
Message-ID<576362d3$0$1602$c3e8da3$5496439d@news.astraweb.com>
In reply to#110043
On Fri, 17 Jun 2016 12:02 pm, Lawrence D’Oliveiro wrote:

> Some kinds of objects often receive a whole lot of method calls in
> sequence. In these situations, it is handy if each method call ends with
> “return self”, so that you can chain the calls together. This is
> particularly common with graphics APIs, for instance.
[...]


Yes, this is design that (for example) Ruby classes tend to follow. It's not
one that the Python builtins tend to follow, but of course people are free
to return self from their own classes' methods if they like.

As an alternative, you might find this simple adaptor useful:

http://code.activestate.com/recipes/578770-method-chaining/



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#110046

FromMichael Selik <michael.selik@gmail.com>
Date2016-06-17 04:23 +0000
Message-ID<mailman.99.1466137450.2288.python-list@python.org>
In reply to#110043
On Thu, Jun 16, 2016 at 10:53 PM Lawrence D’Oliveiro <lawrencedo99@gmail.com>
wrote:

> Example from <http://default-cube.deviantart.com/art/Truchet-612095093>,
> concisely expressing a complex drawing sequence:
>
>     (g
>         .move_to((p1 + p2a) / 2)
>         .line_to(p1 + (p2 - p1) * frac)
>         .line_to((p1 + p1a) / 2)
>         .stroke()
>         .move_to((p2 + p2a) / 2)
>         .line_to(p2 + (p1 - p2) * frac)
>         .line_to((p2 + p1a) / 2)
>         .stroke()
>     )
>

Wouldn't that look nicer with the ``g`` repeated on every line, no extra
indentation, and no extraneous parentheses?

    g.move_to((p1 + p2a) / 2)
    g.line_to(p1 + (p2 - p1) * frac)
    g.line_to((p1 + p1a) / 2)
    g.stroke()
    g.move_to((p2 + p2a) / 2)
    g.line_to(p2 + (p1 - p2) * frac)
    g.line_to((p2 + p1a) / 2)
    g.stroke()

Sometimes it's hard to know when a function has a side-effect. I appreciate
that these impure functions tend to return None.

[toc] | [prev] | [next] | [standalone]


#110047

FromLawrence D’Oliveiro <lawrencedo99@gmail.com>
Date2016-06-16 21:37 -0700
Message-ID<33f73a24-4dcf-429b-9264-a3f3098f1cc3@googlegroups.com>
In reply to#110046
On Friday, June 17, 2016 at 4:24:24 PM UTC+12, Michael Selik wrote:
> On Thu, Jun 16, 2016 at 10:53 PM Lawrence D’Oliveiro wrote:
> 
> > Example from <http://default-cube.deviantart.com/art/Truchet-612095093>,
> > concisely expressing a complex drawing sequence:
> >
> >     (g
> >         .move_to((p1 + p2a) / 2)
> >         .line_to(p1 + (p2 - p1) * frac)
> >         .line_to((p1 + p1a) / 2)
> >         .stroke()
> >         .move_to((p2 + p2a) / 2)
> >         .line_to(p2 + (p1 - p2) * frac)
> >         .line_to((p2 + p1a) / 2)
> >         .stroke()
> >     )
> 
> Wouldn't that look nicer with the ``g`` repeated on every line, no extra
> indentation, and no extraneous parentheses?
> 
>     g.move_to((p1 + p2a) / 2)
>     g.line_to(p1 + (p2 - p1) * frac)
>     g.line_to((p1 + p1a) / 2)
>     g.stroke()
>     g.move_to((p2 + p2a) / 2)
>     g.line_to(p2 + (p1 - p2) * frac)
>     g.line_to((p2 + p1a) / 2)
>     g.stroke()

Clearly, no.

[toc] | [prev] | [next] | [standalone]


#110049

FromNed Batchelder <ned@nedbatchelder.com>
Date2016-06-17 01:13 -0700
Message-ID<ed84c81e-a905-48d9-96ca-58aa5f419e68@googlegroups.com>
In reply to#110047
On Friday, June 17, 2016 at 12:37:14 AM UTC-4, Lawrence D’Oliveiro wrote:
> On Friday, June 17, 2016 at 4:24:24 PM UTC+12, Michael Selik wrote:
> > On Thu, Jun 16, 2016 at 10:53 PM Lawrence D’Oliveiro wrote:
> > 
> > > Example from <http://default-cube.deviantart.com/art/Truchet-612095093>,
> > > concisely expressing a complex drawing sequence:
> > >
> > >     (g
> > >         .move_to((p1 + p2a) / 2)
> > >         .line_to(p1 + (p2 - p1) * frac)
> > >         .line_to((p1 + p1a) / 2)
> > >         .stroke()
> > >         .move_to((p2 + p2a) / 2)
> > >         .line_to(p2 + (p1 - p2) * frac)
> > >         .line_to((p2 + p1a) / 2)
> > >         .stroke()
> > >     )
> > 
> > Wouldn't that look nicer with the ``g`` repeated on every line, no extra
> > indentation, and no extraneous parentheses?
> > 
> >     g.move_to((p1 + p2a) / 2)
> >     g.line_to(p1 + (p2 - p1) * frac)
> >     g.line_to((p1 + p1a) / 2)
> >     g.stroke()
> >     g.move_to((p2 + p2a) / 2)
> >     g.line_to(p2 + (p1 - p2) * frac)
> >     g.line_to((p2 + p1a) / 2)
> >     g.stroke()
> 
> Clearly, no.

To me, it's a toss-up.  The chained version is nice in that it removes the
repetition of "g".  But the unchained version is more explicit, and avoids
the awkward parenthesis.

I think I would lean toward the unchained version.  Clearly tastes can
differ.

--Ned.

[toc] | [prev] | [next] | [standalone]


#110050

FromLawrence D’Oliveiro <lawrencedo99@gmail.com>
Date2016-06-17 01:38 -0700
Message-ID<9f4ac957-f29e-4433-813a-fbebb69fff37@googlegroups.com>
In reply to#110049
On Friday, June 17, 2016 at 8:13:50 PM UTC+12, Ned Batchelder wrote:
> But the unchained version is more explicit, and avoids
> the awkward parenthesis.

What if it had been

    the_context.move_to((p1 + p2a) / 2)
    the_context.line_to(p1 + (p2 - p1) * frac)
    the_context.line_to((p1 + p1a) / 2)
    the_context.stroke()
    the_context.move_to((p2 + p2a) / 2)
    the_context.line_to(p2 + (p1 - p2) * frac)
    the_context.line_to((p2 + p1a) / 2)
    the_context.stroke()

?

[toc] | [prev] | [next] | [standalone]


#110051

FromJussi Piitulainen <jussi.piitulainen@helsinki.fi>
Date2016-06-17 11:45 +0300
Message-ID<lf5a8ikursw.fsf@ling.helsinki.fi>
In reply to#110050
Lawrence D’Oliveiro writes:

> On Friday, June 17, 2016 at 8:13:50 PM UTC+12, Ned Batchelder wrote:
>> But the unchained version is more explicit, and avoids
>> the awkward parenthesis.
>
> What if it had been
>
>     the_context.move_to((p1 + p2a) / 2)
>     the_context.line_to(p1 + (p2 - p1) * frac)
>     the_context.line_to((p1 + p1a) / 2)
>     the_context.stroke()
>     the_context.move_to((p2 + p2a) / 2)
>     the_context.line_to(p2 + (p1 - p2) * frac)
>     the_context.line_to((p2 + p1a) / 2)
>     the_context.stroke()
>
> ?

g = the_context
g.move_to((p1 + p2a) / 2)
g.line_to(p1 + (p2 - p1) * frac)
g.line_to((p1 + p1a) / 2)
g.stroke()
g.move_to((p2 + p2a) / 2)
g.line_to(p2 + (p1 - p2) * frac)
g.line_to((p2 + p1a) / 2)
g.stroke()

[toc] | [prev] | [next] | [standalone]


#110052

FromSteven D'Aprano <steve@pearwood.info>
Date2016-06-17 19:28 +1000
Message-ID<5763c2a7$0$1602$c3e8da3$5496439d@news.astraweb.com>
In reply to#110049
On Fri, 17 Jun 2016 06:13 pm, Ned Batchelder wrote:

> To me, it's a toss-up.  The chained version is nice in that it removes the
> repetition of "g".  But the unchained version is more explicit, and avoids
> the awkward parenthesis.
> 
> I think I would lean toward the unchained version.  Clearly tastes can
> differ.

Indeed. For what it's worth, I'm ever-so-slightly leaning towards Lawrence's
taste here. What Michael Selik earlier described as advantages of the
explicit version:

g.move_to((p1 + p2a) / 2)
g.line_to(p1 + (p2 - p1) * frac)
g.line_to((p1 + p1a) / 2)
g.stroke()


namely, "no extra indentation, and no extraneous parentheses", is to me a
negative, not a positive. Since all these commands belong together in some
sense, I like the chained version:

(g.move_to((p1 + p2a) / 2)
  .line_to(p1 + (p2 - p1) * frac)
  .line_to((p1 + p1a) / 2)
  .stroke()
  )


as the parens and indentation more clearly mark this chunk of code as a
unit. On the other hand, I like the fact that methods which are
conceptually procedures that operate by side-effect return None. So it's
hard to decide precisely which behaviour is better. Its very much a matter
of taste.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#110053

FromMichael Selik <michael.selik@gmail.com>
Date2016-06-17 13:34 +0000
Message-ID<mailman.102.1466170491.2288.python-list@python.org>
In reply to#110052
On Fri, Jun 17, 2016 at 5:31 AM Steven D'Aprano <steve@pearwood.info> wrote:

> (g.move_to((p1 + p2a) / 2)
>   .line_to(p1 + (p2 - p1) * frac)
>   .line_to((p1 + p1a) / 2)
>   .stroke()
>   )
>
> the parens and indentation more clearly mark this chunk of code as a
> unit.


I prefer reserving indentation for where they're required ("for", "while",
"if", etc.). In this case, I'd use an extra blank line before and after.
Or, better, I'd move the chunk of code into a function by itself.

On the other hand, I like the fact that methods which are
> conceptually procedures that operate by side-effect return None.
>

Exactly. The chained version looks like each method is returning a modified
copy. The Pandas library isn't perfect, but it has a good consistency for
methods returning copies unless explicitly "inplace=True", in which case
the method returns None.

Paraphrasing Jakob's law of user experience [0], it doesn't matter if your
design is better. People are more familiar with the design of other
libraries and will expect yours to behave the same way: impure methods
return None, unless named "pop" or a similar standard.

[0] https://www.nngroup.com/articles/end-of-web-design/

[toc] | [prev] | [next] | [standalone]


#110062

FromLawrence D’Oliveiro <lawrencedo99@gmail.com>
Date2016-06-17 15:26 -0700
Message-ID<bbb0309b-c01f-4d67-8e5f-56433ac91411@googlegroups.com>
In reply to#110053
On Saturday, June 18, 2016 at 1:35:06 AM UTC+12, Michael Selik wrote:

> The chained version looks like each method is returning a modified
> copy.

As opposed to a modified original?

[toc] | [prev] | [next] | [standalone]


#110063

FromMichael Selik <michael.selik@gmail.com>
Date2016-06-17 22:45 +0000
Message-ID<mailman.105.1466203517.2288.python-list@python.org>
In reply to#110062
On Fri, Jun 17, 2016, 6:42 PM Lawrence D’Oliveiro <lawrencedo99@gmail.com>
wrote:

> On Saturday, June 18, 2016 at 1:35:06 AM UTC+12, Michael Selik wrote:
>
> > The chained version looks like each method is returning a modified
> > copy.
>
> As opposed to a modified original?
>

Correct. Read the rationale for list.sort returning None. It's in the
Python design FAQ.

>

[toc] | [prev] | [next] | [standalone]


#110065

FromMichael Selik <michael.selik@gmail.com>
Date2016-06-17 23:10 +0000
Message-ID<mailman.106.1466205022.2288.python-list@python.org>
In reply to#110062
On Fri, Jun 17, 2016, 6:44 PM Michael Selik <michael.selik@gmail.com> wrote:

>
>
> On Fri, Jun 17, 2016, 6:42 PM Lawrence D’Oliveiro <lawrencedo99@gmail.com>
> wrote:
>
>> On Saturday, June 18, 2016 at 1:35:06 AM UTC+12, Michael Selik wrote:
>>
>> > The chained version looks like each method is returning a modified
>> > copy.
>>
>> As opposed to a modified original?
>>
>
> Correct. Read the rationale for list.sort returning None. It's in the
> Python design FAQ.
>

Sorry, I should have included the link.

https://docs.python.org/2/faq/design.html#why-doesn-t-list-sort-return-the-sorted-list

Even if we're talking about a non-mutation side-effect, I think the same
rationale applies.

[toc] | [prev] | [next] | [standalone]


#110055

FromRustom Mody <rustompmody@gmail.com>
Date2016-06-17 09:48 -0700
Message-ID<2dffea93-3dbd-4d04-93ed-6e02e3dd8660@googlegroups.com>
In reply to#110052
On Friday, June 17, 2016 at 2:58:19 PM UTC+5:30, Steven D'Aprano wrote:
> On Fri, 17 Jun 2016 06:13 pm, Ned Batchelder wrote:
> 
> > To me, it's a toss-up.  The chained version is nice in that it removes the
> > repetition of "g".  But the unchained version is more explicit, and avoids
> > the awkward parenthesis.
> > 
> > I think I would lean toward the unchained version.  Clearly tastes can
> > differ.
> 
> Indeed. For what it's worth, I'm ever-so-slightly leaning towards Lawrence's
> taste here.

More than 'slightly' out here!
One thing about python OOP that irritates me is the 'self.' clutter.
With a Pascal/VB style with-statement its naturally taken care of

Yeah I know there is this FAQ:
https://docs.python.org/2/faq/design.html#why-doesn-t-python-have-a-with-statement-for-attribute-assignments

I consider it bogus if we allow with to mean something like:
https://msdn.microsoft.com/en-us/library/wc500chb.aspx

[toc] | [prev] | [next] | [standalone]


#110061

FromLawrence D’Oliveiro <lawrencedo99@gmail.com>
Date2016-06-17 15:25 -0700
Message-ID<687c72ec-c532-4823-9106-f74e30709ada@googlegroups.com>
In reply to#110055
On Saturday, June 18, 2016 at 4:48:30 AM UTC+12, Rustom Mody wrote:

> One thing about python OOP that irritates me is the 'self.' clutter.
> With a Pascal/VB style with-statement its naturally taken care of

I used to use “with”-statements back in my Pascal days. Then I had this nasty bug where a piece of code I wrote didn’t mean what I thought it meant (which wasn’t supposed to happen in Pascal). For months I blamed the bug on the app API (HyperCard)...

Once I realized my mistake, I went off “with”-statements completely.

[toc] | [prev] | [next] | [standalone]


#110096

FromPete Forman <petef4+usenet@gmail.com>
Date2016-06-18 13:04 +0100
Message-ID<m1inx6wvni.fsf@iKarel.lan>
In reply to#110055
Rustom Mody <rustompmody@gmail.com> writes:

> On Friday, June 17, 2016 at 2:58:19 PM UTC+5:30, Steven D'Aprano wrote:
>> On Fri, 17 Jun 2016 06:13 pm, Ned Batchelder wrote:
>>
>> > To me, it's a toss-up. The chained version is nice in that it
>> > removes the repetition of "g". But the unchained version is more
>> > explicit, and avoids the awkward parenthesis.
>> >
>> > I think I would lean toward the unchained version. Clearly tastes
>> > can differ.
>>
>> Indeed. For what it's worth, I'm ever-so-slightly leaning towards
>> Lawrence's taste here.
>
> More than 'slightly' out here!
> One thing about python OOP that irritates me is the 'self.' clutter.
> With a Pascal/VB style with-statement its naturally taken care of
>
> Yeah I know there is this FAQ:
> https://docs.python.org/2/faq/design.html#why-doesn-t-python-have-a-with-statement-for-attribute-assignments
>
> I consider it bogus if we allow with to mean something like:
> https://msdn.microsoft.com/en-us/library/wc500chb.aspx

One subtle difference between your two citations is that VB uses a
leading dot. Might that lessening of ambiguity enable a future Python to
allow this?

class Foo:
    def .set(a):  # equivalent to def set(self, a):
        .a = a    # equivalent to self.a = a

Unless it is in a with statement

with obj:
    .a = 1                # equivalent to obj.a = 1
    .total = .total + 1   # obj.total = obj.total + 1

-- 
Pete Forman

[toc] | [prev] | [next] | [standalone]


#110099

FromJoonas Liik <liik.joonas@gmail.com>
Date2016-06-18 17:05 +0300
Message-ID<mailman.116.1466258729.2288.python-list@python.org>
In reply to#110096
On 18 June 2016 at 15:04, Pete Forman <petef4+usenet@gmail.com> wrote:
> Rustom Mody <rustompmody@gmail.com> writes:
>
>> On Friday, June 17, 2016 at 2:58:19 PM UTC+5:30, Steven D'Aprano wrote:
>>> On Fri, 17 Jun 2016 06:13 pm, Ned Batchelder wrote:
>>>
>>> > To me, it's a toss-up. The chained version is nice in that it
>>> > removes the repetition of "g". But the unchained version is more
>>> > explicit, and avoids the awkward parenthesis.
>>> >
>>> > I think I would lean toward the unchained version. Clearly tastes
>>> > can differ.
>>>
>>> Indeed. For what it's worth, I'm ever-so-slightly leaning towards
>>> Lawrence's taste here.
>>
>> More than 'slightly' out here!
>> One thing about python OOP that irritates me is the 'self.' clutter.
>> With a Pascal/VB style with-statement its naturally taken care of
>>
>> Yeah I know there is this FAQ:
>> https://docs.python.org/2/faq/design.html#why-doesn-t-python-have-a-with-statement-for-attribute-assignments
>>
>> I consider it bogus if we allow with to mean something like:
>> https://msdn.microsoft.com/en-us/library/wc500chb.aspx
>
> One subtle difference between your two citations is that VB uses a
> leading dot. Might that lessening of ambiguity enable a future Python to
> allow this?
>
> class Foo:
>     def .set(a):  # equivalent to def set(self, a):
>         .a = a    # equivalent to self.a = a
>
> Unless it is in a with statement
>
> with obj:
>     .a = 1                # equivalent to obj.a = 1
>     .total = .total + 1   # obj.total = obj.total + 1
>
> --
> Pete Forman
> --
> https://mail.python.org/mailman/listinfo/python-list

the leading dot does not resolve the ambiguity that arises from:

with ob_a:
    with ob_b:
        .attr_c = 42 # which object are we modifying right now?

also refer to "javascript the bad parts" about all the edege cases
that python would surely face.
also with is allready used for context managers..

[toc] | [prev] | [next] | [standalone]


#110104

FromPete Forman <petef4+usenet@gmail.com>
Date2016-06-18 16:42 +0100
Message-ID<m1d1newlkg.fsf@iKarel.lan>
In reply to#110099
Joonas Liik <liik.joonas@gmail.com> writes:

> On 18 June 2016 at 15:04, Pete Forman <petef4+usenet@gmail.com> wrote:
>> Rustom Mody <rustompmody@gmail.com> writes:
>>
>>> On Friday, June 17, 2016 at 2:58:19 PM UTC+5:30, Steven D'Aprano wrote:
>>>> On Fri, 17 Jun 2016 06:13 pm, Ned Batchelder wrote:
>>>>
>>>> > To me, it's a toss-up. The chained version is nice in that it
>>>> > removes the repetition of "g". But the unchained version is more
>>>> > explicit, and avoids the awkward parenthesis.
>>>> >
>>>> > I think I would lean toward the unchained version. Clearly tastes
>>>> > can differ.
>>>>
>>>> Indeed. For what it's worth, I'm ever-so-slightly leaning towards
>>>> Lawrence's taste here.
>>>
>>> More than 'slightly' out here!
>>> One thing about python OOP that irritates me is the 'self.' clutter.
>>> With a Pascal/VB style with-statement its naturally taken care of
>>>
>>> Yeah I know there is this FAQ:
>>> https://docs.python.org/2/faq/design.html#why-doesn-t-python-have-a-with-statement-for-attribute-assignments
>>>
>>> I consider it bogus if we allow with to mean something like:
>>> https://msdn.microsoft.com/en-us/library/wc500chb.aspx
>>
>> One subtle difference between your two citations is that VB uses a
>> leading dot. Might that lessening of ambiguity enable a future Python to
>> allow this?
>>
>> class Foo:
>>     def .set(a):  # equivalent to def set(self, a):
>>         .a = a    # equivalent to self.a = a
>>
>> Unless it is in a with statement
>>
>> with obj:
>>     .a = 1                # equivalent to obj.a = 1
>>     .total = .total + 1   # obj.total = obj.total + 1
>>
>> --
>> Pete Forman
>> --
>> https://mail.python.org/mailman/listinfo/python-list
>
> the leading dot does not resolve the ambiguity that arises from:
>
> with ob_a:
>     with ob_b:
>         .attr_c = 42 # which object are we modifying right now?
>
> also refer to "javascript the bad parts" about all the edege cases
> that python would surely face.
> also with is allready used for context managers..

Yes, I ought not to have lumped in the with proposal with that for self.
Python's design FAQ clearly explains why the language does not need that
form of "with".

-- 
Pete Forman

[toc] | [prev] | [next] | [standalone]


#110103

FromRustom Mody <rustompmody@gmail.com>
Date2016-06-18 08:35 -0700
Message-ID<df520243-c3c0-4fe1-95ee-ba1eb8bd9305@googlegroups.com>
In reply to#110096
On Saturday, June 18, 2016 at 5:34:30 PM UTC+5:30, Pete Forman wrote:
> Rustom Mody  writes:
> 
> > On Friday, June 17, 2016 at 2:58:19 PM UTC+5:30, Steven D'Aprano wrote:
> >> On Fri, 17 Jun 2016 06:13 pm, Ned Batchelder wrote:
> >>
> >> > To me, it's a toss-up. The chained version is nice in that it
> >> > removes the repetition of "g". But the unchained version is more
> >> > explicit, and avoids the awkward parenthesis.
> >> >
> >> > I think I would lean toward the unchained version. Clearly tastes
> >> > can differ.
> >>
> >> Indeed. For what it's worth, I'm ever-so-slightly leaning towards
> >> Lawrence's taste here.
> >
> > More than 'slightly' out here!
> > One thing about python OOP that irritates me is the 'self.' clutter.
> > With a Pascal/VB style with-statement its naturally taken care of
> >
> > Yeah I know there is this FAQ:
> > https://docs.python.org/2/faq/design.html#why-doesn-t-python-have-a-with-statement-for-attribute-assignments
> >
> > I consider it bogus if we allow with to mean something like:
> > https://msdn.microsoft.com/en-us/library/wc500chb.aspx
> 
> One subtle difference between your two citations is that VB uses a
> leading dot. Might that lessening of ambiguity enable a future Python to
> allow this?
> 
> class Foo:
>     def .set(a):  # equivalent to def set(self, a):
>         .a = a    # equivalent to self.a = a
> 

Chuckle! Heck Why not?!
But no I did not think of this

> Unless it is in a with statement
> 
> with obj:
>     .a = 1                # equivalent to obj.a = 1
>     .total = .total + 1   # obj.total = obj.total + 1


I intended only this much viz that the syntactic marker '.' disambiguates
between ordinary variable and attribute

As for what happens when there are nested references as mentioned by Waffle:
Well these ambiguities have a venerable vintage in programming languages
Starting from the dangling else to which declaration a variable refers to
when there are nested scopes and much else ie "match-to-the-innermost" seems
to be obvious enough

[toc] | [prev] | [next] | [standalone]


#110136

FromPete Forman <petef4+usenet@gmail.com>
Date2016-06-19 11:16 +0100
Message-ID<m18ty1wkj6.fsf@iKarel.lan>
In reply to#110103
Rustom Mody <rustompmody@gmail.com> writes:

> On Saturday, June 18, 2016 at 5:34:30 PM UTC+5:30, Pete Forman wrote:
>> Rustom Mody  writes:
>> [snip]
>>
>> One subtle difference between your two citations is that VB uses a
>> leading dot. Might that lessening of ambiguity enable a future Python to
>> allow this?
>>
>> class Foo:
>>     def .set(a):  # equivalent to def set(self, a):
>>         .a = a    # equivalent to self.a = a
>>
>
> Chuckle! Heck Why not?!
> But no I did not think of this

Why stop there? Another long standing bugbear can be addressed with
this.

class Foo:
    def .set(.a, b)  # equivalent to def set(self, a): self.a = a
        .c += b      # equivalent to self.c += b

Explicitly, that is three new syntactic items.

1) . before a method name elides the first argument of self
2) . before an argument is shorthand for assign to a member
3) . before a variable in a method body replaces self.

Earlier I had proposed a new use of "with" that would have changed the
binding in (3) from self to something else. That was not a good idea for
two reasons. Python already provides a reasonable way to achieve that,
as described in the design FAQ. The second reason is that it subverts
the current "with" statement which mandates its with_item to be a
context expression. "as target" is optional and so syntactic
discrimination is not possible.

-- 
Pete Forman

[toc] | [prev] | [next] | [standalone]


#110113

FromEthan Furman <ethan@stoneleaf.us>
Date2016-06-18 13:47 -0700
Message-ID<mailman.121.1466282865.2288.python-list@python.org>
In reply to#110096
On 06/18/2016 07:05 AM, Joonas Liik wrote:
> On 18 June 2016 at 15:04, Pete Forman wrote:

>> with obj:
>>      .a = 1                # equivalent to obj.a = 1
>>      .total = .total + 1   # obj.total = obj.total + 1
>
> the leading dot does not resolve the ambiguity that arises from:
>
> with ob_a:
>      with ob_b:
>          .attr_c = 42 # which object are we modifying right now?

The innermost one.  Why would it be anything else?

--
~Ethan~

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.python


csiph-web