Professional Web Applications Themes

Operators +, += and = in Ruby 2 - Ruby

Hi all, this occurred to me some days ago and I'd like to hear what others think. Operator += can't be user defined but instead is extended to a combination of "+" and assignment: "x += y" becomes implicitely "x = x + y". Now, wouldn't it be better to turn that around and have people define operator += and automatically convert operator + like in: "x + y" becomes implicitely "x.dup += y" The reason I'm offering this is performance: "x = x + y" is slower than an inplace manipulation (that += would do), which is often what's ...

  1. #1

    Default Operators +, += and = in Ruby 2


    Hi all,

    this occurred to me some days ago and I'd like to hear what others think.

    Operator += can't be user defined but instead is extended to a combination
    of "+" and assignment:
    "x += y" becomes implicitely "x = x + y".

    Now, wouldn't it be better to turn that around and have people define
    operator += and automatically convert operator + like in:

    "x + y" becomes implicitely "x.dup += y"

    The reason I'm offering this is performance: "x = x + y" is slower than an
    inplace manipulation (that += would do), which is often what's desired
    here.

    On the downside:

    - This will likely break a lot of code already defined unless one would
    allow to define "+" for a while (possibly with a warning).

    - The change has subtle effects, i.e., people relying on "x += y" to
    create a new instance and not changing the state of x might encounter
    surprising effects.

    - dup might or might not be the appropriate method to create a copy
    depending on the class at hand. When defining operator +, we are currently
    free in deciding what's the type of result of this operation. That
    freedom would definitely go away.

    What do others think? Did I overlook something?

    Thx!

    robert

    Robert Guest

  2. #2

    Default Re: Operators +, += and = in Ruby 2

    On Wed, 25 Feb 2004 16:12:16 +0100, Robert Klemme wrote:
    [snip] 

    It would be really nice to be able to overload '+=', so that #close can be
    invoked correct.

    server> ruby a.rb
    0
    1
    server> expand -t2 a.rb
    class A
    count = 0
    def initialize(value=nil)
    value = value || 0
    count += 1
    end
    attr_reader :value
    def close
    count -= 1
    end
    def A.count
    count
    end
    def +(value)
    A.new(value + value)
    end
    end

    p A.count
    a = A.new
    a += 5
    a.close
    p A.count
    server>

    --
    Simon Strandgaard
    Simon Guest

  3. #3

    Default Re: Operators +, += and = in Ruby 2


    "Simon Strandgaard" <dk> schrieb im Newsbeitrag
    news:dk... 
    >
    > It would be really nice to be able to overload '+=', so that #close can[/ref]
    be 

    Your problem is, that += silently discards an instance without invoking
    some kind of "destructor" and without the chance to detect this situation.
    Is that correctly yzed?

    You could indeed deal with that when overriding of + and += was swapped:
    in that case you'd only have to override #dup to increment the counter.
     

    Kind regards

    robert

    Robert Guest

  4. #4

    Default Re: Operators +, += and = in Ruby 2

    On Wed, 25 Feb 2004 16:12:16 +0100, Robert Klemme <net> wrote:
     

    Yes, I think so. With your proposed change it would be impossible to
    express operations where the result has a different type than the first
    operand, like, for example:

    Float = Vector * Vector # (dot product)
    or
    Vector = Matrix * Vector

    So in some cases it is not possible to correctly define a *= operator,
    while a * operator is still desirable.

    Of course, it would be possible to automatically define a missing +=
    using a defined +, and a missing + using a defined +=. Whether this would
    be a good idea is certainly debatable.

    --
    exoticorn/farbrausch
    Dennis Guest

  5. #5

    Default Re: Operators +, += and = in Ruby 2


    "Dennis Ranke" <de> schrieb im Newsbeitrag
    news:CIS.DFN.DE... 
    wrote: 
    >
    > Yes, I think so. With your proposed change it would be impossible to
    > express operations where the result has a different type than the first
    > operand, like, for example:
    >
    > Float = Vector * Vector # (dot product)
    > or
    > Vector = Matrix * Vector[/ref]

    I didn't overlook that one. It was in the first post already:

    <quote>
    On the downside:
    [...]
    - dup might or might not be the appropriate method to create a copy
    depending on the class at hand. When defining operator +, we are currently
    free in deciding what's the type of result of this operation. That
    freedom would definitely go away.
    </quote>

    A solution would be to provide another method (maybe #copy or #op_dup or
    similar) that defaults to #dup but can be overridden to get another return
    value.
     
    would 

    That would lead into the directon of C++ where you can overload all these
    operators independently. Dunno whether that is a good idea or not, but I
    always liked the idea that there was only one set of operators I needed to
    define and got the rest for free. We could maintain this by defining #+,
    #- etc. in Object using #+= etc. internally. So we would retain the
    automatism while not reducing freedom too much.

    Any other thoughts on this?

    Kind regards

    robert

    Robert Guest

  6. #6

    Default Re: Operators +, += and = in Ruby 2

    On Thu, 26 Feb 2004 12:24:13 +0100, Robert Klemme <net> wrote:
     

    Ok, but I can't really see this working. Let's take a Vector class, for
    example, that defines the following operations:

    Vector = Vector + Vector (adding two vectors)
    Float = Vector * Vector (calculating the dot product)
    Vector = Vector * Float (scaling a vector)

    Now the resulting type depends on both the actual Op used as well as the
    type of the second operand. While it would certainly be possible to call
    #op_dup with all of this information, it sounds quite ulgy to have one
    method that has to know about the inner workings of all the operators.

    Another problem (which is much harder to solve) is: What kind of object
    should receive the *= message in the case of the "Float = Vector * Vector"
    operation? A Vector that turns into a Float while processing the message?
    I can't say that I like the sound of objects changing their class in this
    way.
     

    I think the closest you could ever get to this would be the current ruby
    way (ie. defining #+= using #+) and optionally being able to define your
    own #+= as well.

    --
    exoticorn/farbrausch
    Dennis Guest

  7. #7

    Default Re: Operators +, += and = in Ruby 2


    "Dennis Ranke" <de> schrieb im Newsbeitrag
    news:CIS.DFN.DE... 
    wrote: [/ref]
    or 
    >
    > Ok, but I can't really see this working. Let's take a Vector class, for
    > example, that defines the following operations:
    >
    > Vector = Vector + Vector (adding two vectors)
    > Float = Vector * Vector (calculating the dot product)
    > Vector = Vector * Float (scaling a vector)
    >
    > Now the resulting type depends on both the actual Op used as well as the
    > type of the second operand. While it would certainly be possible to call
    > #op_dup with all of this information, it sounds quite ulgy to have one
    > method that has to know about the inner workings of all the operators.[/ref]

    Yep, true. I didn't think of multiple dispatch but you're right that this
    is ugly. One could solve that by defining #op_dup this way:

    def op_dup(op_sym, op_obj)
    dup
    end

    That would allow overriding implementations to decide which return value
    to create.
     
    Vector" 

    Clearly the result of #op_dup. First a copy is created and then the
    inplace operation is performed.
     
    this 

    No instance changes its class here.
     [/ref]
    these [/ref]
    but I [/ref]
    needed [/ref]
    #+, 
    >
    > I think the closest you could ever get to this would be the current ruby
    > way (ie. defining #+= using #+) and optionally being able to define your
    > own #+= as well.[/ref]

    .... or the other way round, i.e. defining #+ using #+= and optionally
    defining #+ as well.

    Thanks for the feedback!

    Regards

    robert

    Robert Guest

  8. #8

    Default Re: Operators +, += and = in Ruby 2

    On Thu, 26 Feb 2004 13:30:52 +0100, Robert Klemme <net> wrote:
     
    > Vector" 
    >
    > Clearly the result of #op_dup. First a copy is created and then the
    > inplace operation is performed.[/ref]

    Well, yes, but what kind of object should #op_dup return? It would have to
    be a Float, because that's the result of the operation, but upon receiving
    the first #*= message it would have to multiply two Vectors, while for
    later #*='s it would have to act like an ordinary Float.
    Possible, but not exactly what I would like to do.
     
    >
    > ... or the other way round, i.e. defining #+ using #+= and optionally
    > defining #+ as well.[/ref]

    True, of course.
    There is a disadvantage to both, though: It would be ugly to inhirit from
    such a class and trying to change the behaviour of #+ and #+=, as you can
    never be sure that it is enough to just overwrite one method, so you'll
    always need to overwrite both.

    --
    exoticorn/farbrausch
    Dennis Guest

  9. #9

    Default Re: Operators +, += and = in Ruby 2


    "Dennis Ranke" <de> schrieb im Newsbeitrag
    news:CIS.DFN.DE... 
    wrote: [/ref][/ref]
    object 
    > > Vector" 
    > >
    > > Clearly the result of #op_dup. First a copy is created and then the
    > > inplace operation is performed.[/ref]
    >
    > Well, yes, but what kind of object should #op_dup return? It would have[/ref]
    to 
    receiving 

    Especially since a Float typically does not have a method for multiplying
    it with a Vector. Does #coerce help here?
     [/ref][/ref]
    ruby [/ref][/ref]
    your 
    > >
    > > ... or the other way round, i.e. defining #+ using #+= and optionally
    > > defining #+ as well.[/ref]
    >
    > True, of course.
    > There is a disadvantage to both, though: It would be ugly to inhirit[/ref]
    from 
    can 

    Yeah, exactly. I think, that's why I like the approach it is today.

    Still not really satisfying. I see the disadvantages of both sides
    clearer now, but I don't see a better solution right now. :-(

    Maybe we'll see multiple dispatch in Ruby 3 and then these things get
    easier. :-)

    Again, thanks for sorting that out!

    Regards

    robert

    Robert Guest

Similar Threads

  1. Operators
    By sai1 in forum Macromedia Dynamic HTML
    Replies: 2
    Last Post: January 2nd, 08:00 PM
  2. Oddity with the x and . operators
    By Dan in forum PERL Miscellaneous
    Replies: 8
    Last Post: October 23rd, 09:01 AM
  3. What are the !== and === operators for?
    By vbAlex in forum PHP Development
    Replies: 4
    Last Post: September 12th, 10:02 AM
  4. [ANN] ruby-freedb, ruby-serialport, ruby-mp3info moved to Rubyforge
    By guillaume.pierronnet@ratp.fr in forum Ruby
    Replies: 0
    Last Post: August 31st, 11:57 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139