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

Perešíni Peter ppershing at gmail.com
Thu Nov 21 11:55:46 CET 2013


Recently I fell in love with Dart method cascading operator .. to the
degree that I find it really convenient and I am missing it in the Python.
The cascade operator

myObj
  ..setX(5)
  ..y=6

is the syntactic sugar equivalent of the following:

tmp = myObj
tmp.setX(5)
tmp.y=6

This can be used to greatly simplify instantiating objects and can also
enable creating domain specific languages in Python. 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()

or

template = HtmlTemplate()
 ..head()
   ..script(src="xyz")
 ..body()
   ..div(class="main")
     ..paragraph("I am the first paragraph")
     ..paragraph("I am the second paragraph")

Note that this is strictly better than method chaining, e.g.

template = MyObject().setX(1).setY(2)

because
a) method chaining is hard to write on multiple lines, the only two options
are

template = MyObject() \
    .setX(1) \
    .setY(2)

which is fragile (explicit line continuation is discouraged in Python) or

(template = MyObject()
    .setX(1)
    .setY(2))

which looks weird.

b) method chaining cannot take advantage of multiple scoping, e.g. the only
way to write Gnuplot example is

(Gnuplot()
  .set("...")
  .newPlot()
    .addSeries()
    .addSeries()
    *.endPlot()*
  .run()
)

with added method *endPlot()* to the Plot class. Moreover, Plot class now
needs a direct reference to its parent (e.g. Gnuplot) so it can return its
reference.
This adds unnecessary cyclic dependencies.

c) method chaining needs specialized API, e.g. each method needs to return
self

d) method chaining cannot be used with attributes, e.g. there is no
equivalent to

obj = MyObject()
  ..x=1
  ..y=2


Note that this proposal is different from "in" statement [
https://mail.python.org/pipermail/python-ideas/2012-November/017736.html]
in the sense that this proposal does not bring anything new into the scope,
e.g.

obj1
  ..obj2
     ..x = y

translates to

tmp1 = obj1
tmp2 = obj2
tmp2.x = y

or (simplified)

obj1.obj2.x = y

no matter if obj2 or obj1 contains variable y.

In my opinion, such cascading operator would greatly help creating domain
specific languages APIs in Python which are

1) easily readable. It is better than being lost in a repetitive stream of
lines looking like obj.x(), obj.y(), obj.z(). Note that repetitive stream
of lines (apart from being too verbose) also introduces a possibility of
mistyping the name of the object

2) easy to implement (no special API considerations as returning self from
each function call)

What do you think?
  Peter
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20131121/e7cc6d01/attachment-0001.html>


More information about the Python-ideas mailing list