ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:103113] [Ruby master Feature#16295] Chainable aliases for String#-@ and String#+@
       [not found] <redmine.issue-16295.20191105134410.7941@ruby-lang.org>
@ 2021-03-30 21:12 ` dan
  2021-03-30 21:31 ` [ruby-core:103114] " dan
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: dan @ 2021-03-30 21:12 UTC (permalink / raw)
  To: ruby-core

Issue #16295 has been updated by danh337 (Dan Higgins).


The `-@` and `+@` calls do work fine for chaining. But `.-@` has a nice equivalent, `.freeze`. Is it possible to give `.+@` a nice equivalent, like `.thaw`? This feels more Rubyistic.

Are newer Ruby MRIs going to have core methods return frozen strings more often? If so, then chaining these freeze and "thaw" methods will be more common.

This already has made some of my production code ugly, when using `tap`. I have to say:
`(+some_object.send(a_method)).tap { |value| value << "blah" }`
or
`some_object.send(a_method).+@.tap { |value| value << "blah" }`

Neither of these looks like good Ruby. I'd rather say `some_object.send(a_method).thaw.tap { |value| value << "blah" }`.

----------------------------------------
Feature #16295: Chainable aliases for String#-@ and String#+@
https://bugs.ruby-lang.org/issues/16295#change-91179

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Original discussion https://bugs.ruby-lang.org/issues/16150?next_issue_id=16147&prev_issue_id=16153#note-40

In #16150, @headius raised the following concern about `String#-@` and `String#+@`:

headius (Charles Nutter) wrote:
> > Not exactly, -@ and +@ makes this much simpler
> 
> I do like the unary operators, but they also have some precedence oddities:
> 
> ```
> >> -"foo".size
> => -3
> >> (-"foo").size
> => 3
> ```
> 
> And it doesn't work at all if you're chaining method calls:
> 
> ```
> >> +ary.to_s.frozen?
> NoMethodError: undefined method `+@' for false:FalseClass
> 	from (irb):8
> 	from /usr/bin/irb:11:in `<main>'
> ```
> 
> But you are right, instead of the explicit `dup` with possible freeze you could use `-` or `+` on the result of `to_s`. However it's still not safe to modify it since it would modify the original string too.

After working for quite a while with those, I have to say I agree. They very often force to use parentheses, which is annoying, and an indication that regular methods would be preferable to unary operators.


In response @matz proposed to alias them as `String#+` and `String#-` without arguments:

>  How about making String#+ and #- without argument behave like #+@ and #-@ respectively, so that we can write:
>  
>  ```
>  "foo".-.size
>  ary.to_s.+.frozen?
>  ```


My personal opinion is that descriptive method names would be preferable to `+/-`:

> IMHO `.-` and `.+` is not very elegant. Proper method names explaining the intent would be preferable.
> 
>   - `-@` could be `dedup`, or `deduplicate`.
>   - `+@` could be `mutable` or `mut`.





-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [ruby-core:103114] [Ruby master Feature#16295] Chainable aliases for String#-@ and String#+@
       [not found] <redmine.issue-16295.20191105134410.7941@ruby-lang.org>
  2021-03-30 21:12 ` [ruby-core:103113] [Ruby master Feature#16295] Chainable aliases for String#-@ and String#+@ dan
@ 2021-03-30 21:31 ` dan
  2021-03-30 21:52 ` [ruby-core:103115] " merch-redmine
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: dan @ 2021-03-30 21:31 UTC (permalink / raw)
  To: ruby-core

Issue #16295 has been updated by danh337 (Dan Higgins).


I believe this shows the semantics. It's the inverse of `.freeze`:

`class String; def thaw; frozen? ? self.+@ : self; end; end`

----------------------------------------
Feature #16295: Chainable aliases for String#-@ and String#+@
https://bugs.ruby-lang.org/issues/16295#change-91180

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Original discussion https://bugs.ruby-lang.org/issues/16150?next_issue_id=16147&prev_issue_id=16153#note-40

In #16150, @headius raised the following concern about `String#-@` and `String#+@`:

headius (Charles Nutter) wrote:
> > Not exactly, -@ and +@ makes this much simpler
> 
> I do like the unary operators, but they also have some precedence oddities:
> 
> ```
> >> -"foo".size
> => -3
> >> (-"foo").size
> => 3
> ```
> 
> And it doesn't work at all if you're chaining method calls:
> 
> ```
> >> +ary.to_s.frozen?
> NoMethodError: undefined method `+@' for false:FalseClass
> 	from (irb):8
> 	from /usr/bin/irb:11:in `<main>'
> ```
> 
> But you are right, instead of the explicit `dup` with possible freeze you could use `-` or `+` on the result of `to_s`. However it's still not safe to modify it since it would modify the original string too.

After working for quite a while with those, I have to say I agree. They very often force to use parentheses, which is annoying, and an indication that regular methods would be preferable to unary operators.


In response @matz proposed to alias them as `String#+` and `String#-` without arguments:

>  How about making String#+ and #- without argument behave like #+@ and #-@ respectively, so that we can write:
>  
>  ```
>  "foo".-.size
>  ary.to_s.+.frozen?
>  ```


My personal opinion is that descriptive method names would be preferable to `+/-`:

> IMHO `.-` and `.+` is not very elegant. Proper method names explaining the intent would be preferable.
> 
>   - `-@` could be `dedup`, or `deduplicate`.
>   - `+@` could be `mutable` or `mut`.





-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [ruby-core:103115] [Ruby master Feature#16295] Chainable aliases for String#-@ and String#+@
       [not found] <redmine.issue-16295.20191105134410.7941@ruby-lang.org>
  2021-03-30 21:12 ` [ruby-core:103113] [Ruby master Feature#16295] Chainable aliases for String#-@ and String#+@ dan
  2021-03-30 21:31 ` [ruby-core:103114] " dan
@ 2021-03-30 21:52 ` merch-redmine
  2021-03-30 23:11 ` [ruby-core:103116] " eregontp
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: merch-redmine @ 2021-03-30 21:52 UTC (permalink / raw)
  To: ruby-core

Issue #16295 has been updated by jeremyevans0 (Jeremy Evans).


danh337 (Dan Higgins) wrote in #note-14:
> I believe this shows the semantics. It's the inverse of `.freeze`:
> 
> `class String; def thaw; frozen? ? self.+@ : self; end; end`

It's not the inverse of freeze, since that is not possible in Ruby.  freeze always returns the receiver.  thaw could not, because you cannot unfreeze an object.

----------------------------------------
Feature #16295: Chainable aliases for String#-@ and String#+@
https://bugs.ruby-lang.org/issues/16295#change-91181

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Original discussion https://bugs.ruby-lang.org/issues/16150?next_issue_id=16147&prev_issue_id=16153#note-40

In #16150, @headius raised the following concern about `String#-@` and `String#+@`:

headius (Charles Nutter) wrote:
> > Not exactly, -@ and +@ makes this much simpler
> 
> I do like the unary operators, but they also have some precedence oddities:
> 
> ```
> >> -"foo".size
> => -3
> >> (-"foo").size
> => 3
> ```
> 
> And it doesn't work at all if you're chaining method calls:
> 
> ```
> >> +ary.to_s.frozen?
> NoMethodError: undefined method `+@' for false:FalseClass
> 	from (irb):8
> 	from /usr/bin/irb:11:in `<main>'
> ```
> 
> But you are right, instead of the explicit `dup` with possible freeze you could use `-` or `+` on the result of `to_s`. However it's still not safe to modify it since it would modify the original string too.

After working for quite a while with those, I have to say I agree. They very often force to use parentheses, which is annoying, and an indication that regular methods would be preferable to unary operators.


In response @matz proposed to alias them as `String#+` and `String#-` without arguments:

>  How about making String#+ and #- without argument behave like #+@ and #-@ respectively, so that we can write:
>  
>  ```
>  "foo".-.size
>  ary.to_s.+.frozen?
>  ```


My personal opinion is that descriptive method names would be preferable to `+/-`:

> IMHO `.-` and `.+` is not very elegant. Proper method names explaining the intent would be preferable.
> 
>   - `-@` could be `dedup`, or `deduplicate`.
>   - `+@` could be `mutable` or `mut`.





-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [ruby-core:103116] [Ruby master Feature#16295] Chainable aliases for String#-@ and String#+@
       [not found] <redmine.issue-16295.20191105134410.7941@ruby-lang.org>
                   ` (2 preceding siblings ...)
  2021-03-30 21:52 ` [ruby-core:103115] " merch-redmine
@ 2021-03-30 23:11 ` eregontp
  2022-02-18 22:41 ` [ruby-core:107661] " danh337 (Dan H)
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: eregontp @ 2021-03-30 23:11 UTC (permalink / raw)
  To: ruby-core

Issue #16295 has been updated by Eregon (Benoit Daloze).


`+@` is rarely safe to use (only if you know what allocated it and that it was never captured in another variable) as it might mutate an argument inplace, if that object is not frozen.
In most cases, people actually want to use `.dup` and that already exists.

@danh337 `-@` is not the same as `freeze`, see discussion above.

----------------------------------------
Feature #16295: Chainable aliases for String#-@ and String#+@
https://bugs.ruby-lang.org/issues/16295#change-91182

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Original discussion https://bugs.ruby-lang.org/issues/16150?next_issue_id=16147&prev_issue_id=16153#note-40

In #16150, @headius raised the following concern about `String#-@` and `String#+@`:

headius (Charles Nutter) wrote:
> > Not exactly, -@ and +@ makes this much simpler
> 
> I do like the unary operators, but they also have some precedence oddities:
> 
> ```
> >> -"foo".size
> => -3
> >> (-"foo").size
> => 3
> ```
> 
> And it doesn't work at all if you're chaining method calls:
> 
> ```
> >> +ary.to_s.frozen?
> NoMethodError: undefined method `+@' for false:FalseClass
> 	from (irb):8
> 	from /usr/bin/irb:11:in `<main>'
> ```
> 
> But you are right, instead of the explicit `dup` with possible freeze you could use `-` or `+` on the result of `to_s`. However it's still not safe to modify it since it would modify the original string too.

After working for quite a while with those, I have to say I agree. They very often force to use parentheses, which is annoying, and an indication that regular methods would be preferable to unary operators.


In response @matz proposed to alias them as `String#+` and `String#-` without arguments:

>  How about making String#+ and #- without argument behave like #+@ and #-@ respectively, so that we can write:
>  
>  ```
>  "foo".-.size
>  ary.to_s.+.frozen?
>  ```


My personal opinion is that descriptive method names would be preferable to `+/-`:

> IMHO `.-` and `.+` is not very elegant. Proper method names explaining the intent would be preferable.
> 
>   - `-@` could be `dedup`, or `deduplicate`.
>   - `+@` could be `mutable` or `mut`.





-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [ruby-core:107661] [Ruby master Feature#16295] Chainable aliases for String#-@ and String#+@
       [not found] <redmine.issue-16295.20191105134410.7941@ruby-lang.org>
                   ` (3 preceding siblings ...)
  2021-03-30 23:11 ` [ruby-core:103116] " eregontp
@ 2022-02-18 22:41 ` danh337 (Dan H)
  2022-02-18 22:48 ` [ruby-core:107662] " danh337 (Dan H)
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: danh337 (Dan H) @ 2022-02-18 22:41 UTC (permalink / raw)
  To: ruby-core

Issue #16295 has been updated by danh337 (Dan H).


Eregon (Benoit Daloze) wrote in #note-16:
> `+@` is rarely safe to use (only if you know what allocated it and that it was never captured in another variable) as it might mutate an argument inplace, if that object is not frozen.
> In most cases, people actually want to use `.dup` and that already exists.
> 
> @danh337 `-@` is not the same as `freeze`, see discussion above.

`.dup` is not quite as good, as it always allocates a copy. The `.thaw` semantics would be to allocate a new copy only if the receiver is already frozen.

I realize that "unfreeze" does not exist, but I'm making the assumption (yes dangerous) that `+@` and `-@` on existing Strings do their best to avoid allocating new objects, and currently there is no method equivalent to do that for `+@`.

----------------------------------------
Feature #16295: Chainable aliases for String#-@ and String#+@
https://bugs.ruby-lang.org/issues/16295#change-96575

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Original discussion https://bugs.ruby-lang.org/issues/16150?next_issue_id=16147&prev_issue_id=16153#note-40

In #16150, @headius raised the following concern about `String#-@` and `String#+@`:

headius (Charles Nutter) wrote:
> > Not exactly, -@ and +@ makes this much simpler
> 
> I do like the unary operators, but they also have some precedence oddities:
> 
> ```
> >> -"foo".size
> => -3
> >> (-"foo").size
> => 3
> ```
> 
> And it doesn't work at all if you're chaining method calls:
> 
> ```
> >> +ary.to_s.frozen?
> NoMethodError: undefined method `+@' for false:FalseClass
> 	from (irb):8
> 	from /usr/bin/irb:11:in `<main>'
> ```
> 
> But you are right, instead of the explicit `dup` with possible freeze you could use `-` or `+` on the result of `to_s`. However it's still not safe to modify it since it would modify the original string too.

After working for quite a while with those, I have to say I agree. They very often force to use parentheses, which is annoying, and an indication that regular methods would be preferable to unary operators.


In response @matz proposed to alias them as `String#+` and `String#-` without arguments:

>  How about making String#+ and #- without argument behave like #+@ and #-@ respectively, so that we can write:
>  
>  ```
>  "foo".-.size
>  ary.to_s.+.frozen?
>  ```


My personal opinion is that descriptive method names would be preferable to `+/-`:

> IMHO `.-` and `.+` is not very elegant. Proper method names explaining the intent would be preferable.
> 
>   - `-@` could be `dedup`, or `deduplicate`.
>   - `+@` could be `mutable` or `mut`.





-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [ruby-core:107662] [Ruby master Feature#16295] Chainable aliases for String#-@ and String#+@
       [not found] <redmine.issue-16295.20191105134410.7941@ruby-lang.org>
                   ` (4 preceding siblings ...)
  2022-02-18 22:41 ` [ruby-core:107661] " danh337 (Dan H)
@ 2022-02-18 22:48 ` danh337 (Dan H)
  2022-02-19 20:34 ` [ruby-core:107667] " Eregon (Benoit Daloze)
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: danh337 (Dan H) @ 2022-02-18 22:48 UTC (permalink / raw)
  To: ruby-core

Issue #16295 has been updated by danh337 (Dan H).


@Eregon how is `-@` different from `.freeze` ? The meaning of these seems very much the same.

----------------------------------------
Feature #16295: Chainable aliases for String#-@ and String#+@
https://bugs.ruby-lang.org/issues/16295#change-96576

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Original discussion https://bugs.ruby-lang.org/issues/16150?next_issue_id=16147&prev_issue_id=16153#note-40

In #16150, @headius raised the following concern about `String#-@` and `String#+@`:

headius (Charles Nutter) wrote:
> > Not exactly, -@ and +@ makes this much simpler
> 
> I do like the unary operators, but they also have some precedence oddities:
> 
> ```
> >> -"foo".size
> => -3
> >> (-"foo").size
> => 3
> ```
> 
> And it doesn't work at all if you're chaining method calls:
> 
> ```
> >> +ary.to_s.frozen?
> NoMethodError: undefined method `+@' for false:FalseClass
> 	from (irb):8
> 	from /usr/bin/irb:11:in `<main>'
> ```
> 
> But you are right, instead of the explicit `dup` with possible freeze you could use `-` or `+` on the result of `to_s`. However it's still not safe to modify it since it would modify the original string too.

After working for quite a while with those, I have to say I agree. They very often force to use parentheses, which is annoying, and an indication that regular methods would be preferable to unary operators.


In response @matz proposed to alias them as `String#+` and `String#-` without arguments:

>  How about making String#+ and #- without argument behave like #+@ and #-@ respectively, so that we can write:
>  
>  ```
>  "foo".-.size
>  ary.to_s.+.frozen?
>  ```


My personal opinion is that descriptive method names would be preferable to `+/-`:

> IMHO `.-` and `.+` is not very elegant. Proper method names explaining the intent would be preferable.
> 
>   - `-@` could be `dedup`, or `deduplicate`.
>   - `+@` could be `mutable` or `mut`.





-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [ruby-core:107667] [Ruby master Feature#16295] Chainable aliases for String#-@ and String#+@
       [not found] <redmine.issue-16295.20191105134410.7941@ruby-lang.org>
                   ` (5 preceding siblings ...)
  2022-02-18 22:48 ` [ruby-core:107662] " danh337 (Dan H)
@ 2022-02-19 20:34 ` Eregon (Benoit Daloze)
  2022-02-19 20:39 ` [ruby-core:107668] " Eregon (Benoit Daloze)
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: Eregon (Benoit Daloze) @ 2022-02-19 20:34 UTC (permalink / raw)
  To: ruby-core

Issue #16295 has been updated by Eregon (Benoit Daloze).


> .dup is not quite as good, as it always allocates a copy.

It creates a new String instance, which is what one needs to guarantee safe mutation without affecting other parts of the program.
Hence, `+@` should rarely be used (only if we know where all the strings passed to this method come from and it's OK to mutate them).
`.dup` does not copy the actual bytes until mutated, because Strings are copy-on-write.

> how is -@ different from .freeze ? The meaning of these seems very much the same.

`-@` interns and might return a different String instance, `.freeze` does not intern and always returns the receiver.

----------------------------------------
Feature #16295: Chainable aliases for String#-@ and String#+@
https://bugs.ruby-lang.org/issues/16295#change-96586

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Original discussion https://bugs.ruby-lang.org/issues/16150?next_issue_id=16147&prev_issue_id=16153#note-40

In #16150, @headius raised the following concern about `String#-@` and `String#+@`:

headius (Charles Nutter) wrote:
> > Not exactly, -@ and +@ makes this much simpler
> 
> I do like the unary operators, but they also have some precedence oddities:
> 
> ```
> >> -"foo".size
> => -3
> >> (-"foo").size
> => 3
> ```
> 
> And it doesn't work at all if you're chaining method calls:
> 
> ```
> >> +ary.to_s.frozen?
> NoMethodError: undefined method `+@' for false:FalseClass
> 	from (irb):8
> 	from /usr/bin/irb:11:in `<main>'
> ```
> 
> But you are right, instead of the explicit `dup` with possible freeze you could use `-` or `+` on the result of `to_s`. However it's still not safe to modify it since it would modify the original string too.

After working for quite a while with those, I have to say I agree. They very often force to use parentheses, which is annoying, and an indication that regular methods would be preferable to unary operators.


In response @matz proposed to alias them as `String#+` and `String#-` without arguments:

>  How about making String#+ and #- without argument behave like #+@ and #-@ respectively, so that we can write:
>  
>  ```
>  "foo".-.size
>  ary.to_s.+.frozen?
>  ```


My personal opinion is that descriptive method names would be preferable to `+/-`:

> IMHO `.-` and `.+` is not very elegant. Proper method names explaining the intent would be preferable.
> 
>   - `-@` could be `dedup`, or `deduplicate`.
>   - `+@` could be `mutable` or `mut`.





-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [ruby-core:107668] [Ruby master Feature#16295] Chainable aliases for String#-@ and String#+@
       [not found] <redmine.issue-16295.20191105134410.7941@ruby-lang.org>
                   ` (6 preceding siblings ...)
  2022-02-19 20:34 ` [ruby-core:107667] " Eregon (Benoit Daloze)
@ 2022-02-19 20:39 ` Eregon (Benoit Daloze)
  2022-02-19 23:44 ` [ruby-core:107669] " zverok (Victor Shepelev)
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: Eregon (Benoit Daloze) @ 2022-02-19 20:39 UTC (permalink / raw)
  To: ruby-core

Issue #16295 has been updated by Eregon (Benoit Daloze).


To make progress on this issue I'd suggest to simplify it to only add `dedup` as an alias for `-@`.
That seems agreed by several people.

`+@` seems very rarely useful, and `dup` is in most cases better/safer (e.g., `s = "".dup; s << ...` or `def foo(s); s.dup << ...; end`).

----------------------------------------
Feature #16295: Chainable aliases for String#-@ and String#+@
https://bugs.ruby-lang.org/issues/16295#change-96587

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Original discussion https://bugs.ruby-lang.org/issues/16150?next_issue_id=16147&prev_issue_id=16153#note-40

In #16150, @headius raised the following concern about `String#-@` and `String#+@`:

headius (Charles Nutter) wrote:
> > Not exactly, -@ and +@ makes this much simpler
> 
> I do like the unary operators, but they also have some precedence oddities:
> 
> ```
> >> -"foo".size
> => -3
> >> (-"foo").size
> => 3
> ```
> 
> And it doesn't work at all if you're chaining method calls:
> 
> ```
> >> +ary.to_s.frozen?
> NoMethodError: undefined method `+@' for false:FalseClass
> 	from (irb):8
> 	from /usr/bin/irb:11:in `<main>'
> ```
> 
> But you are right, instead of the explicit `dup` with possible freeze you could use `-` or `+` on the result of `to_s`. However it's still not safe to modify it since it would modify the original string too.

After working for quite a while with those, I have to say I agree. They very often force to use parentheses, which is annoying, and an indication that regular methods would be preferable to unary operators.


In response @matz proposed to alias them as `String#+` and `String#-` without arguments:

>  How about making String#+ and #- without argument behave like #+@ and #-@ respectively, so that we can write:
>  
>  ```
>  "foo".-.size
>  ary.to_s.+.frozen?
>  ```


My personal opinion is that descriptive method names would be preferable to `+/-`:

> IMHO `.-` and `.+` is not very elegant. Proper method names explaining the intent would be preferable.
> 
>   - `-@` could be `dedup`, or `deduplicate`.
>   - `+@` could be `mutable` or `mut`.





-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [ruby-core:107669] [Ruby master Feature#16295] Chainable aliases for String#-@ and String#+@
       [not found] <redmine.issue-16295.20191105134410.7941@ruby-lang.org>
                   ` (7 preceding siblings ...)
  2022-02-19 20:39 ` [ruby-core:107668] " Eregon (Benoit Daloze)
@ 2022-02-19 23:44 ` zverok (Victor Shepelev)
  2022-02-20  1:49 ` [ruby-core:107670] " phluid61 (Matthew Kerwin)
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: zverok (Victor Shepelev) @ 2022-02-19 23:44 UTC (permalink / raw)
  To: ruby-core

Issue #16295 has been updated by zverok (Victor Shepelev).


> `+@` seems very rarely useful

No opinion on the rest of the ticket, but I thought `buffer = +""` is a quite widespread idiom to start with mutable buffer? It is a bit cryptic, but easy to get used to, and shorter than `String.new`. The way to get used to it is to consider it just "mutable string literal", as it looks like a literal!

While `buffer = ''.dup` is arguably *more* cryptic: like, "why one would *duplicate* empty string they've just created?!"

----------------------------------------
Feature #16295: Chainable aliases for String#-@ and String#+@
https://bugs.ruby-lang.org/issues/16295#change-96588

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Original discussion https://bugs.ruby-lang.org/issues/16150?next_issue_id=16147&prev_issue_id=16153#note-40

In #16150, @headius raised the following concern about `String#-@` and `String#+@`:

headius (Charles Nutter) wrote:
> > Not exactly, -@ and +@ makes this much simpler
> 
> I do like the unary operators, but they also have some precedence oddities:
> 
> ```
> >> -"foo".size
> => -3
> >> (-"foo").size
> => 3
> ```
> 
> And it doesn't work at all if you're chaining method calls:
> 
> ```
> >> +ary.to_s.frozen?
> NoMethodError: undefined method `+@' for false:FalseClass
> 	from (irb):8
> 	from /usr/bin/irb:11:in `<main>'
> ```
> 
> But you are right, instead of the explicit `dup` with possible freeze you could use `-` or `+` on the result of `to_s`. However it's still not safe to modify it since it would modify the original string too.

After working for quite a while with those, I have to say I agree. They very often force to use parentheses, which is annoying, and an indication that regular methods would be preferable to unary operators.


In response @matz proposed to alias them as `String#+` and `String#-` without arguments:

>  How about making String#+ and #- without argument behave like #+@ and #-@ respectively, so that we can write:
>  
>  ```
>  "foo".-.size
>  ary.to_s.+.frozen?
>  ```


My personal opinion is that descriptive method names would be preferable to `+/-`:

> IMHO `.-` and `.+` is not very elegant. Proper method names explaining the intent would be preferable.
> 
>   - `-@` could be `dedup`, or `deduplicate`.
>   - `+@` could be `mutable` or `mut`.





-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [ruby-core:107670] [Ruby master Feature#16295] Chainable aliases for String#-@ and String#+@
       [not found] <redmine.issue-16295.20191105134410.7941@ruby-lang.org>
                   ` (8 preceding siblings ...)
  2022-02-19 23:44 ` [ruby-core:107669] " zverok (Victor Shepelev)
@ 2022-02-20  1:49 ` phluid61 (Matthew Kerwin)
  2022-02-20 12:39 ` [ruby-core:107671] " Eregon (Benoit Daloze)
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: phluid61 (Matthew Kerwin) @ 2022-02-20  1:49 UTC (permalink / raw)
  To: ruby-core

Issue #16295 has been updated by phluid61 (Matthew Kerwin).


zverok (Victor Shepelev) wrote in #note-21:
> > `+@` seems very rarely useful
> 
> No opinion on the rest of the ticket, but I thought `buffer = +""` is a quite widespread idiom to start with mutable buffer? It is a bit cryptic, but easy to get used to, and shorter than `String.new`. The way to get used to it is to consider it just "mutable string literal", as it looks like a literal!
> 
> While `buffer = ''.dup` is arguably *more* cryptic: like, "why one would *duplicate* empty string they've just created?!"

The overarching context for this ticket is chainable aliases. As syntactic dressing for a literal, yes there is value in the existing method names. And creating an alias won't remove them so it's okay either way.

----------------------------------------
Feature #16295: Chainable aliases for String#-@ and String#+@
https://bugs.ruby-lang.org/issues/16295#change-96589

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Original discussion https://bugs.ruby-lang.org/issues/16150?next_issue_id=16147&prev_issue_id=16153#note-40

In #16150, @headius raised the following concern about `String#-@` and `String#+@`:

headius (Charles Nutter) wrote:
> > Not exactly, -@ and +@ makes this much simpler
> 
> I do like the unary operators, but they also have some precedence oddities:
> 
> ```
> >> -"foo".size
> => -3
> >> (-"foo").size
> => 3
> ```
> 
> And it doesn't work at all if you're chaining method calls:
> 
> ```
> >> +ary.to_s.frozen?
> NoMethodError: undefined method `+@' for false:FalseClass
> 	from (irb):8
> 	from /usr/bin/irb:11:in `<main>'
> ```
> 
> But you are right, instead of the explicit `dup` with possible freeze you could use `-` or `+` on the result of `to_s`. However it's still not safe to modify it since it would modify the original string too.

After working for quite a while with those, I have to say I agree. They very often force to use parentheses, which is annoying, and an indication that regular methods would be preferable to unary operators.


In response @matz proposed to alias them as `String#+` and `String#-` without arguments:

>  How about making String#+ and #- without argument behave like #+@ and #-@ respectively, so that we can write:
>  
>  ```
>  "foo".-.size
>  ary.to_s.+.frozen?
>  ```


My personal opinion is that descriptive method names would be preferable to `+/-`:

> IMHO `.-` and `.+` is not very elegant. Proper method names explaining the intent would be preferable.
> 
>   - `-@` could be `dedup`, or `deduplicate`.
>   - `+@` could be `mutable` or `mut`.





-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [ruby-core:107671] [Ruby master Feature#16295] Chainable aliases for String#-@ and String#+@
       [not found] <redmine.issue-16295.20191105134410.7941@ruby-lang.org>
                   ` (9 preceding siblings ...)
  2022-02-20  1:49 ` [ruby-core:107670] " phluid61 (Matthew Kerwin)
@ 2022-02-20 12:39 ` Eregon (Benoit Daloze)
  2022-02-21  8:46 ` [ruby-core:107681] " byroot (Jean Boussier)
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: Eregon (Benoit Daloze) @ 2022-02-20 12:39 UTC (permalink / raw)
  To: ruby-core

Issue #16295 has been updated by Eregon (Benoit Daloze).


Exactly, and so `+@` is already good enough for `buffer =  +"literal"`, and `buffer = "literal".dup` is fine too.
That's one of the rare cases where we know it's safe to reuse the String if it's already mutable.
So I think the use-cases for `.mutable`/`.mut` are very rare, either `+@` works already fine, or `.dup` should really be used instead for the safer semantics.

A third example from the original discussion would be `foo.to_s.dup << "..."` vs `+(foo.to_s) << "..."`.
The idiomatic way for concatenating would of course be simply `"#{foo}..."`, which doesn't need to know about mutability.
If some other mutable operation is needed, then `.dup` is much safer than `+@`, rather than relying on all `.to_s` creating a new String and never returning a cached mutable string (likely to not hold for a number of gems out there).

----------------------------------------
Feature #16295: Chainable aliases for String#-@ and String#+@
https://bugs.ruby-lang.org/issues/16295#change-96590

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Original discussion https://bugs.ruby-lang.org/issues/16150?next_issue_id=16147&prev_issue_id=16153#note-40

In #16150, @headius raised the following concern about `String#-@` and `String#+@`:

headius (Charles Nutter) wrote:
> > Not exactly, -@ and +@ makes this much simpler
> 
> I do like the unary operators, but they also have some precedence oddities:
> 
> ```
> >> -"foo".size
> => -3
> >> (-"foo").size
> => 3
> ```
> 
> And it doesn't work at all if you're chaining method calls:
> 
> ```
> >> +ary.to_s.frozen?
> NoMethodError: undefined method `+@' for false:FalseClass
> 	from (irb):8
> 	from /usr/bin/irb:11:in `<main>'
> ```
> 
> But you are right, instead of the explicit `dup` with possible freeze you could use `-` or `+` on the result of `to_s`. However it's still not safe to modify it since it would modify the original string too.

After working for quite a while with those, I have to say I agree. They very often force to use parentheses, which is annoying, and an indication that regular methods would be preferable to unary operators.


In response @matz proposed to alias them as `String#+` and `String#-` without arguments:

>  How about making String#+ and #- without argument behave like #+@ and #-@ respectively, so that we can write:
>  
>  ```
>  "foo".-.size
>  ary.to_s.+.frozen?
>  ```


My personal opinion is that descriptive method names would be preferable to `+/-`:

> IMHO `.-` and `.+` is not very elegant. Proper method names explaining the intent would be preferable.
> 
>   - `-@` could be `dedup`, or `deduplicate`.
>   - `+@` could be `mutable` or `mut`.





-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [ruby-core:107681] [Ruby master Feature#16295] Chainable aliases for String#-@ and String#+@
       [not found] <redmine.issue-16295.20191105134410.7941@ruby-lang.org>
                   ` (10 preceding siblings ...)
  2022-02-20 12:39 ` [ruby-core:107671] " Eregon (Benoit Daloze)
@ 2022-02-21  8:46 ` byroot (Jean Boussier)
  2022-02-21 10:57 ` [ruby-core:107683] " byroot (Jean Boussier)
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: byroot (Jean Boussier) @ 2022-02-21  8:46 UTC (permalink / raw)
  To: ruby-core

Issue #16295 has been updated by byroot (Jean Boussier).


I agree with @eregon, I should update this feature request to only ask for `String#dedup` as alias of `String#-@`.

`+@` is much less useful except for string literals.

----------------------------------------
Feature #16295: Chainable aliases for String#-@ and String#+@
https://bugs.ruby-lang.org/issues/16295#change-96599

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Original discussion https://bugs.ruby-lang.org/issues/16150?next_issue_id=16147&prev_issue_id=16153#note-40

In #16150, @headius raised the following concern about `String#-@` and `String#+@`:

headius (Charles Nutter) wrote:
> > Not exactly, -@ and +@ makes this much simpler
> 
> I do like the unary operators, but they also have some precedence oddities:
> 
> ```
> >> -"foo".size
> => -3
> >> (-"foo").size
> => 3
> ```
> 
> And it doesn't work at all if you're chaining method calls:
> 
> ```
> >> +ary.to_s.frozen?
> NoMethodError: undefined method `+@' for false:FalseClass
> 	from (irb):8
> 	from /usr/bin/irb:11:in `<main>'
> ```
> 
> But you are right, instead of the explicit `dup` with possible freeze you could use `-` or `+` on the result of `to_s`. However it's still not safe to modify it since it would modify the original string too.

After working for quite a while with those, I have to say I agree. They very often force to use parentheses, which is annoying, and an indication that regular methods would be preferable to unary operators.


In response @matz proposed to alias them as `String#+` and `String#-` without arguments:

>  How about making String#+ and #- without argument behave like #+@ and #-@ respectively, so that we can write:
>  
>  ```
>  "foo".-.size
>  ary.to_s.+.frozen?
>  ```


My personal opinion is that descriptive method names would be preferable to `+/-`:

> IMHO `.-` and `.+` is not very elegant. Proper method names explaining the intent would be preferable.
> 
>   - `-@` could be `dedup`, or `deduplicate`.
>   - `+@` could be `mutable` or `mut`.





-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [ruby-core:107683] [Ruby master Feature#16295] Chainable aliases for String#-@ and String#+@
       [not found] <redmine.issue-16295.20191105134410.7941@ruby-lang.org>
                   ` (11 preceding siblings ...)
  2022-02-21  8:46 ` [ruby-core:107681] " byroot (Jean Boussier)
@ 2022-02-21 10:57 ` byroot (Jean Boussier)
  2022-02-21 19:04 ` [ruby-core:107691] " danh337 (Dan H)
  2022-02-21 19:35 ` [ruby-core:107695] " danh337 (Dan H)
  14 siblings, 0 replies; 15+ messages in thread
From: byroot (Jean Boussier) @ 2022-02-21 10:57 UTC (permalink / raw)
  To: ruby-core

Issue #16295 has been updated by byroot (Jean Boussier).

Status changed from Open to Closed

Closing in favor of https://bugs.ruby-lang.org/issues/18595

----------------------------------------
Feature #16295: Chainable aliases for String#-@ and String#+@
https://bugs.ruby-lang.org/issues/16295#change-96602

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Original discussion https://bugs.ruby-lang.org/issues/16150?next_issue_id=16147&prev_issue_id=16153#note-40

In #16150, @headius raised the following concern about `String#-@` and `String#+@`:

headius (Charles Nutter) wrote:
> > Not exactly, -@ and +@ makes this much simpler
> 
> I do like the unary operators, but they also have some precedence oddities:
> 
> ```
> >> -"foo".size
> => -3
> >> (-"foo").size
> => 3
> ```
> 
> And it doesn't work at all if you're chaining method calls:
> 
> ```
> >> +ary.to_s.frozen?
> NoMethodError: undefined method `+@' for false:FalseClass
> 	from (irb):8
> 	from /usr/bin/irb:11:in `<main>'
> ```
> 
> But you are right, instead of the explicit `dup` with possible freeze you could use `-` or `+` on the result of `to_s`. However it's still not safe to modify it since it would modify the original string too.

After working for quite a while with those, I have to say I agree. They very often force to use parentheses, which is annoying, and an indication that regular methods would be preferable to unary operators.


In response @matz proposed to alias them as `String#+` and `String#-` without arguments:

>  How about making String#+ and #- without argument behave like #+@ and #-@ respectively, so that we can write:
>  
>  ```
>  "foo".-.size
>  ary.to_s.+.frozen?
>  ```


My personal opinion is that descriptive method names would be preferable to `+/-`:

> IMHO `.-` and `.+` is not very elegant. Proper method names explaining the intent would be preferable.
> 
>   - `-@` could be `dedup`, or `deduplicate`.
>   - `+@` could be `mutable` or `mut`.





-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [ruby-core:107691] [Ruby master Feature#16295] Chainable aliases for String#-@ and String#+@
       [not found] <redmine.issue-16295.20191105134410.7941@ruby-lang.org>
                   ` (12 preceding siblings ...)
  2022-02-21 10:57 ` [ruby-core:107683] " byroot (Jean Boussier)
@ 2022-02-21 19:04 ` danh337 (Dan H)
  2022-02-21 19:35 ` [ruby-core:107695] " danh337 (Dan H)
  14 siblings, 0 replies; 15+ messages in thread
From: danh337 (Dan H) @ 2022-02-21 19:04 UTC (permalink / raw)
  To: ruby-core

Issue #16295 has been updated by danh337 (Dan H).


Eregon (Benoit Daloze) wrote in #note-19:
> > .dup is not quite as good, as it always allocates a copy.
> 
> It creates a new String instance, which is what one needs to guarantee safe mutation without affecting other parts of the program.
> Hence, `+@` should rarely be used (only if we know where all the strings passed to this method come from and it's OK to mutate them).
> `.dup` does not copy the actual bytes until mutated, because Strings are copy-on-write.
> 
> > how is -@ different from .freeze ? The meaning of these seems very much the same.
> 
> `-@` interns and might return a different String instance, `.freeze` does not intern and always returns the receiver.

I see you are talking about the internal workings of the code for these, but the semantics is more important.

If I want to use a method name to have the same effect as `-"foo"` I do `"foo".freeze`. There isn't really another way and no other way is needed.

If I want to use a method name for `+"foo"` you say to use `"foo".dup`, but semantically that doesn't work well.

Does anybody else say `.dup` is the best alternative to `.+@`? I'm sorry I do not agree.

Is adding a `.dedup` method when we have `.freeze` really the final decision here? I guess if I'm the only objection then so be it.

And it seems odd to just close this when there are some open questions.

----------------------------------------
Feature #16295: Chainable aliases for String#-@ and String#+@
https://bugs.ruby-lang.org/issues/16295#change-96609

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Original discussion https://bugs.ruby-lang.org/issues/16150?next_issue_id=16147&prev_issue_id=16153#note-40

In #16150, @headius raised the following concern about `String#-@` and `String#+@`:

headius (Charles Nutter) wrote:
> > Not exactly, -@ and +@ makes this much simpler
> 
> I do like the unary operators, but they also have some precedence oddities:
> 
> ```
> >> -"foo".size
> => -3
> >> (-"foo").size
> => 3
> ```
> 
> And it doesn't work at all if you're chaining method calls:
> 
> ```
> >> +ary.to_s.frozen?
> NoMethodError: undefined method `+@' for false:FalseClass
> 	from (irb):8
> 	from /usr/bin/irb:11:in `<main>'
> ```
> 
> But you are right, instead of the explicit `dup` with possible freeze you could use `-` or `+` on the result of `to_s`. However it's still not safe to modify it since it would modify the original string too.

After working for quite a while with those, I have to say I agree. They very often force to use parentheses, which is annoying, and an indication that regular methods would be preferable to unary operators.


In response @matz proposed to alias them as `String#+` and `String#-` without arguments:

>  How about making String#+ and #- without argument behave like #+@ and #-@ respectively, so that we can write:
>  
>  ```
>  "foo".-.size
>  ary.to_s.+.frozen?
>  ```


My personal opinion is that descriptive method names would be preferable to `+/-`:

> IMHO `.-` and `.+` is not very elegant. Proper method names explaining the intent would be preferable.
> 
>   - `-@` could be `dedup`, or `deduplicate`.
>   - `+@` could be `mutable` or `mut`.





-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [ruby-core:107695] [Ruby master Feature#16295] Chainable aliases for String#-@ and String#+@
       [not found] <redmine.issue-16295.20191105134410.7941@ruby-lang.org>
                   ` (13 preceding siblings ...)
  2022-02-21 19:04 ` [ruby-core:107691] " danh337 (Dan H)
@ 2022-02-21 19:35 ` danh337 (Dan H)
  14 siblings, 0 replies; 15+ messages in thread
From: danh337 (Dan H) @ 2022-02-21 19:35 UTC (permalink / raw)
  To: ruby-core

Issue #16295 has been updated by danh337 (Dan H).


Eregon (Benoit Daloze) wrote in #note-7:
> @danh337 `-@` and the proposed `dedup` intern/deduplicate.
> This is the main feature of those methods and it is *very much* part of the semantics (as the docs say).
> It's the whole point of these methods really, to reduce the number of duplicate strings and reduce memory usage (which @byroot and others successfully used in many gems).
> 
> `freeze` does not intern/deduplicate. That has the advantage it's faster, but it doesn't help memory footprint if there are many duplicates of the same string.
> 
> Regarding `+@`/`dup` feel free to continue discussing that on #16295, this issue should remain focused on `dedup`, that is the purpose of the new issue.

The `.@+` is still not resolved, even though #16295 is closed. If the *behavior* of `.+@` and `.dup` is the same, that's fine and I get your point, but `x = "".dup` is semantically weird. I realize that `x = +""` is probably what most would use anyway, but for method chains that mutate a String, where I know the String is *expected* to mutate, a "fast" inverse of `.freeze` would be nice instead of always `.dup`. If a String is already mutable, we do not want to duplicate it.

----------------------------------------
Feature #16295: Chainable aliases for String#-@ and String#+@
https://bugs.ruby-lang.org/issues/16295#change-96613

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Original discussion https://bugs.ruby-lang.org/issues/16150?next_issue_id=16147&prev_issue_id=16153#note-40

In #16150, @headius raised the following concern about `String#-@` and `String#+@`:

headius (Charles Nutter) wrote:
> > Not exactly, -@ and +@ makes this much simpler
> 
> I do like the unary operators, but they also have some precedence oddities:
> 
> ```
> >> -"foo".size
> => -3
> >> (-"foo").size
> => 3
> ```
> 
> And it doesn't work at all if you're chaining method calls:
> 
> ```
> >> +ary.to_s.frozen?
> NoMethodError: undefined method `+@' for false:FalseClass
> 	from (irb):8
> 	from /usr/bin/irb:11:in `<main>'
> ```
> 
> But you are right, instead of the explicit `dup` with possible freeze you could use `-` or `+` on the result of `to_s`. However it's still not safe to modify it since it would modify the original string too.

After working for quite a while with those, I have to say I agree. They very often force to use parentheses, which is annoying, and an indication that regular methods would be preferable to unary operators.


In response @matz proposed to alias them as `String#+` and `String#-` without arguments:

>  How about making String#+ and #- without argument behave like #+@ and #-@ respectively, so that we can write:
>  
>  ```
>  "foo".-.size
>  ary.to_s.+.frozen?
>  ```


My personal opinion is that descriptive method names would be preferable to `+/-`:

> IMHO `.-` and `.+` is not very elegant. Proper method names explaining the intent would be preferable.
> 
>   - `-@` could be `dedup`, or `deduplicate`.
>   - `+@` could be `mutable` or `mut`.





-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2022-02-21 19:35 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <redmine.issue-16295.20191105134410.7941@ruby-lang.org>
2021-03-30 21:12 ` [ruby-core:103113] [Ruby master Feature#16295] Chainable aliases for String#-@ and String#+@ dan
2021-03-30 21:31 ` [ruby-core:103114] " dan
2021-03-30 21:52 ` [ruby-core:103115] " merch-redmine
2021-03-30 23:11 ` [ruby-core:103116] " eregontp
2022-02-18 22:41 ` [ruby-core:107661] " danh337 (Dan H)
2022-02-18 22:48 ` [ruby-core:107662] " danh337 (Dan H)
2022-02-19 20:34 ` [ruby-core:107667] " Eregon (Benoit Daloze)
2022-02-19 20:39 ` [ruby-core:107668] " Eregon (Benoit Daloze)
2022-02-19 23:44 ` [ruby-core:107669] " zverok (Victor Shepelev)
2022-02-20  1:49 ` [ruby-core:107670] " phluid61 (Matthew Kerwin)
2022-02-20 12:39 ` [ruby-core:107671] " Eregon (Benoit Daloze)
2022-02-21  8:46 ` [ruby-core:107681] " byroot (Jean Boussier)
2022-02-21 10:57 ` [ruby-core:107683] " byroot (Jean Boussier)
2022-02-21 19:04 ` [ruby-core:107691] " danh337 (Dan H)
2022-02-21 19:35 ` [ruby-core:107695] " danh337 (Dan H)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).