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


ioquatix (Samuel Williams) wrote:
> I think it's a good idea. Might I suggest two potential ideas?

Go ahead :)

> Firstly, maybe have a shared `Ruby` module for common but interpreter specific functionality.

This is equivalent to my proposition of `ExperimentalFeatures` with a different name, right?

I don't understand how it can be "common" and also "interpreter specific". They are opposite to me. Did you mean "but not"?

> Then, interpreter specific modules e.g. `CRuby`, `MRuby`, `JRuby`, `TruffleRuby` for interpreter specific functionality.
> 
> For experimental stuff, you could choose either `CRuby::Experimental` or `Ruby::Experimental`.

I was thinking both the common namespace and the interpreter-specific namespaces are experimental.
But indeed, maybe we need to be more fine-grained.

For instance, TruffleRuby defines a few methods and classes under `TruffleRuby` and those are fairly stable and documented.
https://github.com/oracle/truffleruby/blob/master/doc/user/truffleruby-additions.md#truffleruby-methods-and-classes
BTW, a few of those would probably make sense under `ExperimentalFeatures` (most of these are needed by ConcurrentRuby).

I think anything under `ExperimentalFeatures` is experimental.
Common stable (non-experimental) features should just be under another namespace (e.g., Kernel or whatever feels appropriate, including possibly a new class/module for the feature).

For interpreter-specific namespaces, I think it's OK to delegate to the documentation of the implementation to say what's experimental and what's stable,
although the distinction should be simple such as `TruffleRuby` would be stable and `TruffleRuby::Experimental` would be experimental.

I think `CRuby::Experimental` would be good (as a replacement for `RubyVM`), because it clearly marks such API are MRI specific and have not matured to a stable API yet.
Just as an example, `RubyVM::AbstractSyntaxTree` will probably break usages of it whenever a node field is added, removed or reordered,
so being clearly marked as experimental in the usages seems good.

> The path for loading such features would be `require 'ruby/experimental/thing'`.

Typically the require is not needed, such functionality is just declared from startup.
That's the case for JRuby, TruffleRuby and Rubinius.
I'm not against it, but I don't see what it solves.
For feature checking, `defined?(ExperimentalFeatures.foo)` (or `respond_to?`) seems good enough.

> Maybe also worthwhile considering how Python's `__future__` works, e.g. https://stackoverflow.com/questions/7075082/what-is-future-in-python-used-for-and-how-when-to-use-it-and-how-it-works is a quick overview if anyone is unfamiliar.

How would that work in Ruby?
It seems more targeted at trying to make code more compatible with more recent versions, which I think we simply do by deprecation in Ruby and not breaking syntax.

----------------------------------------
Feature #15752: A dedicated module for portable experimental features
https://bugs.ruby-lang.org/issues/15752#change-77529

* Author: Eregon (Benoit Daloze)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
I believe we should introduce a module for experimental features portable across Ruby implementations.

An example of such a portable experimental feature is `RubyVM.resolve_feature_path`.
This feature has nothing MRI specific in it, it is a part of basic `require` functionality.
In the future, I would think more experimental features will be introduced, and I think `RubyVM` is not a good place for it.

Currently, `RubyVM` is sometimes used for experimental features, but I believe `RubyVM` should be defined only on MRI and contain only MRI-specific features.
This means it is *impossible* for other implementations such as JRuby and TruffleRuby to define `resolve_feature_path` (even though it's trivial and might be useful for some users),
and keeping `RubyVM` not defined for clearly marking MRI specific features are not available.

This is a problem that will only gets worse as portable experimental features are added to `RubyVM`.
Here is one example of adding an experimental feature but unfortunately there is no common place between Ruby implementations to add it:
https://github.com/jruby/jruby/issues/5206

If other implementations defined `RubyVM`, then only parts of it would be portable and other parts would be MRI specific,
which would be very confusing to both users and Ruby implementers.

Also, `RubyVM` doesn't really indicate by its name that it contains experimental features.

So I propose the obvious name `ExperimentalFeatures`.

I think such a long name is unlikely to clash with existing Object constants, is very clear,
and marks that any usage of it is by definition using not stable APIs that might be removed or changed.

In combination with #15743, this would mean we can very clearly see what kind of feature it is due to explicit naming:

* `ExperimentalFeatures.resolve_feature_path` is a portable experimental feature, which can be supported on other Ruby implementations too.
* `CRuby::InstructionSequence` is a CRuby/MRI-specific feature, which will only be supported on MRI.

OTOH, the `RubyVM` name doesn't indicate this important difference, and doesn't even indicate the features under it might experimental or not portable.

My main motivation here, is allowing other Ruby implementations to support some of these portable experimental features.
There is no reason for only MRI to be able to support code using portable experimental features.

cc @mame @headius



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

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