[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Type inference in ruby

Trevor Andrade

1/8/2005 6:54:00 PM

Hello all,

I was wondering whether it would be possible to have a type inference system
in ruby. My question was asked before
<http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk... by
gabriele renzi but it never received much of a response. This system might
try to figure out whether you are writing code with some obvious errors.
There has been a <http://www.cc.gatech.edu/~lex/ti/t... project on this
for smalltalk. For instance if you have a function like the following



def foo(object)

return object.call(9, 7, 3)

end



couldn't the type system figure out that object must respond to the call
command and thus eliminate an error like:



foo(5)



I guess I am also wondering about a lot of other things like why do you need
multiple assignment in Ruby? There doesn't seem to be any need for it since
you can just modify an object by sending it a message eg x = x + 1 is the
same as x.+(1). I am not sure if this would help type inference systems but
it seems like it should. There is a <http://rubyforge.org/projects/...
ruby project that is trying to create a type inference system although it is
very experimental. Can people give some examples where type inference would
be very difficult in Ruby? Does anybody know what kinds of things make it
difficult to do type inference in a language. On the smalltalk type
inference project site they say the following



"Type inference in Smalltalk-like languages has been studied since at least
1981, when Norihisa Suzuki published a type inference algorithm for
Smalltalk-80. Chuck's algorithm DDP is unusual, however, in two ways: it is
demand-driven and prunes subgoals. A demand-driven algorithm is architected
around the notion of "goals", where each goal is either answered directly
("what is the type of 47?"), or via subgoals ("what is the type of x+y?").
The advantage of this approach is that, whenever too many goals are being
studied, it is possible to "prune" some of the goals by giving them obvious
but poor answers ("the type could be anything"); the analysis can then
procede, and it may still find good answers to other questions. Pruning in
this fashion does not appear possible in the competing approaches of
abstract interpretation and of constraint solving; such approaches must
completely solve any subproblems they generate."



It seems like a system like this would be good for Ruby because it would
allow you to catch some errors and maybe even do some optimizations if you
were making a compiler since you would know the representations of some of
the objects.



Regards,

Trevor Andrade

24 Answers

Eric Anderson

1/8/2005 7:15:00 PM

0

Trevor Andrade wrote:
> I was wondering whether it would be possible to have a type inference system
> in ruby. My question was asked before

I am sure it is possible to implement but I think most people end up
wondering why do it? If you want a typed system (strong or weak) there
are plenty of languages that support it natively. For me that is one of
the reasons I left those other languages. For me a type system has too
much coding overhead without much benefit. The two advantages are:

* Catches type errors
* Possibly better optimizations

To answer the first advantage Ruby encourages Unit testing. Unit testing
it 10 times better than type checking because it can not only check for
valid types but also check for logic errors. So why spend the overhead
of a type system when unit testing is better.

The second advantage again isn't an issue for me. Ruby is fast enough.
If I need it faster I can profile the code to find bottlenecks. If I
need it even faster I can recode the bottlenecks in C. Again, the
overhead of a type system is not worth even the possibility of better
optimizations.

Just my two cents,

Eric

Logan Capaldo

1/8/2005 7:22:00 PM

0

On Sun, 9 Jan 2005 03:54:13 +0900, Trevor Andrade
<trevor.andrade@utoronto.ca> wrote:
> There doesn't seem to be any need for it since
> you can just modify an object by sending it a message eg x = x + 1 is the
> same as x.+(1).
Minor correction, x = x + 1 IS not the same as x.+(1), its the same as
x = x.+(1). + is non-destructive, (well assuming this isn;t a user
defined or modified object).


James Britt

1/8/2005 7:30:00 PM

0

Trevor Andrade wrote:
> Hello all,
>
> I was wondering whether it would be possible to have a type inference system
> in ruby. My question was asked before
> <http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk... by
> gabriele renzi but it never received much of a response. This system might
> try to figure out whether you are writing code with some obvious errors.
> There has been a <http://www.cc.gatech.edu/~lex/ti/t... project on this
> for smalltalk. For instance if you have a function like the following
>

<snip/>

I don't want to dismiss this question, but is there a reference or
archive page for the "static typing (quasi and otherwise)" permathread?

Also, some links that may be of interest:

"Adding Optional Static Typing to Python"
http://www.artima.com/weblogs/viewpost.jsp?th...

"Adding Optional Static Typing to Python -- Part II"
http://www.artima.com/weblogs/viewpost.jsp?th...

"DSL Design Considerations"
http://home.comcast.net/~bc19191/blog/0...

The last one is quite interesting in the way it makes you think about
language design, and how what feature and syntax you do or don't provide
effects usage and language evolution.

James


Alexander Kellett

1/8/2005 7:39:00 PM

0

rade wrote:
> def foo(object)
> return object.call(9, 7, 3)
> end
>
> couldn't the type system figure out that object must respond to the
> call
> command and thus eliminate an error like:
>
> foo(5)

i see no difficulty in using ruby's advanced tracing
facilities to improve documentation and via persistant
storage of such api metadata also adding an "early warning"
system. or rather, not so much early warnings, but more much
more obvious error messages as opposed to wierd 'ugh ur meant
to quack!' style messages ;)

unfortunately i don't have the time :(

> I guess I am also wondering about a lot of other things like why do
> you need
> multiple assignment in Ruby? There doesn't seem to be any need for it
> since
> you can just modify an object by sending it a message eg x = x + 1 is
> the
> same as x.+(1). [snip]

multiple return values and multiple assignment just fit well together
imho :)
without it i'd almost certainly be forced to fork the interpreter :P

i'd be very interested in type inference for
another reason:
intelligent code completion
with tooltips offering details on
method documentation and param/return value
typing expectations

greetings,
Alex



Trevor Andrade

1/8/2005 8:28:00 PM

0

Let me just point out that I am NOT ADVOCATING STATIC TYPING. I don't think
ruby should force users to static type. I am also not advocating any
changes whatsoever to the language Ruby with one exception and that is
multiple assignment which I don't see any need for. I could, of course, be
wrong and if anybody knows a good example where multiple assignment makes
things easier I could easily be persuaded that it is useful. I guess the
only reason for preserving multiple assignment that I can think of is to
preserve idioms like x = x + 1 which as pointed out is different from
x.+(1). You could of course make x = x + 1 translate into x.+(1) as a bit
of syntactic sugar but that might lead to other problems. Type inference is
something that would exist in the interpreter as some kind of error
messages. You could turn it off if necessary. I think that in most cases
it would be helpful in that it would catch real errors and I believe
although I can't prove this that any ruby program at all no matter how
dynamic would pass through the type inference system without any error
provided it did not have any statement that if executed would lead to an
error of the form "NoMethodError: undefined method 'foo' for someobject".
This of course is the error you get when you call a method on an object that
does not have that method defined.

In a dynamic language like Ruby errors of the form I alluded to above are
the only type errors that I believe are in general possible. I have a very
simple model for object oriented language like Ruby which is probably wrong
but I think ultimately captures the gist of things. In Ruby or Smalltalk
you can only essentially do one thing and that is send messages to objects.
Everything in Ruby consists of essentially message passing. Thus the only
error possible is that an object does not know how to respond to a message.
Of course my model is not completely correct because ultimately in any
language you have to actually "do something" at some point. For instance if
you want to add 2 numbers or concatenate a string that is "doing something"
and not just message passing. However the "doing something" part of Ruby
and Smalltalk only exists either at the lowest levels of the language that
are built in or in extensions to the language written in c. You cannot
define how to add integers in Ruby and in fact you cannot even define
integers themselves. Integers are low level constructs that must be built
into the language. You can still even do type inference at this low level
because the number of low level object are finite and the built in
operations you can do with them are already defined like for instance adding
integers or concatenating strings. So it always known that you can't add an
integer to a string and this can always produce an error before runtime
which currently does not happen. For instance you can run the following in
ruby and it is valid

def ass(blah)
q = 4 + "fjdkjkf"
end

and I this error will be caught only at runtime.

There is only one thing wrong with type inference and that is that new
methods can be defined at runtime in Ruby which means it is possible that an
object does not know how to respond at compile time to a message but it does
know how to respond at runtime. However I think this scenario happens very
rarely and if it was happening the programmer could just turn off type
inference.




Trevor Andrade

1/8/2005 8:53:00 PM

0

Alexander Kellet wrote:

>> multiple return values and multiple assignment just fit well together
>> imho :)

I was just wondering how do they fit together? Are you talking about
multiple assignment as in:

X = 1
X = 2

Or as in

X, Y = foo(blah)

Where foo is define as

def foo()
return 1, 2
end

I think was a bit ambiguous in my email so let me make myself clear. The
term multiple assignment is used in two situation or at least I use it in
two situations. In one situation a variable is assigned to and then
assigned to again. In the other situation, two variable are assigned to at
the same time. Both these situations are called multiple assignment. I am
referring to the first situation. I believe you are referring to the
second. I have no problem with the second situation. It is the first that
I believe is unnecessary. Unless I am missing something and the two kinds
of multiple assignment are some how related.




Alexander Kellett

1/8/2005 10:03:00 PM

0

On Jan 8, 2005, at 9:53 PM, Trevor Andrade wrote:
> I think was a bit ambiguous in my email so let me make myself clear.
> The
> term multiple assignment is used in two situation or at least I use it
> in
> two situations. In one situation a variable is assigned to and then
> assigned to again. In the other situation, two variable are assigned
> to at
> the same time. Both these situations are called multiple assignment.
> I am
> referring to the first situation. I believe you are referring to the
> second. I have no problem with the second situation. It is the first
> that
> I believe is unnecessary. Unless I am missing something and the two
> kinds
> of multiple assignment are some how related.

i can't really explain.
but it just feels right.
maybe the ruth/ast will help u see why:
irb(main):003:0> Ruby.parse 'def mult_ret; return 1, 5; end'
=> Def[:mult_ret, [], Return[ArrayLiteral[[IntegerLiteral[1],
IntegerLiteral[5]]]]]
and
irb(main):007:0> Ruby.parse 'a, b = nil, nil'
=> Masgn[ArrayLiteral[[LocalAssign[:a, nil], LocalAssign[:b, nil]]],
nil, ArrayLiteral[[NilLiteral[], NilLiteral[]]]]
(notice the use of ArrayLiteral as return and ArrayLiteral in
multi-assign)

for a more concrete and useful example.
consider this:
a, b = b, a

Alex



Alexander Kellett

1/8/2005 10:20:00 PM

0

On Jan 8, 2005, at 9:53 PM, Trevor Andrade wrote:
> I think was a bit ambiguous in my email so let me make myself clear.
> The
> term multiple assignment is used in two situation or at least I use it
> in
> two situations. In one situation a variable is assigned to and then
> assigned to again. In the other situation, two variable are assigned
> to at
> the same time. Both these situations are called multiple assignment.
> I am
> referring to the first situation. I believe you are referring to the
> second. I have no problem with the second situation. It is the first
> that
> I believe is unnecessary. Unless I am missing something and the two
> kinds
> of multiple assignment are some how related.

having reread this i must say i'm greatly confused
why would anyone want to use
x = 1
x = 2
?
or u mean constants in particular?
a very confused Alex ;)



Alexander Kellett

1/8/2005 10:26:00 PM

0

On Jan 8, 2005, at 9:28 PM, Trevor Andrade wrote:
> You cannot define how to add integers in Ruby and in fact you cannot
> even define
> integers themselves. Integers are low level constructs that must be
> built
> into the language. [snip]

its possible to redefine integer additions in ruby.
however yes you're correct in saying that its not possible
to redefine the integer constructor. (tho i'm working
on making that possible ;))

> There is only one thing wrong with type inference and that is that new
> methods can be defined at runtime in Ruby which means it is possible
> that an
> object does not know how to respond at compile time to a message but
> it does
> know how to respond at runtime. However I think this scenario happens
> very
> rarely and if it was happening the programmer could just turn off type
> inference.

i think personally that test suites should guide typing metadata.
if a testcase only has a test for a single data type. then the
assumption can be made that the type itself is required. if however
it has a test for two different data types each of which have a given
method, which happens to be part of an included module, to ease test
case writing it should be possible via comment hints to show the
inferrer / document-type-metadata-hinter that it is duck typed not
static typed.

Alex



Trevor Andrade

1/8/2005 11:16:00 PM

0

That example was just intended to demonstrate the difference between the two
definition of multiple assignment. I wasn't meant to do something..

-----Original Message-----
From: Alexander Kellett [mailto:ruby-lists@lypanov.net]
Sent: Saturday, January 08, 2005 5:20 PM
To: ruby-talk ML
Subject: Re: Type inference in ruby

On Jan 8, 2005, at 9:53 PM, Trevor Andrade wrote:
> I think was a bit ambiguous in my email so let me make myself clear.
> The
> term multiple assignment is used in two situation or at least I use it
> in
> two situations. In one situation a variable is assigned to and then
> assigned to again. In the other situation, two variable are assigned
> to at
> the same time. Both these situations are called multiple assignment.
> I am
> referring to the first situation. I believe you are referring to the
> second. I have no problem with the second situation. It is the first
> that
> I believe is unnecessary. Unless I am missing something and the two
> kinds
> of multiple assignment are some how related.

having reread this i must say i'm greatly confused
why would anyone want to use
x = 1
x = 2
?
or u mean constants in particular?
a very confused Alex ;)