From: Austin Ziegler Date: 2018-03-23T16:24:38-04:00 Subject: [ruby-core:86270] Re: [Ruby trunk Feature#14594] Rethink yield_self's name --===============1434654388== Content-Type: multipart/alternative; boundary="000000000000db801305681a3751" --000000000000db801305681a3751 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Using `map` would mean that there=E2=80=99s no way of accessing `yield_self= ` behaviour for items that mix in `Enumerable` or already have a `map` function. On Fri, Mar 23, 2018 at 4:08 PM, wrote: > Issue #14594 has been updated by cmoel (Christopher Moeller). > > > I also agree `yield_self` isn't the best name but I'm also skeptical of > `then`. Why not use `map`, which we already have for collections? General= ly > speaking, the `map` function isn't just about collections (though that's > usually how it's used in Ruby). `map` is more about putting an object in = a > context (a block in Ruby's case), modifying the object, and returning the > modified object. > > Another benefit to calling the method `map` instead of `yield_self` or > `then` is most Rubyists already understand `map` and how it's applied to > collections, so there probably wouldn't be a large learning curve for it. > It can be summarized like this: "`Object#map` is similar to applying `map= ` > to an array containing 1 element." > > Though I'm not familiar with the details, `Enumerable#map` and friends' > implementation of `map` could then be an override of `Object#map`, yieldi= ng > the block to each element in the collection, which would maintain how `ma= p` > currently works on collections. > > Can anyone think of any issues with using `map` as a different/better nam= e > for `yield_self`? > > ---------------------------------------- > Feature #14594: Rethink yield_self's name > https://bugs.ruby-lang.org/issues/14594#change-71177 > > * Author: zverok (Victor Shepelev) > * Status: Open > * Priority: Normal > * Assignee: > * Target version: > ---------------------------------------- > *I feel really uncomfortable raising the question again, but...* > > In several months since 2.5 release I've written a lot of code with > `yield_self` (using `backports` gem with earlier versions of Ruby when > necessary), and explained it several times to students, and colleagues (a= nd > in this [blog post](https://zverok.github.io/blog/2018-01-24-yield_self. > html) which have gained pretty decent attention). > > I should say that I am still assured the name chosen is really not > optimal. Reasons: > > * it is just too long for such a basic operation; > * it does not say "what it does", but rather "how it is implemented"; it > is like having `each_returning_block_result` instead of `map`; > * `self` is really misguiding and obscure in situations like this: > > ```ruby > class MyClass > def some_method > @path.yield_self(&File.method(:read)).yield_self(&Parser.method(:new)= ) > ... > end > end > ``` > Intuitively, word "self" inside instance method is read like it somehow > related to current context's `self` (e.g. instance of `MyClass`), which i= t > is absolutely not. In other words, "self" in caller's context has nothing > to do with "self" implied by method's name. > > After reconsidering a lot of options, **my current proposal is: `#then`**= . > > Reasons: > > * despite being a keyword, `something.then(something)` is not a > conflicting Ruby syntax, and allowed by current Ruby; > * it is short! > * it shows intention pretty well, and reads natural, in both cases: when > receives block and when returns Enumerator: > > ```ruby > File.read(filename).then(&JSON.method(:parse)) > rand(10).then.detect(&:odd?) > ``` > > In many languages, `.then` or `.and_then` is useful construct, meaning th= e > same (calculate next value from the result of the previous operation), ju= st > in a narrower context of futures/promises. I believe that even when/if Ru= by > will have those as a language feature, that syntax will play well: > > ```ruby > value.then(&:computation) # =3D> value > promise.then(&:computation) # =3D> promise > ``` > > PS: For historical reasons, [here](https://bugs.ruby-lang. > org/issues/12760#note-5) is huge list of previous proposals I've gathered > for this method name. > > > > -- > https://bugs.ruby-lang.org/ > > Unsubscribe: > > --=20 Austin Ziegler =E2=80=A2 halostatue@gmail.com =E2=80=A2 austin@halostatue.c= a http://www.halostatue.ca/ =E2=80=A2 http://twitter.com/halostatue --000000000000db801305681a3751 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Using `map` would mean that there=E2=80=99s no way of acce= ssing `yield_self` behaviour for items that mix in `Enumerable` or already = have a `map` function.

On Fri, Mar 23, 2018 at 4:08 PM, <cmoel@me.com> wrot= e:
Issue #14594 has been updated by cmoel= (Christopher Moeller).


I also agree `yield_self` isn't the best name but I'm also skeptica= l of `then`. Why not use `map`, which we already have for collections? Gene= rally speaking, the `map` function isn't just about collections (though= that's usually how it's used in Ruby). `map` is more about putting= an object in a context (a block in Ruby's case), modifying the object,= and returning the modified object.

Another benefit to calling the method `map` instead of `yield_self` or `the= n` is most Rubyists already understand `map` and how it's applied to co= llections, so there probably wouldn't be a large learning curve for it.= It can be summarized like this: "`Object#map` is similar to applying = `map` to an array containing 1 element."

Though I'm not familiar with the details, `Enumerable#map` and friends&= #39; implementation of `map` could then be an override of `Object#map`, yie= lding the block to each element in the collection, which would maintain how= `map` currently works on collections.

Can anyone think of any issues with using `map` as a different/better name = for `yield_self`?

----------------------------------------
Feature #14594: Rethink yield_self's name
https://bugs.ruby-lang.org/issues/14= 594#change-71177

* Author: zverok (Victor Shepelev)
* Status: Open
* Priority: Normal
* Assignee:
* Target version:
----------------------------------------
*I feel really uncomfortable raising the question again, but...*

In several months since 2.5 release I've written a lot of code with `yi= eld_self` (using `backports` gem with earlier versions of Ruby when necessa= ry), and explained it several times to students, and colleagues (and in thi= s [blog post](https://zverok.github.io/= blog/2018-01-24-yield_self.html) which have gained pretty decent a= ttention).

I should say that I am still assured the name chosen is really not optimal.= Reasons:

* it is just too long for such a basic operation;
* it does not say "what it does", but rather "how it is impl= emented"; it is like having `each_returning_block_result` instead of `= map`;
* `self` is really misguiding and obscure in situations like this:

```ruby
class MyClass
=C2=A0 def some_method
=C2=A0 =C2=A0 @path.yield_self(&File.method(:read)).yield_self(&am= p;Parser.method(:new)) ...
=C2=A0 end
end
```
Intuitively, word "self" inside instance method is read like it s= omehow related to current context's `self` (e.g. instance of `MyClass`)= , which it is absolutely not. In other words, "self" in caller= 9;s context has nothing to do with "self" implied by method's= name.

After reconsidering a lot of options, **my current proposal is: `#then`**.<= br>
Reasons:

* despite being a keyword, `something.then(something)` is not a conflicting= Ruby syntax, and allowed by current Ruby;
* it is short!
* it shows intention pretty well, and reads natural, in both cases: when re= ceives block and when returns Enumerator:

```ruby
File.read(filename).then(&JSON.method(:parse))
rand(10).then.detect(&:odd?)
```

In many languages, `.then` or `.and_then` is useful construct, meaning the = same (calculate next value from the result of the previous operation), just= in a narrower context of futures/promises. I believe that even when/if Rub= y will have those as a language feature, that syntax will play well:

```ruby
value.then(&:computation) # =3D> value
promise.then(&:computation) # =3D> promise
```

PS: For historical reasons, [here](https://bugs.ruby-l= ang.org/issues/12760#note-5) is huge list of previous proposals I&= #39;ve gathered for this method name.



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

Unsubscribe: <mailto:= ruby-core-request@ruby-lang.org?subject=3Dunsubscribe>
<http://lists.ruby-lang.org/cgi-= bin/mailman/options/ruby-core>



--
=
--000000000000db801305681a3751-- --===============1434654388== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline Unsubscribe: --===============1434654388==--