"Duck Typing" or "No need for abstract classes"

Nicholas Van Weerdenburg wrote:

This is the impression I've gotten- that a live image system uses the
objects that exist while programming against a live system to do code
completion, etc. In effect, this is what irb completion does.

Partially, IRB does not actually evaluate the expressions. If it sees that you are calling a method it will IIRC just list all methods that are provided by any of the currently loaded classes. This is a good thing for expressions with side effects such as `rm -rf /`, but could be improved in other cases.

Interestingly, Rails seems to be evolving into a pseudo-image-like
system, with class reloads and breakpoints that spawn irb sessions.
Conceivably an editor could be smart enough to bind to the running
environment.

As the author of the breakpoint library I'm still very interested in using it for writing an IDE that will attach to a live code base and allow you to investigate, modify and much more. Note that this would at first not be just as nifty as the Smalltalk solutions because you can not generally get code for methods and so on, but using some of the cool thing like the AST library or by reading back the code from Files you could probably get pretty close.

It's an interesting area and I'd be willing to offer as much support as I can to such efforts if somebody can kick this off with a decent code base.

Hello Mathieu,

Depends what kind of Ruby one writes. I have written a lib that includes a
spec of the X11 display protocol, and is less than 100k, yet defines over
400 classes, most of which are anonymous, and most defined methods are
eval'ed from strings built at load time.

Well, needless to say that any class browser chokes to death on that kind
of code.

No i was thinking about this and how i want to implement it in Arachno
Ruby. Sure with this you can't use any kind of static code analysis.
But we can use the fact that ruby scripts are executed hundert of
times during development. So if i hack the interpreter and record the
create_method, create_class, create_module (don't know how they are named in
eval.c) then i can find out what you are building with your evals. At the
end of the program run i output this gathered data about the class
universe to the class browser which mixes it together with the data
from the static code analysis and previous runs maybe by using the
bayesian formulars.

I found this as the only good solution after looking at the ruby TK
source code.

I think that thoroughly applying DRY/OAOO much lessens the need for a

Sorry i forgot this 2 acronyms. DRY ? OAOO ?

···

--
Best regards, emailto: scholz at scriptolutions dot com
Lothar Scholz http://www.ruby-ide.com
CTO Scriptolutions Ruby, PHP, Python IDE 's

"Curt Sampson" <cjs@cynic.net > schrieb im Newsbeitrag
news:Pine.NEB.4.61.0501271018220.2459@angelic-vtfw.cvpn.cynic.net...

But I would propose actually changing the language to better
support this sort of thing.

I opt against this: not every good or useful language feature
must be present in Ruby.

No. Ruby could end up being a second-rate language instead.

It could be, but that seems to be unlikely -- unless non-feature
features are added to it (such as static typing).

[...]

Lisp, on the other hand, in all of its various forms, is still one
of the most powerful programming languages in the world, and is
still being used to write new systems more than forty-five years
after its invention.

...and it doesn't have static typing.

Ruby asked me to give up a lot of useful type checking in order to
get duck typing. It does not have to do so. If it continues to do
so, one day a language is going to come along that offers what
Ruby does but doesn't make this compromise, and people will start
switching, just as people are now switching from Perl to Ruby
because Perl doesn't "need" a better syntax for OO work.

Frankly, I don't see any advantage to static typing. None. I find
that I hate any language that requires me to type stuff just to help
the compiler -- static typing and such type checking is NOT for us,
the programmers, but for the compiler.

Frankly, adding static typing or even type hinting to Ruby will
*reduce* Ruby's flexibility. How? Because people will use it; the
moment that some fool library writer decides that they want
something that *is* an IO object, it will no longer be possible to
pass in a StringIO object (it doesn't inherit from IO, and IO isn't
a module) or even a specially modified Array or String or some other
object.

-austin

···

On Fri, 28 Jan 2005 08:29:34 +0900, Curt Sampson <cjs@cynic.net> wrote:

On Thu, 27 Jan 2005, Robert Klemme wrote:

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

We've had this debate before. Please go read the past discussions [1] before trying to bring something new to the table, or saying ruby needs 'X' to be successful. Especially since we've got lots of ways to add typing to ruby already [2] [3].

[1] site:blade.nagaokaut.ac.jp type check - Google Search
[2] Index of /~eivind/ruby/types/
[3] http://mephle.org/StrongTyping/

PGP.sig (186 Bytes)

···

On 27 Jan 2005, at 15:29, Curt Sampson wrote:

Ruby asked me to give up a lot of useful type checking in order to get
duck typing. It does not have to do so. If it continues to do so, one
day a language is going to come along that offers what Ruby does but
doesn't make this compromise, and people will start switching, just as
people are now switching from Perl to Ruby because Perl doesn't "need" a
better syntax for OO work.

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

"Curt Sampson" <cjs@cynic.net> schrieb im Newsbeitrag
news:Pine.NEB.4.61.0501280820130.14315@angelic-vtfw.cvpn.cynic.net...

> "Curt Sampson" <cjs@cynic.net> schrieb im Newsbeitrag
> news:Pine.NEB.4.61.0501271018220.2459@angelic-vtfw.cvpn.cynic.net...
>
>> But I would propose actually changing the language to better support
>> this sort of thing.
>
> I opt against this: not every good or useful language feature must be
> present in Ruby.

No. Ruby could end up being a second-rate language instead.

Without type inference? I don't think so - and probably others, too.

Look at Java. It was ten years behind the state of the art in OOP
when it was first made, has advanced little since, and its prospects
for real advancement are almost nil. (I'd bet that never going to
see continuations in Java, for example.)

Java has native threads. That's definitively a major advantage -
especially on multiprocessor systems. Also with regard to OO Java is not
as bad as you claim. It got rid of several C++ problems (preprocessor,
multiple inheritance, weak RTTI) while introducing some of its own (jar
hell and classpath problems). It has very sophisticated runtime
environments (with GC, JIT, HotSpot, diagnostic interfaces...), something
I would not claim of Ruby.

Java's already reliant on
precompilers for things like macros and aspect-oriented programming.

Because it was not designed for that. C isn't designed for AOP either.

That's why I left Java for Ruby.

Lisp, on the other hand, in all of its various forms, is still one of
the most powerful programming languages in the world, and is still
being used to write new systems more than forty-five years after its
invention.

Still, even Lisp is not suited to all programming tasks. Many languages
have their strengths and weaknesses and fields where they shine.

Regards

    robert

···

On Thu, 27 Jan 2005, Robert Klemme wrote:

Cool!

(I'm saying that too much the last few days)

What code base to mean? IDE or "live codebase"'?

This is way beyond me so I'd be interested in knowing what you think
the main components needed are, and how the functionality would be
distributed across breakpoint, IDE, and a "live codebase" manager.

Thanks,
Nick

···

On Wed, 26 Jan 2005 05:45:48 +0900, Florian Gross <flgr@ccan.de> wrote:

Nicholas Van Weerdenburg wrote:

> This is the impression I've gotten- that a live image system uses the
> objects that exist while programming against a live system to do code
> completion, etc. In effect, this is what irb completion does.

Partially, IRB does not actually evaluate the expressions. If it sees
that you are calling a method it will IIRC just list all methods that
are provided by any of the currently loaded classes. This is a good
thing for expressions with side effects such as `rm -rf /`, but could be
improved in other cases.

> Interestingly, Rails seems to be evolving into a pseudo-image-like
> system, with class reloads and breakpoints that spawn irb sessions.
> Conceivably an editor could be smart enough to bind to the running
> environment.

As the author of the breakpoint library I'm still very interested in
using it for writing an IDE that will attach to a live code base and
allow you to investigate, modify and much more. Note that this would at
first not be just as nifty as the Smalltalk solutions because you can
not generally get code for methods and so on, but using some of the cool
thing like the AST library or by reading back the code from Files you
could probably get pretty close.

It's an interesting area and I'd be willing to offer as much support as
I can to such efforts if somebody can kick this off with a decent code base.

--
Nicholas Van Weerdenburg

DRY= don't repeat yourself, http://c2.com/cgi/wiki?DontRepeatYourself
OAOO= once and only once, http://c2.com/cgi/wiki?OnceAndOnlyOnce

I think DRY is from the Pragmatic Programmers, and OAOO from the XP
community. Not positive though. As of the difference, I think it was
that OAOO is RYSARSYDRY= repeat yourself and refactor so you don't
repeat yourself.

Regards,
Nick

···

On Fri, 28 Jan 2005 06:04:54 +0900, Lothar Scholz <mailinglists@scriptolutions.com> wrote:

Hello Mathieu,

> Depends what kind of Ruby one writes. I have written a lib that includes a
> spec of the X11 display protocol, and is less than 100k, yet defines over
> 400 classes, most of which are anonymous, and most defined methods are
> eval'ed from strings built at load time.

> Well, needless to say that any class browser chokes to death on that kind
> of code.

No i was thinking about this and how i want to implement it in Arachno
Ruby. Sure with this you can't use any kind of static code analysis.
But we can use the fact that ruby scripts are executed hundert of
times during development. So if i hack the interpreter and record the
create_method, create_class, create_module (don't know how they are named in
eval.c) then i can find out what you are building with your evals. At the
end of the program run i output this gathered data about the class
universe to the class browser which mixes it together with the data
from the static code analysis and previous runs maybe by using the
bayesian formulars.

I found this as the only good solution after looking at the ruby TK
source code.

> I think that thoroughly applying DRY/OAOO much lessens the need for a

Sorry i forgot this 2 acronyms. DRY ? OAOO ?

--
Best regards, emailto: scholz at scriptolutions dot com
Lothar Scholz http://www.ruby-ide.com
CTO Scriptolutions Ruby, PHP, Python IDE 's

--
Nicholas Van Weerdenburg

...I hate any language that requires me to type stuff just to help
the compiler...

Me too. This is why I'm proposing that we have systems where the
compiler figures this out for us.

static typing and such type checking is NOT for us,
the programmers, but for the compiler.

I'm not quite sure what you mean by "static typing," but type checking
is for us, the programmers. One of the things that is good about Ruby is
that it does thorough type checking--it is a strongly typed language.

...the moment that some fool library writer decides that they want
something that *is* an IO object, it will no longer be possible to
pass in a StringIO object (it doesn't inherit from IO, and IO isn't
a module) or even a specially modified Array or String or some other
object.

Any "fool library writer" can do that now:

     raise "wrong type" unless arg.class <= SomeClass

I agree doing that would be silly. But this has no relevance; I'm
talking about types, not classes.

Given that you are objecting to the direction I'm proposing whilst being
unaware that you're agreeing with me on key points and possibly even
unaware that you're already using type checking, I would suggest you go
do some research on type systems before commenting further.

Here's the start on your research: find out why Class.class method is
deprecated in favour of Class.type.

It's quite common that someone who doesn't understand an advanced
langauge feature (usually because it's not in any of the languages he
uses) will object to it through ignorance, only to be unable to live
without that feature once he starts using it. Garbage collection was
once considered slow, inefficient and unreliable. Would you like to take
GC out of Ruby?

cjs

···

On Fri, 28 Jan 2005, Austin Ziegler wrote:
--
Curt Sampson <cjs@cynic.net> +81 90 7737 2974 http://www.NetBSD.org
      Make up enjoying your city life...produced by BIC CAMERA

Wow, talk about missing the point.

1. Ruby already has typing, in fact it already has strong typing. There
is no way to apply an operation to (invoke a method on) an object where
the operation is not suited to the type of the object.

2. [3] Is not strong typing, it's manually declared checking of the
class of method arguments at runtime. Yuck.

3. [2] is again misnamed, it's a class checker, not a type checker. It's
not quite as misnamed as [3], but other than that it's essentially the
same. Yuck.

This is now about the third time we've gone around with people attacking
the idea of restricting how objects can be passed around based on their
class, which I'm quite happy to attack, too. We're in full agreement here!

So can we talk about TYPES, not classes, and maybe you can tell me
what you disagree with about making Ruby a bit smarter about this sort
of thing? That an unmodified standard Ruby installation, attempts to
execute the second statement of this complete program:

     a = Object
     a.not_a_method

and then throws an exception is just silly. Any bozo can just look at it
and say it's not going to work. A computer can look at much more complex
things and say it's not going to work.

cjs

···

On Fri, 28 Jan 2005, Eric Hodel wrote:

We've had this debate before. Please go read the past discussions [1] before trying to bring something new to the table, or saying ruby needs 'X' to be successful. Especially since we've got lots of ways to add typing to ruby already [2] [3].

[1] site:blade.nagaokaut.ac.jp type check - Google Search
[2] Index of /~eivind/ruby/types/
[3] http://mephle.org/StrongTyping/

--
Curt Sampson <cjs@cynic.net> +81 90 7737 2974 http://www.NetBSD.org
      Make up enjoying your city life...produced by BIC CAMERA

One of the areas where hinting (if I understand what you mean
correctly by it) can be useful is for interoperability with more
static platforms.

It does happen, ask those of us who use Ruby to provide WSDL/SOAP
services to other platforms :slight_smile:

I could hint at method type and return value signatures, generating
decent WSDL would be a lot easier.

A .NET client of the Ruby service will die horribly more often than
not if there is a slight variation in the return message from Ruby as
to what it was expecting based on the WSDL, whereas Ruby is much more
accepting.

If you've seen WSDL syntax, you'll understand why I want to generate
it from the Ruby code instead of writing it manually and running
wsdl2ruby over it :slight_smile:

Currently I have my own "hinting" using Module#included and per class
annotations.

class WebApi
  include Webservice

  wsdl_method :meth, :in => [String, Integer], :out => [String]
  def meth(param1, param2)
    ""
  end
end

This way works, but I'd prefer something closer to the method code.

Leon

···

On Fri, 28 Jan 2005 12:16:34 +0900, Austin Ziegler <halostatue@gmail.com> wrote:

Frankly, adding static typing or even type hinting to Ruby will
*reduce* Ruby's flexibility.

Nicholas Van Weerdenburg wrote:

Interestingly, Rails seems to be evolving into a pseudo-image-like
system, with class reloads and breakpoints that spawn irb sessions.
Conceivably an editor could be smart enough to bind to the running
environment.

It's an interesting area and I'd be willing to offer as much support as
I can to such efforts if somebody can kick this off with a decent code base.

What code base to mean? IDE or "live codebase"'?

The IDE project.

This is way beyond me so I'd be interested in knowing what you think
the main components needed are, and how the functionality would be
distributed across breakpoint, IDE, and a "live codebase" manager.

I've not thought much about this yet, but I think the separation would be like this:

* breakpoint: Backend for running code in the right places of a running
   application.
* live codebase manager: Find code for method objects, extract diverse
   meta data.
* IDE: frontends for displaying the results of the live codebase manager
   and for providing a GUI for manipulating the environment.

> ...I hate any language that requires me to type stuff just to help
> the compiler...

Me too. This is why I'm proposing that we have systems where the
compiler figures this out for us.

> static typing and such type checking is NOT for us,
> the programmers, but for the compiler.

I'm not quite sure what you mean by "static typing," but type checking
is for us, the programmers. One of the things that is good about Ruby is
that it does thorough type checking--it is a strongly typed language.

> ...the moment that some fool library writer decides that they want
> something that *is* an IO object, it will no longer be possible to
> pass in a StringIO object (it doesn't inherit from IO, and IO isn't
> a module) or even a specially modified Array or String or some other
> object.

Any "fool library writer" can do that now:

     raise "wrong type" unless arg.class <= SomeClass

I agree doing that would be silly. But this has no relevance; I'm
talking about types, not classes.

It's relevant to me. Sure if sucks less if someone is insisting on a
type rather then a class, but it still sucks. It's pretty common in
Ruby to rely on on pseudo-types such as objects that implement #to_s.

Given that you are objecting to the direction I'm proposing whilst being
unaware that you're agreeing with me on key points and possibly even
unaware that you're already using type checking, I would suggest you go
do some research on type systems before commenting further.

Here's the start on your research: find out why Class.class method is
deprecated in favour of Class.type.

I just looked..
Class.type is deprecated in favour of Class.class

It's quite common that someone who doesn't understand an advanced
langauge feature (usually because it's not in any of the languages he
uses) will object to it through ignorance, only to be unable to live
without that feature once he starts using it. Garbage collection was
once considered slow, inefficient and unreliable. Would you like to take
GC out of Ruby?

Garbage collection was slow, inefficient and unreliable. Times change.

And it's quite common for someone who uses a feature from another
language to not be able to let go :).

Lisp and Smalltalk have had this type debate for years. If I recall,
the sides are seperated by opinion, not ignorance.

cjs
--
Curt Sampson <cjs@cynic.net> +81 90 7737 2974 http://www.NetBSD.org
      Make up enjoying your city life...produced by BIC CAMERA

Regards,
Nick

···

On Fri, 28 Jan 2005 13:48:17 +0900, Curt Sampson <cjs@cynic.net> wrote:

On Fri, 28 Jan 2005, Austin Ziegler wrote:

--
Nicholas Van Weerdenburg

Where is that? Not in my rubys:

$ ruby -vwe 'Class.type'
ruby 1.8.2 (2004-12-25) [powerpc-darwin7.7.0]
-e:1: warning: Object#type is deprecated; use Object#class
$ ./ruby19 -vwe 'Class.type'
ruby 1.9.0 (2005-01-27) [powerpc-darwin7.7.0]
-e:1: warning: Object#type is deprecated; use Object#class

PGP.sig (186 Bytes)

···

On 27 Jan 2005, at 20:48, Curt Sampson wrote:

Here's the start on your research: find out why Class.class method is
deprecated in favour of Class.type.

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

hey Curt,

how about an example? i read explicit code
better than descriptions of your needs based
on literature and jargon/wording that i've
never met :slight_smile: afaict main problem with this thread
has been lack of understanding exactly what
you're looking for. could you give a few examples
with code (non working, just the syntax you
think it should have) and output expectations?

thanks :slight_smile:
Alex

...I hate any language that requires me to type stuff just to
help the compiler...

Me too. This is why I'm proposing that we have systems where the
compiler figures this out for us.

static typing and such type checking is NOT for us, the
programmers, but for the compiler.

I'm not quite sure what you mean by "static typing," but type
checking is for us, the programmers. One of the things that is
good about Ruby is that it does thorough type checking--it is a
strongly typed language.

Variables (labels) are untyped, though. Most people who want some
sort of type checking, including your erstwhile correspondent
Transami, end up wanting something that looks an awful lot like
class checking on variables (e.g., variables that only accept
objects of a given type/class; homogenous containers, etc.)

...the moment that some fool library writer decides that they
want something that *is* an IO object, it will no longer be
possible to pass in a StringIO object (it doesn't inherit from
IO, and IO isn't a module) or even a specially modified Array or
String or some other object.

Any "fool library writer" can do that now:

     raise "wrong type" unless arg.class <= SomeClass

I agree doing that would be silly. But this has no relevance; I'm
talking about types, not classes.

Okay, so define an object's type. See, this is where things get
complicated -- it's *hard* to pin down an object's type in a
language as dynamic as Ruby. For some methods, I require that the
object provided have #<< defined; for others it's something else. I
have gone away from pre-checking this[1], and there's really no way
that any sort of heuristic can be built for it, either -- at least
not one that performs faster than just running the code. Now, if you
wanted to talk about something in Ruby that caches execution
information and uses that to analyse the best execution paths and
increase type safety through repeated runs, I can agree -- but
you'll still have at least one run that's not optimized in any way.

Given that you are objecting to the direction I'm proposing whilst being
unaware that you're agreeing with me on key points and possibly even
unaware that you're already using type checking, I would suggest you go
do some research on type systems before commenting further.

Here's the start on your research: find out why Class.class method
is deprecated in favour of Class.type.

Actually, in Ruby, it's the other way around. #type has been
deprecated in favour of #class. They were synonymous. The "type" of
an object is something more nebulous, and it's much harder to
determine; as I said, an Object (modified), an Array, a String, or a
StringIO object can all act like an IO object -- and the only way
you can check that is by knowing what methods are required by the
entire method.

It's quite common that someone who doesn't understand an advanced
langauge feature (usually because it's not in any of the languages
he uses) will object to it through ignorance, only to be unable to
live without that feature once he starts using it. Garbage
collection was once considered slow, inefficient and unreliable.
Would you like to take GC out of Ruby?

Actually, I'm objecting to your asinine arrogance -- suggesting that
without this, Ruby will be a second-class language and that you do
know better.

You don't. Why don't you actually try reading some of the older
discussions on types and classes and variants of type checking and
type inference before you start going on about this.

Because classes and objects aren't closed in Ruby, it becomes
computationally expensive (prohibitively so) to try to have the
compiler or interpreter to do a lot of this "programmer protection"
stuff. That's just reality. There are things that can be done to
improve performance, but it's more of a histogram analysis than a
single run performance improvement.

-austin
[1] One of the things that I do is check this during the assignment
    of adapters. That is, when you write:
      Text::Format.new.hyphenator = Text::Hyphen.new
    You'll be guaranteed that the #hyphenator object of the
    anonymous Text::Format object will respond to #hyphenate_to(). I
    don't actually verify during the hyphenation call in
    Text::Format that your hyphenator is a real hyphenator -- so if
    you circumvent my uniform access method and do:

      Text::Format.new.instance_variable_set("@hyphenator", Object.new)

    You're going to get an ugly exception at runtime, not at
    initialization.

···

On Fri, 28 Jan 2005, Austin Ziegler wrote:

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

Frankly, adding static typing or even type hinting to Ruby will
*reduce* Ruby's flexibility.

One of the areas where hinting (if I understand what you mean
correctly by it) can be useful is for interoperability with more
static platforms.

That is what I meant by it, and that is the only place that I think
that it's useful. That's not to say that it's the only place, but
it's the only place that I find such utility.

However, type hinting for the purpose of improving Ruby (either
performance or programmer "safety") would be useless. IMO.

It does happen, ask those of us who use Ruby to provide WSDL/SOAP
services to other platforms :slight_smile:

This could theoretically be done with a bit of extra typing, similar
to what you've done with your Webservice module. However, it can be
improved:

  module Webservice
    def wsdl(options = {})
      if options[:method]
        op = { :in => options[:in], :out => options[:out] }
        (@__wsdl_cache[options[:method]] ||= ) << op
      else
        (@__wsdl_cache ||= ) << options
      end
    end

    def method_added(method)
      @__wsdl_definitions ||= {}
      @__wsdl_definitions[method] ||=
      @__wsdl_cache.each do |options|
        @__wsdl_definitions[method] << options
      end
      @__wsdl_cache.clear
    end

    def self.extended(mod)
      class << mod
        define_method(:wsdl_definitions) { || @__wsdl_definitions }
      end
    end
  end

  class WebApi
    extend Webservice

    wsdl :in => [ String, Integer ], :out => [ String ]
    wsdl :in => [ Integer, String ], :out => [ String ]
    def meth(param1, param2)
      ""
    end

    wsdl :in => [ String ], :out => [ Integer ]
    def atoi(str)
      str.to_i
    end

    wsdl :method => :meth, :in => [ String, Float ],
         :out => [ String ]
  end

  puts WebApi.wsdl_definitions.inspect

What I'd recommend doing, even, is using symbols or some other way
of expressing a type or class, e.g., :String, not String. But the
above should simplify your WSDL generation.

-austin

···

On Fri, 28 Jan 2005 21:42:00 +0900, leon breedt <bitserf@gmail.com> wrote:

On Fri, 28 Jan 2005 12:16:34 +0900, Austin Ziegler > <halostatue@gmail.com > wrote:

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

We've had this debate before. Please go read the past discussions [1] before trying to bring something new to the table, or saying ruby needs 'X' to be successful. Especially since we've got lots of ways to add typing to ruby already [2] [3].

[1] site:blade.nagaokaut.ac.jp type check - Google Search
[2] Index of /~eivind/ruby/types/
[3] http://mephle.org/StrongTyping/

Wow, talk about missing the point.

No, I know exactly your point, but you are being very bad at expressing it. Constantly saying that everybody is attacking you does not add credit to your statement, either. Eivind Eklund wrote a rather wonderful piece on exactly what you haven't expressed, but want to. Unfortunately its URL escapes me.

1. Ruby already has typing, in fact it already has strong typing. There
is no way to apply an operation to (invoke a method on) an object where
the operation is not suited to the type of the object.

This is now about the third time we've gone around with people attacking
the idea of restricting how objects can be passed around based on their
class, which I'm quite happy to attack, too. We're in full agreement here!

The speed at which you have responded, and the way you are thinking you have been attacked indicate you haven't read nearly enough of the history of this debate in Ruby (if it all). Only 3 hours is not enough to fully comprehend why what you want is hard in Ruby, and why people are perfectly happy the way things are.

Let me go back to your original statement, since that is your clearest post on your position to date...

No, Ruby's implementation of [Duck Typing] is the problem. You can do duck typing
very much like Ruby does and still have statically checked types; you
just need a type inference engine to do that for you.

I fully agree with you that a type inferencing engine can do this for you, but in Ruby it will be hard (the Self papers are the best reference on this).

I think that that may actually be the next big step in popular
programming languages. A lot of programmers these days expect that they
will both never have a memory leak, and never have to track memory
allocations and deallocations by hand. So we have garbage collectors.

Yep, its always great when the computer does things for us. Nobody here will debate you on that.

Soon people may see that it's perfectly reasonable to expect to be told
at compile time type about type mismatches, and yet not have to keep
track of types by hand, in the way that Java forces you to (and prevents
duck typing). So add a type inference engine or whatever you need for
this.

Yes, this would benefit us greatly, except for one problem... There is no "compile time" in Ruby, there is only run-time. (Self's type inferencing doesn't have a problem with having no "compile time", but Self has several advantages over Ruby. Its biggest advantage is that Self has people who want to work on this problem working on this problem... Ruby doesn't).

And now back to the rest of your mail:

So can we talk about TYPES, not classes, and maybe you can tell me
what you disagree with about making Ruby a bit smarter about this sort
of thing?

I agree Ruby should be as smart as it can about this, it is just hard (please see the Self papers and the history of this discussion on the mailing list).

That an unmodified standard Ruby installation, attempts to
execute the second statement of this complete program:

    a = Object
    a.not_a_method

and then throws an exception is just silly. Any bozo can just look at it
and say it's not going to work. A computer can look at much more complex
things and say it's not going to work.

Ok, here is your much more complex thing, but not too complex, but I cannot tell if it is going to work until I run it:

srand Time.now.to_i

Thread.start do
   sleep rand(1)
   ObjectSpace.each_object(Object) do |o|
     def o.not_a_method() end
   end
end

a = Object.new
a.not_a_method # not_a_method may or may not be defined here

No "compile time" type inferencer can tell you if that is going to work or not. A run-time type inferencer needs to do lots of things to tell you if that is going to work, and even still, it may not know that a.not_a_method is going to work until just before you try to call a.not_a_method.

This is why you feel your ideas are being attacked so much. You cannot be certain that a.not_a_method will work until, at best, just before you are about to call it and nobody can take your execution timeslice.

The type inferencer must do a lot of work just before you try something to tell you if it failed or not. I can get an identical message by just trying it, and for everybody that is shooting you down, that's exactly what they are comfortable with.

We like duck typing, and we're perfectly happy that exceptions are raised when things won't work.

Oh, and one more:

begin
   a = Object.new
   a.not_a_method # The type inferencer must not give up here!
rescue
   class Object; def not_a_method() end; end
   retry
end

(Yes, I've used code exactly like this to do rapid prototyping, its incredibly cool.)

PGP.sig (186 Bytes)

···

On 28 Jan 2005, at 01:10, Curt Sampson wrote:

On Fri, 28 Jan 2005, Eric Hodel wrote:

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

Hi,

Maybe some terms and thoughts need to be clarified here.

Curt:
How are you defining "type"? It gets used so much to mean different
things. To you, what defines the type of a particular object?

If you go by "types as method signatures", there are obviously cases
where they can't be checked at compile time. What should be done in
these cases? ie., this code:

···

---
def Foo(other)
  other.to_foo
end

Foo(23)
---

... could easily be checked. while this:

---
def bar(other)
  other.send(*gets.chomp.split)
end

bar(23)
---

... would be impossible to check. We could decide to implement an
inconsistant type checking, but full type checking would be
impossible. How should difficult/impossible cases be handled? Another
difficult case:

---
eval(gets)

23.not_a_method
---

in this case, it would be not only difficult to detect the error at
compile time, but it would be difficult to differentiate between it
and an illegal method call. or:

---
load "foobar.rb" if ARGV.include? "load"

23.not_a_method
---

Loading and requiring is done at runtime, not at compile time. So how
would you know which methods were available to an unmodified Integer
at runtime?

These are just a few examples, mostly attempting to be on the extreme
side. But they show a few possible problems with checking types,
especially based on method signatures, at compile time.

cheers,
Mark

Personally, I use both terms interchangeably, but i often mention both so
that people from either side will recognise the concept. My personal
explanation of the concept is like this:

1. avoid repeating yourself, if you see how to
2. repeat yourself, if you don't see how not to
3. eliminate the repetition caused by (2) once you figure out how

But then, I am very much into liberal interpretations of such phrases.

···

On Fri, 28 Jan 2005, Nicholas Van Weerdenburg wrote:

On Fri, 28 Jan 2005 06:04:54 +0900, Lothar Scholz

I think DRY is from the Pragmatic Programmers, and OAOO from the XP
community. Not positive though. As of the difference, I think it was
that OAOO is RYSARSYDRY= repeat yourself and refactor so you don't
repeat yourself.

_____________________________________________________________________
Mathieu Bouchard -=- Montréal QC Canada -=- http://artengine.ca/matju

Nicholas Van Weerdenburg wrote:

Lisp and Smalltalk have had this type debate for years. If I recall,
the sides are seperated by opinion, not ignorance.

Quoting "The Postman", "How is this relationship supposed to work, if you don't listen to me?"

I am neither sided on this for this post, but felt it was a good time to add my Postman quote...

Zach