ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
From: eregontp@gmail.com
To: ruby-core@ruby-lang.org
Subject: [ruby-core:100528] [Ruby master Feature#17273] shareable_constant_value pragma
Date: Sun, 25 Oct 2020 12:57:57 +0000 (UTC)	[thread overview]
Message-ID: <redmine.journal-88152.20201025125757.17@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-17273.20201021055619.17@ruby-lang.org

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


Maybe the pragma should be `# frozen_constants: true`?
"Freezing a constant" is intuitively "deeply-freeze the value", isn't it?

And since we already have `# frozen_string_literal: true` it would make nice connection.

Also, `shareable` seems very abstract, while I'd think almost every Rubyist knows what frozen (and deeply frozen) means.

Semantics-wise, I think we could still use the same semantics as `Ractor.make_shareable`.
I guess nobody wants a `deep_freeze` that also freezes an object's class.
And freezing a shareable object which is not always frozen (immutable) seems of little value:
* no much point to freeze a `Ractor`/`Thread::TVar`
* those are probably uncommon to be used as a value for a constant

Are there other shareable but not immutable objects besides `Ractor`/`Thread::TVar`/`Module`?

Along that idea, I think `#deep_freeze` (#17145) could by default skip shareable values (so `skip_shareable:` would default to true).

----------------------------------------
Feature #17273: shareable_constant_value pragma
https://bugs.ruby-lang.org/issues/17273#change-88152

* Author: ko1 (Koichi Sasada)
* Status: Open
* Priority: Normal
----------------------------------------
This proposal is to introduce `# shareable_constant_value: true` pragma to make constant values shareable objects.
With this pragma, you don't need to add `freeze` to access from non-main ractors.

```ruby
# shareable_constant_value: true

A = [1, [2, [3, 4]]]
H = {a: "a"}

Ractor.new do
  p A
  p H
end.take
```

## Background

Now, we can not access constants which contains a unshareable object from the non-main Ractor.

```ruby
A = [1, [2, [3, 4]]]
H = {a: "a"}

Ractor.new do
  p A #=> can not access non-sharable objects in constant Object::A by non-main Ractor. (NameError)
  p H
end.take
```

If we know we don't modify `A` and `H` is frozen object, we can freeze them, and other ractors can access them.


```ruby
A = [1, [2, [3, 4].freeze].freeze].freeze
H = {a: "a".freeze}.freeze

Ractor.new do
  p A #=> [1, [2, [3, 4]]]
  p H #=> {:a=>"a"}
end.take
```

Adding nesting data structure, we need many `.freeze` method.
Recently, I added `Ractor.make_shareable(obj)` makes `obj` shareable with freezing objects deeply (see [Feature #17274]).
We only need to introduce this method for each constant.

```ruby
A = Ractor.make_shareable( [1, [2, [3, 4]]] )
H = Ractor.make_shareable( {a: "a"} )

Ractor.new do
  p A #=> [1, [2, [3, 4]]]
  p H #=> {:a=>"a"}
end.take
```

However, if we have 100 constants, it is troublesome.

## Proposal

With `# shareable_constant_value: true`, you can specify all constants are shareable.

```ruby
# shareable_constant_value: true

A = [1, [2, [3, 4]]]
# compiled with: A = Ractor.make_shareable( [1, [2, [3, 4]]] )
H = {a: "a"}
# compiled with: H = Ractor.make_shareable( {a: "a"} )

Ractor.new do
  p A
  p H
end.take
```

(Strictly speaking, don't call `Ractor.make_shareable`, but apply same effect. This means rewriting `Ractor.make_shareable` doesn't affect this behavior)

You can specify `# shareable_constant_value: false` in the middle of the place.

```ruby
# shareable_constant_value: true

S1 = 'str' #
p S1.frozen? #=> true

# shareable_constant_value: false

S2 = 'str' #
p S2.frozen? #=> false
```

The effect of this pragma is closed to the scope.

```ruby
class C
  # shareable_constant_value: true
  A = 'str'
  p A.frozen? #=> true

  1.times do
    # shareable_constant_value: false
    B = 'str'
    p B.frozen? #=> false
  end
end

X = 'str'
p X.frozen? #=> false
```

`Ractor.make_shareable(obj)` doesn't affect anything to shareable objects.


```ruby
# shareable_constant_value: true
class C; end

D = C
p D.frozen? #=> false
```

Some objects can not become shareable objects, so it raises an exception:

```ruby
# shareable_constant_value: true

T = Thread.new{}
#=> `make_shareable': can not make shareable object for #<Thread:0x000055952e40ffb0 /home/ko1/ruby/src/trunk/test.rb:3 run> (Ractor::Error)
```

## Implementation

https://github.com/ruby/ruby/pull/3681/files



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

  parent reply	other threads:[~2020-10-25 12:58 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-21  5:56 [ruby-core:100466] [Ruby master Feature#17273] shareable_constant_value pragma ko1
2020-10-21 18:58 ` [ruby-core:100477] " eregontp
2020-10-22  0:46 ` [ruby-core:100484] " ko1
2020-10-22  0:52 ` [ruby-core:100485] " ko1
2020-10-23 21:23 ` [ruby-core:100517] " marcandre-ruby-core
2020-10-25 12:57 ` eregontp [this message]
2020-10-26 16:29 ` [ruby-core:100581] " ko1
2020-10-29 16:14 ` [ruby-core:100647] " ko1
2020-10-29 19:26 ` [ruby-core:100652] " eregontp
2020-10-29 19:29 ` [ruby-core:100653] " eregontp
2020-10-29 19:33 ` [ruby-core:100654] " eregontp
2020-10-29 19:47 ` [ruby-core:100657] " ko1
2020-10-29 19:53 ` [ruby-core:100659] " merch-redmine
2020-12-16 18:36 ` [ruby-core:101473] " marcandre-ruby-core

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.ruby-lang.org/en/community/mailing-lists/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=redmine.journal-88152.20201025125757.17@ruby-lang.org \
    --to=ruby-core@ruby-lang.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).