Adding, removing and redefining features at runtime

I am working on an article on the subject of implementing dynamically typed
languages on the .net CLR. In .net Types are immutable, ie. once defined
they cannot be changed. Writing about this I needed to cover the problem of
namespace collisions. Most modern languages including ruby has introduced
namespaces to alleviate the namespace collision problem, but the convention
of adding your own methods to existing classes reintroduces the problem.

Is ruby merely being pragmatic by allowing you to do this, because it seldom
causes any real problems? Or is it inherently wrong and should not be
permitted by the language/object model?

How do you feel about this feature. Would it be a big loss if ruby didn’t
support it? My own feelings are ambivalent. I have found myself adding
features to Time, Enumerable, Module and when I do it I always appreciate
how nice it is that the feature is where it belongs, but I always have this
nagging fear of collisions that I push to the back of my mind.

Curious Tom

I am working on an article on the subject of implementing dynamically typed

languages on the .net CLR. In .net Types are immutable, ie. once defined

they cannot be changed. Writing about this I needed to cover the problem of

namespace collisions. Most modern languages including ruby has introduced

namespaces to alleviate the namespace collision problem, but the convention

of adding your own methods to existing classes reintroduces the problem.

···

On Fri, 26 Sep 2003, Thomas Sondergaard wrote:

Sounds like an interesting article. I didn’t realize you were a .Net’er.
Looking forward to reading it if it will be available. Will it?

Is ruby merely being pragmatic by allowing you to do this, because it seldom

causes any real problems? Or is it inherently wrong and should not be

permitted by the language/object model?

Why would it be in Ruby (and other languages) if it were inherently wrong?
Sounds like kind of a loaded question.

How do you feel about this feature. Would it be a big loss if ruby didn’t

support it? My own feelings are ambivalent. I have found myself adding

features to Time, Enumerable, Module and when I do it I always appreciate

how nice it is that the feature is where it belongs, but I always have this

nagging fear of collisions that I push to the back of my mind.

If not for this feature, I might not have ended up staying with Ruby when
I started learning it several years ago. It’s a unifying part of the
whole dynamic feeling and philosophy of the language. Ruby without this
feature would cease to be Ruby to me.

Chad

I am working on an article on the subject of implementing dynamically
typed languages on the .net CLR. In .net Types are immutable, ie. once
defined they cannot be changed. Writing about this I needed to cover the
problem of namespace collisions. Most modern languages including ruby
has introduced namespaces to alleviate the namespace collision problem,
but the convention of adding your own methods to existing classes
reintroduces the problem.

Is ruby merely being pragmatic by allowing you to do this, because it
seldom causes any real problems? Or is it inherently wrong and should
not be permitted by the language/object model?

It’s controversial, that’s for sure, and well worth writing an article
about, as the risks are obvious but not all of the benefits are.

It is wrong to argue that it’s inherently wrong. It’s also wrong to argue
that it’s inherently right. You could say that Ruby is being pragmatic
because it seldom causes problems, but you need to emphasise the
responsibility of the programmer to make sure their code behaves nicely.

How do you feel about this feature. Would it be a big loss if ruby
didn’t support it? My own feelings are ambivalent. I have found myself
adding features to Time, Enumerable, Module and when I do it I always
appreciate how nice it is that the feature is where it belongs, but I
always have this nagging fear of collisions that I push to the back of
my mind.

The nagging feeling is justifiable. Nobody wants namespace collisions,
and they should be avoided by good management, not good luck. Sometimes
it’s easy to justify the addition of some or other method, sometimes it’s
not. So you can put your extra methods in a module and extend individual
objects with that module, instead of including it in classes. That
narrows your impact and allows you to keep track of what’s going on, and
should go some way to reducing that nagging feeling.

The main thing is that Ruby represents a significant step forward in
popular computing [1], and you need to embrace some danger to make that
progress. Fortunately, in one’s own programs, just embracing a tiny bit
of “danger” can make a large practical difference, e.g. modifiying the way
an object represents itself just for the purpose of a unit test.

Two benefits of Ruby’s approach that are probably underestimated by people
who, for whatever reason, like to cling to static typing:

  • the ability of library writers to create powerful frameworks,
    thus containing the “risk” in a way that can be studied, discussed
    and tested

  • the ability of everyday programmers to make small but meaningful
    improvements or bugfixes to the language or libraries, thus
    achieving independence and inspiring change based on working
    examples

At the end of the day, it’s better to solve problems pragmatically than
dogmatically :slight_smile: I look forward to reading your article.

Curious Tom

Cheers,
Gavin

[1] The groundwork was done by LISP, Smalltalk, Perl et al, but that does
not diminish Ruby at all.

PS. I am launching a project that consolidates popular extensions to the
standard classes. Look at project “extensions” on RubyForge if you’re
interested. The CVS will hopefully be there within 7 days. A release
will be a few more weeks. This is inspired by that nagging feeling.
Instead of implementing common modifications in my code, I can rely on a
reference implementation that is documented and tested.

Hi –

I am working on an article on the subject of implementing dynamically typed
languages on the .net CLR. In .net Types are immutable, ie. once defined
they cannot be changed. Writing about this I needed to cover the problem of
namespace collisions. Most modern languages including ruby has introduced
namespaces to alleviate the namespace collision problem, but the convention
of adding your own methods to existing classes reintroduces the problem.

Is ruby merely being pragmatic by allowing you to do this, because it seldom
causes any real problems? Or is it inherently wrong and should not be
permitted by the language/object model?

How do you feel about this feature. Would it be a big loss if ruby didn’t
support it? My own feelings are ambivalent. I have found myself adding
features to Time, Enumerable, Module and when I do it I always appreciate
how nice it is that the feature is where it belongs, but I always have this
nagging fear of collisions that I push to the back of my mind.

There’s been debate on the merits (or otherwise) of changing core
classes; see for example http://www.ruby-talk.org/81923 (Paul Brannan)
for some reflections on this.

But if I’m reading your question correctly, you’re asking generally
about the language design which allows dynamic modifications of any
class, core or otherwise. If so, then you’re asking about a complete
transformation in the design of the language… so I doubt you’ll get
too many Ruby programmers who think this would not be a big loss :slight_smile:
At least, speaking for myself, a language that was sort of Ruby-ish in
appearance but redesigned to be non-dynamic would not interest me.

Or did you mean some arrangement whereby core classes were frozen but
others were not? I’m not sure how/whether that would/could work, and
I personally don’t think it would be desireable at all.

David

···

On Fri, 26 Sep 2003, Thomas Sondergaard wrote:


David Alan Black
home: dblack@superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

Thomas Sondergaard wrote:

Is ruby merely being pragmatic by allowing you to do this, because it seldom
causes any real problems? Or is it inherently wrong and should not be
permitted by the language/object model?

How do you feel about this feature. Would it be a big loss if ruby didn’t
support it? My own feelings are ambivalent. I have found myself adding
features to Time, Enumerable, Module and when I do it I always appreciate
how nice it is that the feature is where it belongs, but I always have this
nagging fear of collisions that I push to the back of my mind.

I like the freedom, and I have yet to experience any problem with it.
The benefits far outweigh the concerns, and I think that the concerns –
along with their solutions (ala Java) – stretch too far (although I
don’t doubt people have their stories here and there). Further, I
simply don’t like a language telling me that I can’t do something
because it may be unsafe.

Sean O'Dell

I also look forward to reading the article. Your question also gives me
a chance to post a quote I ran across the other day (which I’m certain
is familiar to many, but is new to me):

“[M]any computer scientists have fallen into the trap of trying to
define languages like George Orwell’s Newspeak, in which it is
impossible to think bad thoughts. What they end up doing is killing
the creativity of programming.”
Larry Wall
http://www.wall.org/~larry/keynote/keynote.html

The above expresses my own thoughts as to the language. On the object
model question, I agree with the views of others that you do have to be
careful.

Regards,

Mark

···

On Thursday, September 25, 2003, at 09:04 PM, Thomas Sondergaard wrote:

[snip]

Or is it inherently wrong and should not be
permitted by the language/object model?

[snip]

W liście z pią, 26-09-2003, godz. 03:04, Thomas Sondergaard pisze:

Most modern languages including ruby has introduced
namespaces to alleviate the namespace collision problem, but the convention
of adding your own methods to existing classes reintroduces the problem.

Is ruby merely being pragmatic by allowing you to do this, because it seldom
causes any real problems? Or is it inherently wrong and should not be
permitted by the language/object model?

For me it’s essential that you can add new generic functions which
dispatch on old types, and that you can add new types on which old
generic functions dispatch. I refuse to like languages which don’t
allow both.

It’s not essential that the language is object oriented though, and
I don’t like being forced to put a name into a shared namespace. The
traditional OO style also allows to dispatch on one parameter only.

So, in Ruby it’s an essential feature with a bad side effect. I don’t
like how it is done (that you “add a method to a class” and risk name
clashes), but it’s great that it can be done at all.

Languages which can do both without the namespace issue: Lisp (CLOS),
Dylan, and to some extent Haskell, Clean and Mercury (where the dispatch
is limited and usually can be resolved statically).

···


__("< Marcin Kowalczyk
__/ qrczak@knm.org.pl
^^ Blog człowieka poczciwego.

“Thomas Sondergaard” thomas@FirstNameGoesHereSondergaard.com schrieb im
Newsbeitrag news:3f738d97$0$48913$edfadb0f@dtext02.news.tele.dk…

I am working on an article on the subject of implementing dynamically
typed
languages on the .net CLR. In .net Types are immutable, ie. once defined
they cannot be changed. Writing about this I needed to cover the problem
of
namespace collisions. Most modern languages including ruby has
introduced
namespaces to alleviate the namespace collision problem, but the
convention
of adding your own methods to existing classes reintroduces the problem.

Is ruby merely being pragmatic by allowing you to do this, because it
seldom
causes any real problems? Or is it inherently wrong and should not be
permitted by the language/object model?

How do you feel about this feature. Would it be a big loss if ruby
didn’t
support it? My own feelings are ambivalent. I have found myself adding
features to Time, Enumerable, Module and when I do it I always
appreciate
how nice it is that the feature is where it belongs, but I always have
this
nagging fear of collisions that I push to the back of my mind.

It would definitely be a loss for me. A typical development cycle
involves using irb to try things out and redefine methods if the old
definition didn’t work out. So it’s crucial for this development style.
It makes things go faster because you can reapply methods on existing
state which you don’t have to recreate during each debugging / development
cycle.

Also, as I leared recently, this seems to be a typical develpment style
with Lisp, too. Lisp goes even further in that it provides for
recompilation of functions to machine code from within a running system!
See here for an example report that emphasises modification of a running
system (Chapter 9)
http://www.ess.stsci.edu/psdb/spike/spike-wg/psflang-report.pdf

Kind regards

robert

I’m generally a static typing kind of guy, but have been trying to get into
the Ruby mindset as well. If Java or C# types were mutable (if it were even
possible), it would horrify me. I use those languages because I value the
rigidity of the compile-time checks and mutable types would totally
undermine that.

But I use Ruby when I value productivity over compile-time checking, so I
don’t think it would be an appropriate tradeoff to sacrifice the ability to
dynamically add methods. It’s harder to break something without knowing it
in Java than in Ruby, but it’s just so much faster to make something work in
Ruby. I really value having both at my disposal.

This feature makes porting or refactoring code in Ruby a dream.

Take this code, for example:

class Module
private
def move_class_methods (cls, *attrs)
attrs.each {|attr|
module_eval(<<-EOS)
def self.#{attr}(*args)
$stderr.puts "WARNING: #{cls}.#{attr} called from " + caller[0]
#{cls}.#{attr}(*args)
end
EOS
}
end
end

It allows you to easily redefine/move class methods from one class
to another:

class OldLocation
move_class_methods(NewLocation, :foo)

def bar
return self.foo(1, 2)
end
end

class NewLocation
def self.foo(x, y)
return x * y + y ** 2 - 3
end
end

You could write similar code to aid in refactoring instance methods.

···

Thomas Sondergaard (thomas@FirstNameGoesHereSondergaard.com) wrote:

How do you feel about this feature. Would it be a big loss if ruby didn’t
support it?


Eric Hodel - drbrain@segment7.net - http://segment7.net
All messages signed with fingerprint:
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04

Chad Fowler chad@chadfowler.com writes:

If not for this feature, I might not have ended up staying with Ruby when
I started learning it several years ago. It’s a unifying part of the
whole dynamic feeling and philosophy of the language. Ruby without this
feature would cease to be Ruby to me.

I agree completely on this topic. I just can’t express how big a
selling point this feature was to me. It has made writing unit tests
a dream I can override functions in modules like PAM so that they
can run in automated tests.

– Samuel

Is ruby merely being pragmatic by allowing you to do this, because it

seldom

causes any real problems? Or is it inherently wrong and should not be

permitted by the language/object model?

Why would it be in Ruby (and other languages) if it were inherently wrong?
Sounds like kind of a loaded question.

Hey, be fair! While there are two sentences and two question marks it is
really only one question and the phrasing merely indicates two points of
views - pragmatic or simply wrong! Being a rubyist myself, I don’t think it
is inherently wrong, I think it is pragmatic!

Thomas

“[M]any computer scientists have fallen into the trap of trying to
define languages like George Orwell’s Newspeak, in which it is
impossible to think bad thoughts. What they end up doing is killing
the creativity of programming.”
Larry Wall
http://www.wall.org/~larry/keynote/keynote.html

I really like that! However, there is another thing to consider. In non-open
source compiled languages resolving a namespace conflict is a bigger issues
than it is with open source scripts. After all, if it bites you change it,
right?

Might partially explain why languages like ruby, python etc have made
different design decisions here.

Cheers,

Thomas

Excellent idea. Two questions, though - how do you define popularity,
and how do you avoid bloat?

martin

···

Gavin Sinclair gsinclair@soyabean.com.au wrote:

PS. I am launching a project that consolidates popular extensions to the
standard classes. Look at project “extensions” on RubyForge if you’re
interested. The CVS will hopefully be there within 7 days. A release
will be a few more weeks. This is inspired by that nagging feeling.
Instead of implementing common modifications in my code, I can rely on a
reference implementation that is documented and tested.

StandardClassExtensions on the wiki lists several good ones, as many
people know. Obviously, not all are essential, but it’s a damn good
place to start. It’s as close as I get to defining popularity.

Avoiding bloat is a tricky issue, of course. I start with the ones I
have implemented time and again (groan) in my code, and then add the
ones I’ve wanted to do but couldn’t be bothered (e.g. Class#autoinit).

RubyForge surveys might be a good tool here.

Gavin

···

On Saturday, September 27, 2003, 1:05:48 AM, Martin wrote:

Gavin Sinclair gsinclair@soyabean.com.au wrote:

PS. I am launching a project that consolidates popular extensions to the
standard classes. Look at project “extensions” on RubyForge if you’re
interested. The CVS will hopefully be there within 7 days. A release
will be a few more weeks. This is inspired by that nagging feeling.
Instead of implementing common modifications in my code, I can rely on a
reference implementation that is documented and tested.

Excellent idea. Two questions, though - how do you define popularity,
and how do you avoid bloat?

I can think of two things that should be there: #map_with_index and number
formatting, since they appear every so often. Other examples exist, I am
sure, but seeing what extensions are listed on the RubyGarden wiki would be
a good start.

IMO, the way to avoid bloat is like this:

ext.rb # loads everything
ext/numeric
ext/numeric.rb # loads all extensions to Numeric classes
ext/numeric/format.rb
ext/enumerable
ext/enumerable.rb # loads all extensions to Enumerable
ext/enumerable/map.rb

The file ext/numeric/format.rb could contain the number formatting routine I
wrote and is currently on the RubyGarden wiki. If there are other numeric
formatting routines, they could be put there as well. The file
ext/enumerable/map.rb could contain #map_with_index.

What do you think?

-austin

···

On Sat, 27 Sep 2003 00:05:48 +0900, Martin DeMello wrote:

Gavin Sinclair gsinclair@soyabean.com.au wrote:

PS. I am launching a project that consolidates popular extensions to
the standard classes. Look at project “extensions” on RubyForge if
you’re interested. The CVS will hopefully be there within 7 days. A
release will be a few more weeks. This is inspired by that nagging
feeling. Instead of implementing common modifications in my code, I can
rely on a reference implementation that is documented and tested.
Excellent idea. Two questions, though - how do you define popularity, and
how do you avoid bloat?


austin ziegler * austin@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.09.26
* 12.01.15

In article 87wubws1b2.fsf@alieniloquent.com,

···

Samuel Tesla samuel@alieniloquent.com wrote:

Chad Fowler chad@chadfowler.com writes:

If not for this feature, I might not have ended up staying with Ruby when
I started learning it several years ago. It’s a unifying part of the
whole dynamic feeling and philosophy of the language. Ruby without this
feature would cease to be Ruby to me.

I agree completely on this topic. I just can’t express how big a
selling point this feature was to me. It has made writing unit tests
a dream I can override functions in modules like PAM so that they
can run in automated tests.

This is an interesting idea, can you provide some more details?
Do you mean that you’re stubbing some methods which might not work in your
testing environment/context?

Phil

PS. I am launching a project that consolidates popular extensions to
the standard classes. Look at project “extensions” on RubyForge if
you’re interested. The CVS will hopefully be there within 7 days. A
release will be a few more weeks. This is inspired by that nagging
feeling. Instead of implementing common modifications in my code, I can
rely on a reference implementation that is documented and tested.

Excellent idea. Two questions, though - how do you define popularity, and
how do you avoid bloat?

I can think of two things that should be there: #map_with_index and number
formatting, since they appear every so often. Other examples exist, I am
sure, but seeing what extensions are listed on the RubyGarden wiki would be
a good start.

#map_with_index is there now. Well, on my computer anyway.

IMO, the way to avoid bloat is like this:

ext.rb # loads everything
ext/numeric
ext/numeric.rb # loads all extensions to Numeric classes
ext/numeric/format.rb
ext/enumerable
ext/enumerable.rb # loads all extensions to Enumerable
ext/enumerable/map.rb

The file ext/numeric/format.rb could contain the number formatting routine I
wrote and is currently on the RubyGarden wiki. If there are other numeric
formatting routines, they could be put there as well. The file
ext/enumerable/map.rb could contain #map_with_index.

What do you think?

-austin

What I have chosen is:

require “extensions/all” # everything
require “extensions/enumerable”
require “extensions/io”
require “extensions/string”

Since these deal exclusively with modifications to core classes, it
makes sense to me that the things you load should be named after them.
It doesn’t make sense to me that finer granularity is required,
because: (a) it’s too much to remember and too much hassle to look up;
and (b) the extensions shouldn’t be so numerous as to require it.

However, you are the second person to propose what you did, so I’ll
have to give it some thought.

BTW, the extension package is conservative. If an intended method
already exists, it emits a warning and doesn’t overwrite the
method. Also, an exception is thrown if a method is claimed to be
implemented but isn’t.

Gavin

···

On Saturday, September 27, 2003, 2:10:42 AM, Austin wrote:

On Sat, 27 Sep 2003 00:05:48 +0900, Martin DeMello wrote:

Gavin Sinclair gsinclair@soyabean.com.au wrote:

Austin Ziegler wrote:

I can think of two things that should be there: #map_with_index and number
formatting, since they appear every so often. Other examples exist, I am
sure, but seeing what extensions are listed on the RubyGarden wiki would be
a good start.

Some suggestions.

The Ruby Way has some odds and ends that might be useful here. Use
them freely if you wish, but I think a comment saying which ones came
from there would be appropriate. Source is in the RAA.

Also, nil_or_empty? comes up from time to time. I sympathize with the
need for it, but I prefer the name null?. These expressions would all
be true:

nil.null?
[].null?
"".null?
0.null?    # I'm uncertain about this one.

I like the “mapf” idea someone had (map function). Example:
Instead of
array.map {|x| x.capitalize }
we could do
array.mapf(:capitalize)

I like having odd? and/or even? methods for numbers, but that’s just
me.

Cheers,
Hal

Florian Gross found one way to do

array.map(&:capitalize)

(defining Symbol#to_proc), if you can stand the line noise.

···

On Sat, Sep 27, 2003 at 02:19:15AM +0900, Hal Fulton wrote:

I like the “mapf” idea someone had (map function). Example:
Instead of
array.map {|x| x.capitalize }
we could do
array.mapf(:capitalize)

I like having odd? and/or even? methods for numbers, but that’s just
me.


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

LOAD “LINUX”,8,1
– Topic on #LinuxGER