Couldn't we get rid of some "features" that have little practical use and create problems for implementers and make optimisation harder?
For example `$~` and `$_` variables. Yes, they are lazily loaded but they force the VM implementers to jump through so many hops in order to keep track of them.
> In the case of $~ and $_, the challenge is not in representing accesses of them directly but in handling implicit reads and writes of them that cross call boundaries. For example, calling [] on a String and passing a Regexp will cause the caller's frame-local $~ (and related values) to be updated to the MatchData for the pattern match that happens inside [].
Indeed we could, and as a reply mentions some implementations do take liberties with various Ruby features like $~ and $_ (in MacRuby they are thread-local, which sorta works but is often broken behavior).
Part of my challenge as a Ruby implementer is to figure out which features really must be implemented to the letter of the law and which ones can be fudged without impacting anyone. ObjectSpace was an example that could be fudged; it turned out nobody ever used it for anything other than iterating over all classes in the system. I also often make my case to the MRI/ruby-core folks and Matz himself as to features that are an unreasonable performance hit for not enough benefit. Sometimes I win those arguments, sometimes I lose them.
I agree. I would also propose that some esoteric features are separated out into gems. For example, String encoding could be simplified to support only UTF-8, with a gem for the few people who need something else. The Date/Time class also is a monster that supports calendar changes from the 16th century, accurate to the nanosecond.
In general, a standard library that offers a 95% of what most people need, instead of 99%, seems like a good way to go.
For example `$~` and `$_` variables. Yes, they are lazily loaded but they force the VM implementers to jump through so many hops in order to keep track of them.
> In the case of $~ and $_, the challenge is not in representing accesses of them directly but in handling implicit reads and writes of them that cross call boundaries. For example, calling [] on a String and passing a Regexp will cause the caller's frame-local $~ (and related values) to be updated to the MatchData for the pattern match that happens inside [].