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

A

Austin Ziegler

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
 
C

Curt Sampson

...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
 
N

Nicholas Van Weerdenburg

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


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.


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.

Regards,
Nick
 
Z

Zach Dennis

Nicholas said:
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
 
E

Eric Hodel

--Apple-Mail-4--264556749
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=US-ASCII; format=flowed

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

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

--
Eric Hodel - (e-mail address removed) - http://segment7.net
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04

--Apple-Mail-4--264556749
content-type: application/pgp-signature; x-mac-type=70674453;
name=PGP.sig
content-description: This is a digitally signed message part
content-disposition: inline; filename=PGP.sig
content-transfer-encoding: 7bit

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (Darwin)

iD8DBQFB+dOOMypVHHlsnwQRAlDCAKDX+gwee1rvWgpployhaGWf/LX1QwCgnGD1
Fzdndk5AVpc3iPb16fqDp4U=
=ii9T
-----END PGP SIGNATURE-----

--Apple-Mail-4--264556749--
 
E

Eric Hodel

--Apple-Mail-5--263450671
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=US-ASCII; format=flowed

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.

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]
http://www.google.com/search?q=site:blade.nagaokaut.ac.jp+type+check
[2] http://people.freebsd.org/~eivind/ruby/types/
[3] http://mephle.org/StrongTyping/

--
Eric Hodel - (e-mail address removed) - http://segment7.net
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04

--Apple-Mail-5--263450671
content-type: application/pgp-signature; x-mac-type=70674453;
name=PGP.sig
content-description: This is a digitally signed message part
content-disposition: inline; filename=PGP.sig
content-transfer-encoding: 7bit

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (Darwin)

iD8DBQFB+dfgMypVHHlsnwQRAtWfAKDiAOVU3b+eo5Pn+ptujFZRf9Vw5QCg1HGr
Y5bhzVKESFfva47YEBY7+yQ=
=vDZr
-----END PGP SIGNATURE-----

--Apple-Mail-5--263450671--
 
C

Curt Sampson

It's relevant to me. Sure if sucks less if someone is insisting on a
type rather then a class, but it still sucks.

Then you must think that Ruby really sucks, because ruby does indeed
insist on a type, and generates an exception if you pass into a method
an object of the wrong type.

See for yourself:

irb(main):001:0> def second(o) o[2]; end
=> nil
irb(main):002:0> second([1, 2, 3, 4])
=> 3
irb(main):003:0> second("abcd")
=> 99
irb(main):004:0> second(1.75)
NoMethodError: undefined method `[]' for 1.75:Float
from (irb):1:in `second'
from (irb):4

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

Right. Typo on my part. But why is it deprecated?
Garbage collection was slow, inefficient and unreliable. Times change.

Right. And when decent type systems are fast and efficient, as they
already are in some langauges, where will Ruby be?
Lisp and Smalltalk have had this type debate for years. If I recall,
the sides are seperated by opinion, not ignorance.

There is no debate about typing itself. Both Lisp and Smalltalk are,
like Ruby, strongly typed langauges. Smalltalk, like Ruby, is pretty
darn poor about how it deals with types. Lisp, it depends on the
dialect, and I'm not so familiar with it.

Basically, when Ruby can find out that you have a type error fairly
early on, it doesn't. It just says, "too bad, I'm going to wait until
the very last minute possible before I point out this problem to you."

Worse yet, not only can Ruby not figure out earlier on that there's
a problem in any case whatsoever, but even when I can tell it how to
figure out that there's a problem, Ruby can't do anything with that
information.

cjs
 
C

Curt Sampson

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] http://www.google.com/search?q=site:blade.nagaokaut.ac.jp+type+check
[2] http://people.freebsd.org/~eivind/ruby/types/
[3] http://mephle.org/StrongTyping/

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
 
A

Alexander Kellett

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 :) 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 :)
Alex
 
A

Alexander Kellett

Worse yet, not only can Ruby not figure out earlier on that there's
a problem in any case whatsoever, but even when I can tell it how to
figure out that there's a problem, Ruby can't do anything with that
information.

agreed. if you give me a short script and an explicit example
and a week or two then i'll have a short specific solution for
you. feel free to generalize the solution ;)

i've wanted to do this for a while anyway.

Alex
 
R

Robert Klemme

Curt Sampson said:
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
 
L

leon breedt

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.

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

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 :)

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

class WebApi
include Webservice

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

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

Leon
 
G

gabriele renzi

Nicholas Van Weerdenburg ha scritto:
Lisp and Smalltalk have had this type debate for years. If I recall,
the sides are seperated by opinion, not ignorance.

well, but common lisp has optional typing (wich does not imply
staticness :)
 
A

Austin Ziegler

Me too. This is why I'm proposing that we have systems where the
compiler figures this out for us.
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.)
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.
 
D

David A. Black

Hi --

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.

Also, it's "ducks all the way down" -- in the sense that *nothing* can
actually substitute for running the code. I know that most of the
examples that illustrate this are marginal at best:

s = "hi"
def s.upcase; "ha ha"; end

...

puts s.upcase if s.respond_to?:)upcase) and s.is_a?(String) # ...

However, it's still true -- and, looking at it in a more optimistic
way, I find the possibilities of harnessing this kind of power quite
exciting.

This reminds me of my days as head of Photo Services at a museum in
New York City. The issue always arose of whether or not to create a
complete index of all the negatives in all the file cabinets. My
position was always: whatever it says in the index, the *only* way to
know whether we have a negative of a given work is to look in the file
cabinet. I would never hire a photographer to shoot an object without
making that final check. Therefore, the index would serve mostly as a
kind of unnecessary second skin to the negative collection itself, and
creating the index would not be worth the time it would take.


David
 
A

Austin Ziegler

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 :)

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], :eek:ut => options[:eek:ut] }
(@__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 ], :eek:ut => [ String ]
wsdl :in => [ Integer, String ], :eek:ut => [ String ]
def meth(param1, param2)
""
end

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

wsdl :method => :meth, :in => [ String, Float ],
:eek:ut => [ 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
 
E

Eric Hodel

--Apple-Mail-7--221960717
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed


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]
http://www.google.com/search?
q=site%3Ablade.nagaokaut.ac.jp+type+check
[2] http://people.freebsd.org/~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.)

--
Eric Hodel - (e-mail address removed) - http://segment7.net
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04

--Apple-Mail-7--221960717
content-type: application/pgp-signature; x-mac-type=70674453;
name=PGP.sig
content-description: This is a digitally signed message part
content-disposition: inline; filename=PGP.sig
content-transfer-encoding: 7bit

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (Darwin)

iD8DBQFB+nnyMypVHHlsnwQRAkwCAKDOxHQO8sWrx9zXJ2WlJUgr1UUz+wCgtJT9
w8dst3LeEL+xAUAZU+GJwKw=
=mVBN
-----END PGP SIGNATURE-----

--Apple-Mail-7--221960717--
 
M

Mark Hubbart

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
 
A

Alexander Kellett

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.

i very much doubt that these corner cases will really
play much in the real world. if something is ambiguous
and the static type checking/introspection is really
needed, then the inferencer can just as well warn the
programmer of this. a baby inferencer would basically
warn all the time, until eventually it would work.

an interesting way to test case this would be to have
runtime tracing report on typing during execution, and
run the inferencer against the output of this, whenever
something has a mismatch, the test fails.

Alex
 
M

Mark Hubbart

i very much doubt that these corner cases will really
play much in the real world. if something is ambiguous
and the static type checking/introspection is really
needed, then the inferencer can just as well warn the
programmer of this. a baby inferencer would basically
warn all the time, until eventually it would work.

So you are suggesting that the runtime keeps track of state between
runs? Are you thinking that this will only be used during test runs,
and won't be used when the end user runs the code?
an interesting way to test case this would be to have
runtime tracing report on typing during execution, and
run the inferencer against the output of this, whenever
something has a mismatch, the test fails.

Don't discount these cases just because they are edge cases. They are
simply shorter versions of things that are actually used. When
metaprogramming, it is common to define methods on the fly using
define_method and a string, or by using method_missing, or by adding a
singleton method. For example, an xml generation lib could take an xml
schema and create an object that refers to that schema to create it's
own methods. And I suspect that most Ruby programmers would consider
that an acceptable way of doing it. But the dynamic nature of it would
likely cause difficulties when attempting to determine what methods
that object would respond to. And that's not an edge case, that's a
real life one.

Perhaps the greatest strength of Ruby is the fact that so much can
happen at runtime. Things that you *can't* detect at compile time.
Things like dynamic definition and redefinition of methods, dynamic
code loading, etc. These will make it difficult, if impossible, to
raise meaningful errors at compile time, *ever*. Any code that
requires a library, or has an eval statement, must be suspected as
having added, removed, or changed some methods - and so errors can't
be raised.

cheers,
Mark
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top