views:

207

answers:

6

Lots of programming languages already have the compound statements +=, -=, /=, etc. A relatively new style of programming is to "chain" method calls onto each other, e.g. in Linq, JQuery and Django's ORM.

I sometimes, more often than I'd like, find the need to do this in Django:

# Get all items whose description beginning with A
items = Items.objects.filter(desc__startswith='A')
if something:
    # Filter further to items whose description also ends with Z
    items = items.filter(desc__endswith='Z')

I think it would be easier and actually more readable if there was a compound method call statement such as .= which could work like this:

items = Items.objects.filter(desc__startswith='A')
if something:
    items .= filter(desc__endswith='Z')
  • Are there any programming languages that support this or something like it?
  • If the answer is no, why not?
  • Is this style of programming really that new?
  • Are there any PEPs (Python Enhancement Proposals) that support this idea?
A: 

Scala's collections support in-place operations, provided that the variable is a var.

scala> var L = List("b", "c")
L: List[java.lang.String] = List(b, c)

scala> L ::= "a"

scala> L
res8: List[java.lang.String] = List(a, b, c)

(For those unfamiliar with Scala, :: is a method of List)

This is a style of programming that many avoid, and in Scala you can avoid such in-place mutation by using immutable vals:

scala> val L = List("b", "c")
L: List[java.lang.String] = List(b, c)

scala> L ::= "a"
<console>:7: error: reassignment to val
       L ::= "a"
Ben James
His question is specifically about in-place call operator.
missingfaktor
He asked, "Are there any programming languages that support this *or something like it*?". Although it's not an operator (it's sugar for the compiler) and it only applies to methods that don't contain alphanumeric characters, I'd say it's enough like it to warrant mentioning.
Ben James
Fair enough. ` ` ` `
missingfaktor
+1  A: 

IMHO, i don't like it.

just imagine this,

items .= click(function(){...});

it's not a syntax error anymore, but it doesn't make sense, does it?

I can say it does not make sense simply because if you expand my example, it would be like this,

items = items.click(function(){...});

items.click(function(){...}); would just return the object items , and you will assign it to items?

in this example,

items .= filter(desc__endswith='Z');

it would make sense, but not true to all objects, maybe that's the reason it was not implemented.

as to parent .= children();, what happens to parent later on the codes?

I'm talking jQuery way.

Reigel
Hmm, makes sense to me. Maybe you could explain why it doesn't make sense?
Deniz Dogan
Explain first why that line would make sense to you?
Reigel
It makes sense to me because to me that would be the equivalent of `items = items.click(function () {...});` which is valid JQuery, isn't it?
Deniz Dogan
@Deniz - yes, but what does it do? it's just like saying `items = items`.
Reigel
After having seen your edit, it still makes sense to me. Imagine that depending on the values of two variables `bindOver` and `bindOut`, you want to bind the mouseover and/or the mouseout event to some set of items. So basically you do `items = $.getItems()` and then if `bindOver` you do `items .= mouseover(function...)` and then if `bindOut` you do `items .= mouseout(function...)`.
Deniz Dogan
with that, it's just like saying `items = items` because the `events function` (mouseover, mouseout, etc) would return the object that calls it.
Reigel
Yes, that's the idea. I don't see any problem with it.
Deniz Dogan
@Reigel - Have to agree with Deniz on this one. If you're allowed to write `items = items.click(function (){...});`, however silly, then there is nothing wrong with `items .= click(function (){...});` (even if it is pointless)!
James Wiseman
It only makes sense for methods that return a *modified copy* of themselves. Using it on *mutating* methods that simply return themselves misses the point.
Glenn Maynard
@James - I'll agree with `(even if it is pointless)!`. @all it's just my humble opinion.
Reigel
@Glenn -Exactly my point.
Reigel
@Reigel: You have to think about the times where it isn't pointless. E.g. consider I would do `items .= children()` in one case and `items .= find('.foo')` in another case.
Deniz Dogan
@Glen - but you can still do it anyway. People can still write `x=x+!¬"!"£!;;as92734` and it will be invalid,garbage and erroneous. This still isn't an argument for preventing `x+=!¬"!"£!;;as92734`
James Wiseman
@Deniz - `items .= children();` is still not good. what if it's `parent .= children();`, with that, the parent is overwritten by the children. what if you use `parent` later. well, to you it's not a problem, cause you know its already overwritten somewhere. But then, what about those who will debug your code? do they have clues on that?
Reigel
@Reigel: That's odd--I was disagreeing with you. The syntax still makes *sense* when used on mutating methods (if they return themselves, which isn't a common Python convention)--it's just pointless.
Glenn Maynard
@Reigel - Yeah, I spotted the IMHO. Still voted this up, however :-)
James Wiseman
@Glenn hahaha but still I agree with what you've said.
Reigel
@Reigel - `items = items.children();` is still not good. what if it's `parent = parent.children();`, with that, the parent is overwritten by the children. what if you use `parent` later. well, to you it's not a problem, cause you know its already overwritten somewhere. But then, what about those who will debug your code? do they have clues on that?
Glenn Maynard
@Reigel: I guess we'll just have to agree to disagree. In my opinion, this is not a confusing syntax addition in JQuery nor in Python. If it confuses some programmer, that programmer should simply be taught how it works. Some people like to write extremely long one-liners in JQuery, which can be confusing to some people, but that's still not a reason to disallow it.
Deniz Dogan
@Deniz - yeah ;) But I still don't like it. My opinion.
Reigel
@Reigel: Sure, no problem. :)
Deniz Dogan
Given that '.' is also a decimal point, I wonder what the following would give us if the above convention is allowed: `alert(1.===1);​​​` :-)
James Wiseman
@All - haha this answer of mine made it to top 2 on `Most commented` on `Moderator's tools` XD
Reigel
@James - I could imagine more. But I don't want to :D
Reigel
Slightly offtopic, but this will never be a syntax addition to jQuery as jQuery is not a language but a framework for JavaScript ;-) As for if it makes sense, to me personally I agree with Reigel on this.
CharlesLeaf
@James: I'd imagine that it would be correctly parsed as `1. === 1`. It's not that strange.
Deniz Dogan
+1  A: 

I can't answer those questions, and I'm not sure what I think of this because I havn't seen it before, but it does have an interesting applicatioon: all of the inplace operators become obsolete.

a = 1
a .= __add__(1)
a .= __mul__(2)

Of course, it's clearer to write a += 1, but if this syntax had come earlier in the design of the language, and the __add__ methods were less ugly (eg. just add), the language today might have eleven fewer operators today.

(Of course, there would be other implications of that--in particular, the automatic fallback from __iadd__ to __add__ would be lost. Still, it's an interesting concept.)

Glenn Maynard
(This site is, from time to time, simply dumb. Why is is making me enter a captcha? Have I not used the site enough to prove that I'm a real user?)
Glenn Maynard
+2  A: 

This is supported in Perl 6.

mkarasek
yet another reason to not mess with pearl. I _swear_ I don't go looking for them. They just fall in my lap.
aaronasterling
@AaronMcSmooth: +1, but it's spelled Perl.
JUST MY correct OPINION
oi that's embarrassing. one of those typos like when I type 'f' instead of 5. Just wishing I could edit...
aaronasterling
A: 

I have thought about this often when doing Java or C# programming, where you find yourself repeating not just one but often the same two or more object references on both sides of the assignment -- e.g., you have a member of some object that is a string, and you want to call some methods on that string and assign it back to the member variable. Oddly enough, it hasn't bothered me nearly as much in Python.

The .= operator you propose is one idea I thought of at the time I was doing C#. Another option would be to allow a leading dot to as a shorthand for the object being assigned to, like this:

foo.bar.str = .lower()  # same as foo.bar.str = foo.bar.str.lower()

Pascal, Modula-2, and Visual Basic have a with statement (different from Python's statement of the same name) that would allow you to write something like this if it existed in Python (I call it "using" here so it is not mistaken for valid Python):

using foo.bar:
    str = str.lower()  # same as foo.bar.str = foo.bar.str.lower()

This is very convenient when you are going to be doing a lot of manipulation of members of a single object since it allows a block. However, you still have a level of redundancy here, which could be eliminated if you combined the last two ideas like so:

using foo.bar:
    str = .lower()

This seems to me like it would be a nice bit of syntactic sugar, and I find it very readable, but it does not seem like it is high on the priority list of most language designers. However, since Python does have Modula-2 influences, perhaps it's not out of the question that it would eventually be added.

kindall
A: 

Ruby has this feature in a way, but implements it differently. This is through 'destructive' methods, which alter the variable they are called on. For example, calling str.split just returns the object split, it doesn't alter it. But, if you call str.split! it changes it in place. Most builtin array and string methods have a destructive and non-destructive version.

bennybdbc