ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
From: mame@ruby-lang.org
To: ruby-core@ruby-lang.org
Subject: [ruby-core:95018] [Ruby master Feature#16153] eventually_frozen flag to gradually phase-in frozen strings
Date: Sat, 21 Sep 2019 16:27:52 +0000 (UTC)	[thread overview]
Message-ID: <redmine.journal-81645.20190921162752.c82ce81513f9c6d1@ruby-lang.org> (raw)
In-Reply-To: redmine.issue-16153.20190909021526@ruby-lang.org

Issue #16153 has been updated by mame (Yusuke Endoh).


Matz didn't determine this proposal at the meeting.  There were four points discussed:

* Before matz accepts this proposal, he must decide the grand design change: Ruby should be immutable by default?
* If we want to make Ruby gradually immutable, this proposal is feasible.
* However, it is arguable if it is worthwhile consuming one bit for each object for this feature.
* Even after Ruby is immutable, it is doubtful if Ruby becomes so faster.

---

The following is my opinion.

I'm against making Ruby immutable by default.  One of the most important properties of Ruby is dynamics.  Ruby has allowed users to change almost anything in run time: dynamically (re)defining classes and methods (including core builtin ones), manipulating instance variables and local variables (via Binding) through encapsulation, etc.  These features are not recommended to abuse, but they actually bring big flexibility: monkey-patching, DRY, flexible operation, etc.  However, blindly freezing objects may spoil this usefulness.

It is a bit arguable if this flexibility limits performance.  Some people say that it is possible to make Ruby fast with the flexibility kept (TruffleRuby proves it).  That being said, I admit that the flexibility actually limits performance in the current MRI, and that we have no development resource to improve MRI so much in near future.  I think that my proposal #11934 was one possible way to balance the flexibility and performance.  Anyway, we need to estimate how much Ruby can be faster if the flexibility is dropped.  If it becomes 10 times faster, it is worth considering of course.  If it becomes 10 percent faster, it does not pay (in my opinion).

----------------------------------------
Feature #16153: eventually_frozen flag to gradually phase-in frozen strings
https://bugs.ruby-lang.org/issues/16153#change-81645

* Author: Dan0042 (Daniel DeLorme)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Freezing objects can give us a nice performance boost, but freezing previously non-frozen objects is a backward-incompatible change which is hard to handle because the place where the object is mutated can be far from where it was frozen, and tests might not cover the cases of frozen input vs non-frozen input.

I propose adding a flag which gives us a migration path for freezing objects. For purposes of discussion I will call this flag "eventually_frozen". It would act as a pseudo-frozen flag where mutating the object would result in a warning instead of an error. It would also change the return value of `Object#frozen?` so code like `obj = obj.dup if obj.frozen?` would work as expected to remove the warning. Note that eventually_frozen strings cannot be deduplicated, as they are in reality mutable.

This way it would be possible for Symbol#to_s (and many others) to return an eventually_frozen string in 2.7 which gives apps and gems time to migrate, before finally becoming a frozen deduplicated string in 3.0. This might even open up a migration path for eventually using `frozen_string_literal:true` as default. For example if it was possible to add `frozen_string_literal:eventual` to all files in a project (or as a global switch), we could run that in production to discover where to fix things, and then change it to `frozen_string_literal:true` for a bug-free performance boost.

Proposed changes:
* Object#freeze(immediately:true)
   * if `immediately` keyword is true, set frozen=true and eventually_frozen=false
   * if `immediately` keyword is false, set eventually_frozen=true UNLESS frozen flag is already true
* String#+@
   * if eventually_frozen is true, create a duplicate string with eventually_frozen=false
* Object#frozen?(immediately:false)
   * return true if `immediately` keyword is false and eventually_frozen flag is true
* rb_check_frozen
   * output warning if eventually_frozen flag is true




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

  parent reply	other threads:[~2019-09-21 16:28 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <redmine.issue-16153.20190909021526@ruby-lang.org>
2019-09-09  2:15 ` [ruby-core:94851] [Ruby master Feature#16153] eventually_frozen flag to gradually phase-in frozen strings daniel
2019-09-19  9:11 ` [ruby-core:94986] " duerst
2019-09-19 18:46 ` [ruby-core:94992] " daniel
2019-09-20 11:32 ` [ruby-core:95003] " duerst
2019-09-21  8:33 ` [ruby-core:95016] " shevegen
2019-09-21 16:27 ` mame [this message]
2019-09-23 20:43 ` [ruby-core:95046] " daniel
2019-11-01 13:56 ` [ruby-core:95635] " daniel
2019-11-03 16:52 ` [ruby-core:95659] " eregontp
2019-11-03 16:58 ` [ruby-core:95660] " eregontp
2019-11-04 16:17 ` [ruby-core:95669] " daniel
2019-11-06 10:49 ` [ruby-core:95721] " eregontp
2019-11-06 11:09 ` [ruby-core:95723] " jean.boussier

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-81645.20190921162752.c82ce81513f9c6d1@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).