[Python-ideas] Dart-like method cascading operator in Python

Perešíni Peter ppershing at gmail.com
Fri Nov 22 09:23:29 CET 2013


Thanks Steve for very useful comments


>  Please give examples of how this might do such a thing, rather than just
> claim it will. "This syntax will end world hunger and bring peace to the
> Middle East..." I don't see how this syntax can simplify instantiating
> objects:
>
> obj = MyClass("spam", "eggs")
>
> is already pretty simple. Perhaps you're referring only to a small
> subset of (in my opinion) *poorly designed* if not outright buggy
> objects which aren't instantiated completely on creation and need to be
> tweaked by hand before being ready to use. Or those with excessively
> complicated APIs that could really do with a few helper functions.
>

I do not agree that all objects that are mutable are poorly designed.
Anything which is tree-like (e.g. mentioned DSLs, API wrappers around
complicated objects (e.g. xml), configurations, gnuplot example, ...) can
be difficult to instantiate using normal syntax:

tree = Tree()
  ..newChild(value=5)
      ..newChild(value=3)
      ..newChild()
  ..newChild(color="green")


Now, that said, sometimes you can turn this instatiation to be more
Pythonic, e.g. (using lists instead of repetitive calls of "addSomething")
but it is hard to visually parse (distinguish between end of constructors
vs end of lists):

tree = Tree(children=[
   Node(value=5, children=[
       Node(value=3),
       Node()
   ]),
   Node(color="green")
])

Alternative is to do inverse of instantiation, e.g.

tmp1 = [Node(value=3),
            Node()]
tmp2 = [Node(value=5, children=tmp1),
            Node(color="green")]
tree = Tree(children=tmp2)

which is hard to comprehend what is going on there.


>  > In particular, we can
> > make this much more powerful in Python (as opposed to Dart) because
> Python
> > recognizes scope by indentation and therefore it would be possible to do
> > something like
> >
> > gnuplot.newPlot()
> >  ..set("xrange [0:5]")
> >  ..set("yrange [0:20]")
> >  ..newPlot()
> >      ..addSeries("Linear", [1,2,3])
> >      ..addSeries("Quadratic", [1,4,6])
> >  ..run()
>
> I had to read that multiple times before I was able to interpret what
> this is supposed to mean. It doesn't help that I'm not familiar enough
> with the gnuplot API to tell exactly what you're doing. I *think* that
> it would be the equivalent of this:
>
> p = gnuplot.newPlot()
> p.set("xrange [0:5]")
> p.set("yrange [0:20]")
> q = p.newPlot()
> q.addSeries("Linear", [1,2,3])
> q.addSeries("Quadratic", [1,4,6])
> p.run()
>
> Yes, this is correct


>  If I'm wrong, I think that suggests that your extension to the syntax
> isn't as clear as you hoped. If I'm right, I wonder what the point of
> the inner sub-block is, since you don't appear to do anything with the q
> plot. What have I missed?
>

I apologize for confusion. maybe newPlot() isn't the best name. In my head
the newPlot() function would
- add a new Plot to the Gnuplot object
- return this Plot object so you can work with it (e.g. add series,
customize, etc.)

When I reflect about this example, the p.set("xrange") is also a bit
misleading to people not familiar with gnuplot -- gnuplot has "set" command
and p.set("xrange [0:1]") was meant to imitate writing "set xrange[0:1]"
line in gnuplot




> For starters, you should explain precisely how the compiler will
> determine what is the "last object used" in practice. Your examples
> so far suggest it is based on the last line of source code, but
> that's tricky. For example:
>
> x = spam(); y = eggs()
>   ..method()
>
> I would *assume* that this implicitly calls y.method rather than
> x.method, but that's not a given. How about this?
>

I would assume the same


>
> y = spam()
> x = eggs()
> del y
>   ..method()
>
> Does that call x.method()? And what do this do?
>
>
I think the reasonable way to define it would be that the cascade operator
will act only if the last thing (on the previous line) was an expression.
In particular, all statements like "del y, for, while, if-else" followed by
a cascade should be a parse error with the exception of the assignment
which is a statement but we want to allow it. I am not sure about yield --
it can be a bit difficult to agree on the exact semantic there (e.g. should
I yield first, then continue with the cascade or should I execute the whole
cascade and yield as a final step?)


> myClass()
> for i in range(3):
>     ..method()
>
> Is it a syntax error? Or does it call i.method()? Or perhaps even call
> method on the range object? Or does the myClass object still count as
> the implicit "last object used"?
>

I think this should be a syntax error. (as it anyway defeats the purpose of
making things clear)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20131122/1f4de858/attachment-0001.html>


More information about the Python-ideas mailing list