"stereotyping"

Sean O’Dell wrote:

No has to just do it. But when people ask for something, it gets
annoying to
hear over and over “but why but why but why.” Why is not an
appropriate
question anymore.

It might not be appropriate to you because you seem to feel that
there
have been answers to it already.

I’m guessing here that the people that ask now either haven’t
accepted
that the answers that have been given to be valid.

···

Do you Yahoo!?
Free Pop-Up Blocker - Get it now
http://companion.yahoo.com/

Sean O’Dell wrote:

No has to just do it. But when people ask for something, it gets

annoying to

hear over and over “but why but why but why.” Why is not an

appropriate

question anymore.

It might not be appropriate to you because you seem to feel that
there
have been answers to it already.

I’m guessing here that the people that ask now either haven’t
accepted
that the answers that have been given to be valid.

When people give their reasons, that’s it. That’s the reason. The line of
questioning tends to go like this:

Q = random programmer questioner
A = Ruby community answerer

Q: Does Ruby have type checking?

Q: I need type checking. Will it ever have type checking?

answer is that you don’t need it. If we figure it out, then your needs will
be considered valid. Why do you need type checking anyway?

Q: Because we find it helps us control our large team projects.

offer more evidence?

Q: Okay. We have to look to code quite often in lieu of project documentation,
and normally we look to the description of classes, and the declarations of
function parameters to determine how to make calls and to understand how
classes are designed that are unfamiliar to some of the programmers on the
team. Type checking would help us to know what parameters are used by
certain methods at-a-glance, which saves us from having to spend time
studying source code to figure things out.

Perhaps if you gave us another reason.

Q: Okay. When an unsuitable object is passed to a method, and that method
tries to call a method of the object that either doesn’t exist or has a
different number of parameters than expected, an error occurs deep inside the
method and it’s tedious figuring out how to fix what went wrong. Some form
of type checking would help us recognize our mistakes faster.

C-extension object, so that should be good enough for you. Perhaps another
reason would convince us.

Q: Gee, alright, but I’m running out of reasons.

a sufficient quantity of reasons, you could argue indefinitely, and therefore
win the argument. The fact that you are running out of reasons and are
leaving the discussion indicates that perhaps you don’t really know what you
need. The Great Ziegler knows what you need. Or would you prefer to
continue discussing this?

Q: Huh? Okay, I think. Uhm … well, we’ve been pushing to use Ruby on some
of our projects for a long time here, and the higher ups aren’t crazy about
Ruby for a couple of reasons, and one of them is type checking. See, they
used to be programmers and they still know a lot about what we do, and they
also know the value of type checking, but they’re not quite as willing as we
are to experiment a little. I think they may have a lot of money sunk into
the company or something. Just for the sake of argument, to promote its use,
having any form of type checking, even if it’s completely circumventable,
would give us a way to assuage our superiors that Ruby would not become an
unmanagable tangle.

laughed at others before. HA HA! Don’t try the pointy-haired boss argument
with us, apprentice. Away with you now! To Smalltalk or Python, we care
not! At least until we figure out how to implement some form of type
checking that we’re satisfied is strict enough to crack diamonds on, then you
may return and we will gladly accept all of your arguments.

Okay, I’m just jabbing now. But in all seriousness, it really sounds like the
message around here is: “we don’t want type checking, but we’re trying to
figure out how to implement it, and so far we have rejected some attempts
because they were too soft for us because while we’re really into no typing
at all, when we do implement type checking, it must be super-rigorous or not
at all, and until then your arguments for why you need type checking are
completely beneath contempt, although if we do ever figure out how to
implement a super-rigorous type checking system, then we’ll give you what
you’ve been asking for.”

Sean O'Dell
···

On Thursday 20 November 2003 11:07 am, Michael Campbell wrote:
A: No.
A: Maybe, but we can’t figure out how to do it right now so our official
A: I don’t agree that it helps you control your large team projects. Can you
A: We always just read the source code, so that should be good enough for you.
A: We always just read the source code where the error occured, unless it’s a
A: Thus you are close to realizing the friviolity of your request. If you had
A: We have heard that argument before, and we will laugh at you now as we have

Okay. I’m going to respond to this and then I’m going to stop. This
is getting stupid because someone has decided to take things
personally and use strawmen and ad hominem attacks instead of reason
and logic.

Q: Does Ruby have type checking?
A: No.

Incorrect. Ruby does have type checking. It’s not name-based type
checking or static type checking or even the ability to enforce
types in method signatures, but Ruby is a strongly, dynamically
typed language.

Q: I need type checking. Will it ever have type checking?
A: Maybe, but we can’t figure out how to do it right now so our
official answer is that you don’t need it. If we figure it out,
then your needs will be considered valid. Why do you need type
checking anyway?

Incorrect. Ruby may provide optional signature specification in
the future. Many people are unconvinced that it’s necessary.
Especially since that there’s alternatives that are better (unit
testing; DbC).

Q: Because we find it helps us control our large team projects.
A: I don’t agree that it helps you control your large team
projects. Can you offer more evidence?

Fweeep! Foul on O’Dell! Introduction of circular argument and
misrepresentation of discussion. The question asked was how it
helps you control your large team projects. That question has not
been clearly answered by you, although Thien did answer it – and he
was given what options Ruby does offer (not counting rdoc).

Q: Okay. We have to look to code quite often in lieu of project
documentation, and normally we look to the description of
classes, and the declarations of function parameters to
determine how to make calls and to understand how classes are
designed that are unfamiliar to some of the programmers on the
team. Type checking would help us to know what parameters are
used by certain methods at-a-glance, which saves us from having
to spend time studying source code to figure things out.
A: We always just read the source code, so that should be good
enough for you. Perhaps if you gave us another reason.

Again, an improper representation to both the question and the
answer. Opening a .h file is no different than opening the source.
You say you do Java as well as C++, right? There are no .h files,
and opening a .java file gives you the source as well. The same
applies to Ruby.

Q: Okay. When an unsuitable object is passed to a method, and that
method tries to call a method of the object that either doesn’t
exist or has a different number of parameters than expected, an
error occurs deep inside the method and it’s tedious figuring
out how to fix what went wrong. Some form of type checking
would help us recognize our mistakes faster.
A: We always just read the source code where the error occured,
unless it’s a C-extension object, so that should be good enough
for you. Perhaps another reason would convince us.

Third foul! Strawman on the floor. This differs not at all from the
situation from C++ or Java.

Q: Gee, alright, but I’m running out of reasons.
A: Thus you are close to realizing the friviolity of your request.
If you had a sufficient quantity of reasons, you could argue
indefinitely, and therefore win the argument. The fact that you
are running out of reasons and are leaving the discussion
indicates that perhaps you don’t really know what you need. The
Great Ziegler knows what you need. Or would you prefer to
continue discussing this?

Fourth foul – stooping to personal attacks.

I’m going to ignore the rest of your diatribe, because it’s even
less reasoned than the above.

Good bye, Mr O’Dell. Continue using Ruby, or not. Don’t pretend that
name checking is even remotely the same as type checking or
interface guarantee. Half-promises are worse than no promises at
all.

-austin

···

On Fri, 21 Nov 2003 04:44:02 +0900, Sean O’Dell wrote:

austin ziegler * austin@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.11.20
* 15.28.36

A: I don’t agree that it helps you control your large team projects. Can you
offer more evidence?

Q: Okay. We have to look to code quite often in lieu of project documentation,
and normally we look to the description of classes, and the declarations of
function parameters to determine how to make calls and to understand how
classes are designed that are unfamiliar to some of the programmers on the
team. Type checking would help us to know what parameters are used by
certain methods at-a-glance, which saves us from having to spend time
studying source code to figure things out.

You’re assuming the guy who wrote the library methods used this
optional ‘interface’ extension. If he cant even be bothered to
document his library, why would he do that? Wouldnt a class
need to know in advance that it would be passed to an interface-aware
method?

This seems to be using interface implementation to flag a class

as suitable for use in a particular way. Thats just as much an agreed
protocol between the method and the argument as a respond_to? approach,
but respond_to? doesnt require such a fundamental change to the
language (and thats what it would have to be, if it was really to be
useful - I dont think an optional feature would please anyone).

D’d certainly like extensions to respond_to? so I could check argument
type and count (think someone posted that earlier?) - but that could
be mixed in, so I wouldnt be imposing this on those who didnt want it.

Q: Okay. When an unsuitable object is passed to a method, and that method
tries to call a method of the object that either doesn’t exist or has a
different number of parameters than expected, an error occurs deep inside the
method and it’s tedious figuring out how to fix what went wrong. Some form
of type checking would help us recognize our mistakes faster.

But again, its less hassle to document your API than to do rigourous
argument checking.

It seemed like you were more interested in a way to know how an API
will use your object. Why not send in a probe?

Pass a custom object in that has a method_missing? method that does
a ludicrous amount of debugging of how its called. That would tell you
how an API is actually using your object, what methods it calls and how.

Thats a back of a beermat approach, but I reckon that coupled with
some good unit testing frees you up from relying on the kindness of
strangers, at least a little.
Even if it only tests method name and argument count, that gives you all
an interface would, without any changes to the API you are using.

The difference is API probing can be done with existing mechanisms,
optionally and more importantly, they dont require both sides
of the method to play by the rules. Or reach a consensus :slight_smile:

Q: Gee, alright, but I’m running out of reasons.

A: Thus you are close to realizing the friviolity of your request.

[snip]

The pissing contest is getting old now, and its just drawing out a
long thread to a longer one.

I think I share some of both sides viewpoint, but I dont want a
Java’ed Ruby, and it seems that this interface idea is coming from
that angle.

···


Boling’s postulate:
If you’re feeling good, don’t worry. You’ll get over it.
Rasputin :: Jack of All Trades - Master of Nuns

In article 200311201143.59231.sean@celsoft.com,

: Q: Okay. We have to look to code quite often in lieu of project
: documentation, and normally we look to the description of
: classes, and the declarations of function parameters to
: determine how to make calls and to understand how classes are
: designed that are unfamiliar to some of the programmers on the
: team. Type checking would help us to know what parameters are
: used by certain methods at-a-glance, which saves us from having
: to spend time studying source code to figure things out.

Of course, the simple answer to that is to use
properly-descriptive parameter names.

I know. I agree, too. Doesn’t happen as often as I wish.

It generally doesn’t matter what something is made of–what
matters is what it is.

I disagree here. It’s a nomenclature issue, I suppose, but I am personally
only concerned about what an object does, not what it is. I can’t use an
object passed to me that is a string, if it gives me no way to make use of
it. I need access, so to me the most important thing is what it does.

Also, objects do things in different ways. I could have an object that is a
Report object. If it uses text files, great, that’s easy. If it uses MySQL,
okay, let me go set up a table it can use somewhere, or make the connection
to an existing one. It’s what it does that determines there is an issue.

But, then again, you can say that with something like an interface, you’re
making both statements. Interfaces are immutable, and you can’t partially
implement one. When fulfilled, you can say “this object is this” as well as
“this object does this” pretty clearly.

In other words, if it’s Java you’re looking for, you know where to
find it. Ruby “market share” isn’t something I think is even
worth considering. It’s a wonderfully handy tool and it makes my
life easier, and that’s all I ask of it.

Yeah, I know people feel that way. The problem I have with that point of view
is that not caring about market share sounds a lot like not caring about
anyone outside the Ruby community. Getting programmers to use Ruby is not
about gaining market share, it’s about being able to say “Ruby is here to be
the best programming language we can make it, no more and no less.” If you
decide that features from Java aren’t worth putting in simply because Java
has it, that’s prejudice that I don’t think is at the heart of Ruby. Ruby is
about adopting what works. Interfaces work in lots of places. Directing
people away from Ruby to get a feature like this doesn’t seem to me what the
Ruby community historically has done. It’s packed with lots of cool features
taken from here and there. If interfaces can be done with finesse and makes
Ruby stronger, it should be adopted. As things progress, it seems like we’ve
found a way to do it without a lot of back-breaking work which doesn’t break
Ruby now, and which also doesn’t look like a third eye growing out of its
elbow. It could be just another quietly tucked away feature that gets used
by some, ignored by others.

I don’t care what management thinks of Ruby: I only care about
getting the job done. When something needs to be done, I use
whatever tools are at my disposal and are most effective. Ruby
doesn’t need to be “promoted”; it just needs to be used. Let it
promote itself by demonstrating results. Leave the bulleted
feature lists to the likes of Microsoft Word.

Being able to put something on a feature list is not a reason to discount it,
though, either. It has value in itself. If people have been asking for
something, and you’ve found a cool way to do it that fits right in with the
language, then you put it on the list. But that’s not WHY you do it, to put
it on the list. You do it because there are real reasons for it, and the
reward is yet another really cool feature on the list.

Ask yourself: why does Ruby have iterators? You could do loops lots of other
ways. It’s there because it was the coolest, smoothest way that could be
conceived of at the time and it endures today.

This is what I think we can achieve. Something cool and smooth and which will
endure and will make Ruby just that one little bit better.

Sean O'Dell
···

On Friday 21 November 2003 02:42 pm, Dave Brown wrote:

Sean O’Dell sean@celsoft.com wrote:

Whatever you say Ziegler.

Sean O'Dell
···

On Thursday 20 November 2003 12:28 pm, Austin Ziegler wrote:

Okay. I’m going to respond to this and then I’m going to stop. This
is getting stupid because someone has decided to take things
personally and use strawmen and ad hominem attacks instead of reason
and logic.

On Fri, 21 Nov 2003 04:44:02 +0900, Sean O’Dell wrote:

Q: Does Ruby have type checking?
A: No.

Incorrect. Ruby does have type checking. It’s not name-based type
checking or static type checking or even the ability to enforce
types in method signatures, but Ruby is a strongly, dynamically
typed language.

Q: I need type checking. Will it ever have type checking?
A: Maybe, but we can’t figure out how to do it right now so our
official answer is that you don’t need it. If we figure it out,
then your needs will be considered valid. Why do you need type
checking anyway?

Incorrect. Ruby may provide optional signature specification in
the future. Many people are unconvinced that it’s necessary.
Especially since that there’s alternatives that are better (unit
testing; DbC).

Q: Because we find it helps us control our large team projects.
A: I don’t agree that it helps you control your large team
projects. Can you offer more evidence?

Fweeep! Foul on O’Dell! Introduction of circular argument and
misrepresentation of discussion. The question asked was how it
helps you control your large team projects. That question has not
been clearly answered by you, although Thien did answer it – and he
was given what options Ruby does offer (not counting rdoc).

Q: Okay. We have to look to code quite often in lieu of project
documentation, and normally we look to the description of
classes, and the declarations of function parameters to
determine how to make calls and to understand how classes are
designed that are unfamiliar to some of the programmers on the
team. Type checking would help us to know what parameters are
used by certain methods at-a-glance, which saves us from having
to spend time studying source code to figure things out.
A: We always just read the source code, so that should be good
enough for you. Perhaps if you gave us another reason.

Again, an improper representation to both the question and the
answer. Opening a .h file is no different than opening the source.
You say you do Java as well as C++, right? There are no .h files,
and opening a .java file gives you the source as well. The same
applies to Ruby.

Q: Okay. When an unsuitable object is passed to a method, and that
method tries to call a method of the object that either doesn’t
exist or has a different number of parameters than expected, an
error occurs deep inside the method and it’s tedious figuring
out how to fix what went wrong. Some form of type checking
would help us recognize our mistakes faster.
A: We always just read the source code where the error occured,
unless it’s a C-extension object, so that should be good enough
for you. Perhaps another reason would convince us.

Third foul! Strawman on the floor. This differs not at all from the
situation from C++ or Java.

Q: Gee, alright, but I’m running out of reasons.
A: Thus you are close to realizing the friviolity of your request.
If you had a sufficient quantity of reasons, you could argue
indefinitely, and therefore win the argument. The fact that you
are running out of reasons and are leaving the discussion
indicates that perhaps you don’t really know what you need. The
Great Ziegler knows what you need. Or would you prefer to
continue discussing this?

Fourth foul – stooping to personal attacks.

I’m going to ignore the rest of your diatribe, because it’s even
less reasoned than the above.

Good bye, Mr O’Dell. Continue using Ruby, or not. Don’t pretend that
name checking is even remotely the same as type checking or
interface guarantee. Half-promises are worse than no promises at
all.

A: I don’t agree that it helps you control your large team projects. Can
you offer more evidence?

Q: Okay. We have to look to code quite often in lieu of project
documentation, and normally we look to the description of classes, and
the declarations of function parameters to determine how to make calls
and to understand how classes are designed that are unfamiliar to some of
the programmers on the team. Type checking would help us to know what
parameters are used by certain methods at-a-glance, which saves us from
having to spend time studying source code to figure things out.

You’re assuming the guy who wrote the library methods used this
optional ‘interface’ extension. If he cant even be bothered to
document his library, why would he do that? Wouldnt a class
need to know in advance that it would be passed to an interface-aware
method?

Because this is far simpler, and once started, cannot lapse. When he tests
his code, if he forgot to update the interface description, he’ll get errors
that notify him. You can be mostly assured that the interface description
you see from a library is up-to-date, unlike documentation.

Convenience is a mighty strong catalyst for action.

This seems to be using interface implementation to flag a class
as suitable for use in a particular way. Thats just as much an agreed
protocol between the method and the argument as a respond_to? approach,
but respond_to? doesnt require such a fundamental change to the
language (and thats what it would have to be, if it was really to be
useful - I dont think an optional feature would please anyone).

The difference is: simply stating a class’ purpose is easy. You do it once
and that’s pretty much it. As you develop, though, the interface changes.
Keeping up with specific method documentation is much more labor-intensive.
If you have an interface description that you had to adhere to, you wouldn’t
have the option of falling behind on updating it. Your code simply wouldn’t
work until you did.

D’d certainly like extensions to respond_to? so I could check argument
type and count (think someone posted that earlier?) - but that could
be mixed in, so I wouldnt be imposing this on those who didnt want it.

You can already do that now in Ruby, but perhaps an interface mechanism could
make that easier.

Q: Okay. When an unsuitable object is passed to a method, and that method
tries to call a method of the object that either doesn’t exist or has a
different number of parameters than expected, an error occurs deep inside
the method and it’s tedious figuring out how to fix what went wrong.
Some form of type checking would help us recognize our mistakes faster.

But again, its less hassle to document your API than to do rigourous
argument checking.

No, it’s more hassle. To update a document, you have to open a different
file, and if you make a typo or just plain write it wrong, there is nothing
to stop you from doing so. Interfaces can be described in the same source
file as your class definition, so it’s easy to find and update, plus, you
can’t update it wrong, or your code gives you errors.

It seemed like you were more interested in a way to know how an API
will use your object. Why not send in a probe?

Because probes can sometimes cause damage, and the errors reported deep inside
may not be easily understood. It’s a hit-or-miss proposition in there; some
people have no trouble diving in and reading someone else’s code. I do it as
a last resort because I find it’s a terribly inefficient way to debug.

Thats a back of a beermat approach, but I reckon that coupled with
some good unit testing frees you up from relying on the kindness of
strangers, at least a little.

I just don’t think that probing and unit testing alone does quite what I’m
proposing. My proposal provides a lot of assurance, a lot of understanding
right up-front, and I think will just plain make a heck of a lot of people
happy.

Even if it only tests method name and argument count, that gives you all
an interface would, without any changes to the API you are using.

Well, since classes can implement interfaces, the test can also check that
methods are being passed object that fulfill the interface contract. So, a
sort of type checking can be performed.

The difference is API probing can be done with existing mechanisms,
optionally and more importantly, they dont require both sides
of the method to play by the rules. Or reach a consensus :slight_smile:

We have probing already, and it functions for lots of people. Not everyone.
And not to the degree of ease and clarity some would like.

Q: Gee, alright, but I’m running out of reasons.

A: Thus you are close to realizing the friviolity of your request.

The pissing contest is getting old now, and its just drawing out a
long thread to a longer one.

This was actually the start of it, as far as I know. You must have gotten
this post out of order, or read into things previously said that I didn’t
catch.

I think I share some of both sides viewpoint, but I dont want a
Java’ed Ruby, and it seems that this interface idea is coming from
that angle.

It is, it most certainly is, except for two things. One, it’s not a
requirement, you can ignore it and never have to deal with it. Two, classes
that claim to implement an interface can still work dynamically and can add
their own methods. It’s just an optional feature, not a whole new system
being imposed globally.

Sean O'Dell
···

On Friday 21 November 2003 12:48 pm, Rasputin wrote:

From: Rasputin [mailto:rasputin@idoru.mine.nu]
It seemed like you were more interested in a way to know how an API
will use your object. Why not send in a probe?

Pass a custom object in that has a method_missing? method that does
a ludicrous amount of debugging of how its called. That would tell you
how an API is actually using your object, what methods it calls and how.

Below is a quick hack to do that. Needs work. Needs redirection of IO. But
its kinda cute… Has issues with side effects, of course, and printing
crapola all over the place.

Usage:

ins = ObjectProbe::Inspector.new( SomeObject.new )

ins.probe

module ObjectProbe

class Inspector
def initialize( object )
@object = object
end

def target_class
  @object.class
end

def target_methods
  @object.methods - Object.new.methods
end

def probe
  puts "Probing: #{target_class}"
  target_methods.each do | method |
    meta = MetaMethod.new( method.intern, @object )
    print "  Method: #{method}( "
    meta.args.each do | arg |
      print "[ #{arg.___requires.join(', ')} ], "
    end
    puts
  end
end

end

class MetaMethod
def initialize( method, object )
@method = method
@object = object
end

def symbol
  @method
end

def arity
  m = @object.method( @method )
  m.arity
end

def args
  result = []
  arity.times { result << DummyArgument.new }
  begin
    @object.send( @method, *result )
  rescue
    puts $!.to_s
  end
  result
end

end

class DummyArgument
attr_reader :___requires

def initialize
  @___requires = []
end

def DummyArgument.clean_out_methods
  methods_list = Object.new.methods
  methods_list.each do | m |
    meth = m.intern
    # keep the important fns, and keep __send__ and __id__ to prevent

warnings.
next if( meth == :method_missing || meth == :send || meth ==
:id )
module_eval <<-“end_eval”
alias_method :#{meth.to_i}, #{meth.inspect}
def #{meth.id2name}(*args, &block)
method_missing( :#{meth}, *args )
#{meth.to_i}(*args, &block)
end
end_eval
end
end

def method_missing( symbol, *args )
  @___requires << symbol
end

clean_out_methods

end
end

In article 200311211505.55669.sean@celsoft.com,

: But, then again, you can say that with something like an interface,
: you’re making both statements. Interfaces are immutable, and you can’t
: partially implement one. When fulfilled, you can say “this object is
: this” as well as “this object does this” pretty clearly.

That’s the inverse of the Ruby Way.

If I want to be inclusive, I use less-specific features, I don’t
require things I talk to to adhere to large, and
often-unnecessary, APIs.

I agree, which is why for my own personal use, I’m going back to something
akin to what I wrote up in my first RCR. Simple type tag agreements.

Now it works on file handles, streams, arrays, regular strings,
and StringIO objects! It’s amazing how powerful you can make
something if you’re just careful about which interfaces you
choose. This is the kind of thing that makes people describe Ruby
as a “beautiful” language.

Yeah, and it’s great with built-in types because we know them to be somewhat
standard so we can depend on them. There’s no need for type checking when
there’s only a handful few types people could possibly pass in; just handle
them all, even if you just throw a nice error saying you don’t handle that
type.

It 's probably fair to say that the major audience for the
development of Ruby as a language is the Yukihiro Matsumoto
community. The fact that it’s useful to anyone else is merely our
good luck.

This sort of inward-focus has changed my view of Ruby. I suppose it’s this
sort of culture which will bear for us the next generation of programming
language, but it also has me backpedalling in a few areas. It’s good to
experiment and be different, though; it breeds ideas. Ruby is LOADED with
ideas.

Why should Person A do something that Person B suggests, which
otherwise doesn’t benefit Person A’s life, merely because Person B
thinks that Person C, an otherwise uninterested third party, might
be interested in Person A’s thing? I think that’s the whole point
behind this big war, which everyone (bar Matz himself) seems to be
overlooking.

It depends if Person A sees the truth in what Person B is saying, and if
Person A cares to interest Person C. Clearly, in this case, Person A (aka
Matz) does not care to interest Person C, whatever the truth might be.

: Getting programmers to use Ruby is not about gaining market
: share, it’s about being able to say “Ruby is here to be the best
: programming language we can make it, no more and no less.”

'scuse my bluntness, but to hell with that. Project managers
don’t care about theoretical features: they care about RESULTS.
The best way to promote Ruby isn’t to add a billion features to
the language; it’s to write great software in it, and to show that
the it’s great software.

What’s ironic here is that what they use in actual practice (the dominant
paradigm right now) is type checking. My proposal wasn’t to actually add
type checking to Ruby, but to convince project managers that there was a
sufficient mechanism to give them the advantages they seek with type
checking. Or at least, assuage their fears that leaving type checking behind
was a giant ball of hair ready to choke them and their budget.

For example: I’d wager that the biggest thing helping to promote
Python isn’t its OO capabilities, or its flexibility, or anything
like that. The single biggest thing promoting Python is BitTorrent.

Come up with something that gets Ruby as ubiquitous as BitTorrent
has made Python, and you won’t need to worry about interfaces or
any other managerial bullet-point list items.

But then, the goal here isn’t to promote Ruby. Ruby is for the Ruby
community, not everyone else.

Sean O'Dell
···

On Monday 24 November 2003 01:12 pm, Dave Brown wrote:

Sean O’Dell sean@celsoft.com wrote:

Sean O’Dell wrote:

But again, its less hassle to document your API than to do rigourous
argument checking.

No, it’s more hassle. To update a document, you have to open a different
file, and if you make a typo or just plain write it wrong, there is nothing
to stop you from doing so. Interfaces can be described in the same source
file as your class definition, so it’s easy to find and update, plus, you
can’t update it wrong, or your code gives you errors.

You always have to update documentation when you change something.
Having an interface checking
system doesn’t mean that you don’t have to document your code. So in
effect, having interfaces means
you have to update two different places when you make an interface
change (three, actually, if you
count the code that uses the interface), and there’s more things that
can get out of sync.

Besides, with systems like RDoc you can make all documentation
annotations in your source and
generate the documentation from there, so it’s really no more or less
convenient than having an
interface definition in your source, at least for documentation purposes.

  • Dan

Is this or something like it on the RAA? Perhaps a slightly more general
mechanism to proxy messages to the “real” object and call a
hook/callback?

···

“David Naseby” david.naseby@eonesolutions.com.au wrote:

Below is a quick hack to do that. Needs work. Needs redirection of IO.
But its kinda cute… Has issues with side effects, of course, and
printing crapola all over the place.


Greg McIntyre ======[ greg@puyo.cjb.net ]===[ http://puyo.cjb.net ]===

  • Sean O’Dell sean@celsoft.com [1144 19:44]:
    This seems to be using interface implementation to flag a class
    as suitable for use in a particular way. Thats just as much an agreed
    protocol between the method and the argument as a respond_to? approach,
    but respond_to? doesnt require such a fundamental change to the
    language (and thats what it would have to be, if it was really to be
    useful - I dont think an optional feature would please anyone).

The difference is: simply stating a class’ purpose is easy. You do it once
and that’s pretty much it. As you develop, though, the interface changes.
Keeping up with specific method documentation is much more labor-intensive.
If you have an interface description that you had to adhere to, you wouldn’t
have the option of falling behind on updating it. Your code simply wouldn’t
work until you did.

Right, but thats no different to enforcing a respond_to? and
arity check coupled with an assert. I’m not saying thats a better
way, just it gives you the same assurance (IMO) without
such a big change to the language.

But again, its less hassle to document your API than to do rigourous
argument checking.

No, it’s more hassle. To update a document, you have to open a different
file, and if you make a typo or just plain write it wrong, there is nothing
to stop you from doing so. Interfaces can be described in the same source
file as your class definition, so it’s easy to find and update, plus, you
can’t update it wrong, or your code gives you errors.

My main doubt about this is, unless I misunderstand it,
this only makes APIs easier to use if the author decides to
use interface declarations.
But the choice ‘to doc or not to doc’ is no different to
‘to interface or not to’ for a lazy sod (I speak as one myself).
Unless you enforce it across the language, which would get you
burnt at the stake, you’ve potentially forked the language and you may
not even see a benefit.

It seems to me that when working around lazy b*stards like

me, its easier to doc a third party library than to retrofit
interfaces onto it.

It seemed like you were more interested in a way to know how an API
will use your object. Why not send in a probe?

Because probes can sometimes cause damage, and the errors reported deep inside
may not be easily understood. It’s a hit-or-miss proposition in there; some
people have no trouble diving in and reading someone else’s code. I do it as
a last resort because I find it’s a terribly inefficient way to debug.

I agree, and I have found several promising APIs unusable because the
documentation was non-existent. My point was there are ways and means in
Ruby that the typed languages dont have, that feel more Rubyish than
a bolt-on feature.
In this case (investigating an alien object) we can verify an
object passed as an argument( respond_to? and arity checks) has methods
we expect, and callers of our methods can also see how methods they pass in
are being used by us (by use of a probe object).
I dont think an interface check can do any more. Admittedly someone has
written ‘this object is for Xing’ on it, but 99% of the time knowing there
is a method doX(objectA,objectB) does that job. There are edge cases
(using RMI systems, etc) but personally I’d prefer to dissect the remote
object rather than trust a flag on it if I didnt trust the source - and if
I knew where it came from, I’d rather unit test it.

I’ve started talking personal prefs, so I’ll stop posting after this -
thats my 2p, anyway.

Well, since classes can implement interfaces, the test can also check that
methods are being passed object that fulfill the interface contract. So, a
sort of type checking can be performed.

But thats no different from probing the objects you are passed as arguments.

I think I share some of both sides viewpoint, but I dont want a
Java’ed Ruby, and it seems that this interface idea is coming from
that angle.

Incihentally, my opposition to this isnt ‘not invented here’, its simply
that interfaces in Java increase flexibility, whereas in Ruby they
seem to be a restriction.

···

On Friday 21 November 2003 12:48 pm, Rasputin wrote:


Truth is the most valuable thing we have – so let us economize it.
– Mark Twain
Rasputin :: Jack of All Trades - Master of Nuns

Sean O’Dell wrote:

But again, its less hassle to document your API than to do rigourous
argument checking.

No, it’s more hassle. To update a document, you have to open a different
file, and if you make a typo or just plain write it wrong, there is
nothing to stop you from doing so. Interfaces can be described in the
same source file as your class definition, so it’s easy to find and
update, plus, you can’t update it wrong, or your code gives you errors.

You always have to update documentation when you change something.

Not always. If you provide code to others and are responsible enough to do
so, sure. On team projects, documentation happens very sporadically. RAA is
full of non or poorly documentation code. It is a good habit to have, but
humans often don’t keep up with as well as they should.

Having an interface checking
system doesn’t mean that you don’t have to document your code. So in
effect, having interfaces means
you have to update two different places when you make an interface
change (three, actually, if you
count the code that uses the interface), and there’s more things that
can get out of sync.

Or, you could argue, the interface description could serve as the source for
your API documentation. I’m going to add that to the wiki; the idea just
occurred to me. Automatic documentation generation would be extremely easy
if you had interface objects to query.

Besides, with systems like RDoc you can make all documentation
annotations in your source and
generate the documentation from there, so it’s really no more or less
convenient than having an
interface definition in your source, at least for documentation purposes.

That much is a plus, but the biggest problem I have with that is the same as
the problem I had with defining interfaces through classes: methods are
spread out by the code inside them. Browsing a class is not all that
pleasant because of that. Smaller source files aren’t so bad, but when a lot
of code sits in a source file, everything gets really spread out.

Sean O'Dell
···

On Friday 21 November 2003 01:50 pm, Dan Doel wrote:

and i thought it was so radical when i wrote it yesterday

notice if TypeErrors woud return offending respond_to? method

in error message then it would continue to probe

class DuckHunter

def initialize
@a_r_g_s = {}
end

def a_r_g_s
@a_r_g_s
end

def d_u_c_k_c_a_l_l
begin
yield
rescue TypeError => e
self.send(e.message)
retry
end
end

def method_missing(aSym, *args)
# This will happen the first time
aSymStr = aSym.to_s
@a_r_g_s[“#{aSymStr}”] = [ args.collect { |a| “#{a.class}” } ]
begin
d = %Q{
def self.#{aSymStr}(*args)
# This will happen the subsequent time
@a_r_g_s[“#{aSymStr}”] } + %q{.concat [ args.collect { |a|
“#{a.class}” } ]
self
end
}
instance_eval d
rescue SyntaxError
puts “TypeError induced SyntaxError! TypeError must return respond_to
method!”
raise
end
self
end

end

example

class TypeTest
def ameth(x)
big4 x

···

#—
puts x.to_i
puts x.jump(4)
puts x.do_what_ever(“Duck can take it!”, /\w+/)
puts x.do_what_ever(“Duck can take it!”, /\w+/, 42)
end
end

t = TypeTest.new

puts “\nDUCK QUACKS”

dh = DuckHunter.new
dh.d_u_c_k_c_a_l_l do
t.ameth(dh)
end

show args

puts “\nameth:”
dh.a_r_g_s.each { |name, argpat| argpat.each { |args| puts “\t#{name}
(#{args.join(‘,’)})” } }

-----------

On Saturday 22 November 2003 12:52 am, Greg McIntyre wrote:

“David Naseby” david.naseby@eonesolutions.com.au wrote:

Below is a quick hack to do that. Needs work. Needs redirection of IO.
But its kinda cute… Has issues with side effects, of course, and
printing crapola all over the place.

Is this or something like it on the RAA? Perhaps a slightly more general
mechanism to proxy messages to the “real” object and call a
hook/callback?

late could be added

Sorry I forgot to post results of DuckHunter examples. (DuckHunter itself is
also included below).

DuckHunter is a concise probe providing the functionality of #duck_signature,
and has a unique feature that suggests how Ruby might proceed to cleaning up
some of its code: If a type error returns the method that was not implemented
in the error message then DuckHunter will fix and continue to probe. Using
this on a number of libraries I have discoverd that ruby has a problem in
that it allows TypeError to be raised for any reason whatsoever. There needs
to be a tighter system for raising TypeErrors, including returning the
offened method. I believe that one of the first things that needs to happen
to improve Ruby’s type mechanics is to ensure that a signature probe can run
without fail on any method.

Results:

DUCK QUACKS

big4:
succ()
to_i()
>()
>(Fixnum)

DUCK QUACKS
#DuckHunter:0x402a8738
#DuckHunter:0x402a8738
#DuckHunter:0x402a8738
#DuckHunter:0x402a8738

ameth:
succ()
jump(Fixnum)
to_i()
to_i()
>()
>(Fixnum)
do_what_ever(String,Regexp)
do_what_ever(String,Regexp,Fixnum)

-t0

···

On Saturday 22 November 2003 02:22 am, T. Onoma wrote:

and i thought it was so radical when i wrote it yesterday

notice if TypeErrors woud return offending respond_to? method

in error message then it would continue to probe

class DuckHunter

def initialize
@a_r_g_s = {}
end

def a_r_g_s
@a_r_g_s
end

def d_u_c_k_c_a_l_l
begin
yield
rescue TypeError => e
self.send(e.message)
retry
end
end

def method_missing(aSym, *args)
# This will happen the first time
aSymStr = aSym.to_s
@a_r_g_s[“#{aSymStr}”] = [ args.collect { |a| “#{a.class}” } ]
begin
d = %Q{
def self.#{aSymStr}(*args)
# This will happen the subsequent time
@a_r_g_s[“#{aSymStr}”] } + %q{.concat [ args.collect { |a|
“#{a.class}” } ]
self
end
}
instance_eval d
rescue SyntaxError
puts “TypeError induced SyntaxError! TypeError must return respond_to
method!”
raise
end
self
end

end

example

class TypeTest
def ameth(x)
big4 x
#—
puts x.to_i
puts x.jump(4)
puts x.do_what_ever(“Duck can take it!”, /\w+/)
puts x.do_what_ever(“Duck can take it!”, /\w+/, 42)
end
end

t = TypeTest.new

puts “\nDUCK QUACKS”

dh = DuckHunter.new
dh.d_u_c_k_c_a_l_l do
t.ameth(dh)
end

show args

puts “\nameth:”
dh.a_r_g_s.each { |name, argpat| argpat.each { |args| puts “\t#{name}
(#{args.join(‘,’)})” } }

-----------

On Saturday 22 November 2003 12:52 am, Greg McIntyre wrote:

“David Naseby” david.naseby@eonesolutions.com.au wrote:

Below is a quick hack to do that. Needs work. Needs redirection of IO.
But its kinda cute… Has issues with side effects, of course, and
printing crapola all over the place.

Is this or something like it on the RAA? Perhaps a slightly more general
mechanism to proxy messages to the “real” object and call a
hook/callback?

late could be added