Hi,

I'm not sure talking about tools is really useful here. It's fairly 
obvious what kind of tooling you can have with type support, and there 
are many static languages that have in their arsenal a set of tools for 
type-checking. I don't think Ruby needs to go there. Even if it did, the 
benefits of tooling are only tangential to the practical benefits of 
what the compiler/interpreter can do with annotated type information at 
run-time.

Let's look at this in a more immediate context. There are a few 
real-world Ruby idioms that work around the lack of type information in 
the language. Specifically, I'm thinking of method overloading (or the 
lack thereof) and run-time type-checking. These are two issues that, as 
far as I know, people spend many a minute hacking poorer solutions to, 
because the language is limiting.

1) When it comes to overloading, the current solution is to write some 
kind of "case" switch or "is_a?"/"respond_to?" checks on classes/method 
names, and then dispatching the correct code. Something like:

     def run(server)
       case server
         when Hash;  Server.new(server).start
         when Server; server.start
       end
     end

We've all seen and written these methods before. They're annoying to 
write, they're even harder to document. Why couldn't we just do (forgive 
me, I'm using a different syntax to that which was proposed in this thread):

     def run(opts: Hash)
       Server.new(opts).start
     end

     def run(server: Server)
       server.start
     end

Before all the duck-typists go nuts, there's no reason why you couldn't 
specify a duck-type here.

2) Run-time type-checking would have the same benefits. Right now, there 
is a lot of code that will check an argument type and then manually 
raise ArgumentError. Why can't we just offload this to the method 
dispatcher in the interpreter itself?

     def format(argument: #to_name)
         puts argument.to_name
     end

All of the manual exception raising and checking is now hidden, and the 
method looks clean and obvious. Since typing is optional, the 
compiler-invoked type-checking would only occur on methods written in 
this fashion. Optionally you could have the interpreter disable 
type-checking globally on methods, if you wanted performance. In fact, 
if a library used this setup, they would effectively have a way to 
switch off all type checking for performance. Right now, whenever anyone 
manually adds an "raise unless arg.respond_to?" statement in their code, 
there is no way to switch it off. I'm unsure how anyone could argue that 
this kind of functionality, which is only available by annotating types 
for the interpreter, is a bad thing.

Finally, type information is worthwhile if for nothing else than 
documentation purposes. The ability to introspect a parameter and get a 
type, for instance, could go a long way to building automated run-time 
type checking libraries, even if the compiler did not support it 
implicitly. For example, given,

     def foo(x: Fixnum) ... end

Accessing method(:foo).parameters[:x].type could be used to introspect 
expected types. The signature is also self-documenting, and we no longer 
need to come up with RDoc or even complicated YARD syntax to document 
this code. This, by the way, is where we start getting into tooling. As 
I mentioned, these benefits are less immediate, but there are some 
useful code analysis tools that can be built around such type 
information (doc tools, data flow, type checkers).

- Loren

On 9/28/2010 7:52 AM, Asher wrote:
> Martin,
>
> With respect, I think you're considering this backwards, attempting to adjust Ruby in order to address how you're used to dealing with language.
>
> As I see it, one of the major advantages of Ruby is its flexibility, insofar as it figures out for you many details (such as implicit typing). One of the major disadvantages of Ruby is that it has to figure out all of these details. In other words, attempting to satisfy both the advantages and disadvantages of typing in this way is likely to do little other than amplify the disadvantages of Ruby (primarily the underlying weight of the VM) as well as the disadvantages of typing (having to specify details everywhere, having to update details in multiple places for minor changes, etc.)
>
> So you say "reliable, powerful tools" - why does this correspond to typing in any way?
>
> I think instead we should be asking what "powerful" and "reliable" mean in a programming context where typing is not the primary emphasis. What is a hardened Ruby program? I think this is worth asking, but I don't think it's a question whose answer is barred by way of any relation to typing.
>
> Some languages (PHP?) have dealt with this by using "type hints", but I think this simply encourages the wrong approach, emphasizing explicit typing over patterns that are not type-reliant. For instance (as many web pages/blogs will attest), a common pattern for Ruby-newbies is first Class checking, and second method response checking. While there are (rare) appropriate applications for these tests, most of the time they are misplaced and are symptoms of a view of language that comes from somewhere other than Ruby.
>
> Perhaps we would be better served by talking about what sorts of tools we desire. "Reliable" is obvious enough, but what of "powerful"? How are we to define this aspect of tools, particularly regarding Ruby specifically?
>
> So some questions:
>
> 1. What tools should exist?
>
> 2. Which of these tools don't yet exist or should exist with better implementations?
>
> 3. What is the inherent relation of these tools to typing?
>
> I think that much of what we are dealing with here is what I would call a distinction between meta-programming languages and memory-programming languages. Ruby is not a memory-oriented programming language, but a meta- oriented programming language. The functionality of Ruby has far more to do with contingent context elaborated at a run-point in the program context than it does with the mapping of code structures to computer (memory) structures. In other words, the brilliance of Ruby is that the code is not about how the computer works, but is about how the objects work (which require no inherent relation to the computer itself or to their particular mode of storage in memory). This seems to me to deal first and foremost with "getting away" from types while nevertheless retaining the underlying benefits that types provide (albeit mostly invisibly).
>
> Best,
> Asher
>
>
> On Sep 28, 2010, at 6:53 AM, Martin Pilkington wrote:
>
>> Hi Matz
>>
>> Thanks for the reply. I full agree with you (and Alan Kay) that typing can be a pain, though due to benefits in more accurate and effective tools there are advantages to it. If there was a way to easily and reliably get tools as powerful as languages with static typing without the need for the typing then I'd be all for it as I love using duck typed languages and the freedom they give.
>>
>> I did consider structural typing and it could be a route to go down. Ultimately I'm just wanting a better way for me and others to build reliable, powerful tools for Ruby, regardless of how that is approached. I did hit a snag when considering structural typing though, which may be due to my relative inexperience with structural typing, so you might be able to help with a solution.
>>
>> Obviously structural typing is great at easily working out whether two objects are technically interchangeable, whether or not they conceptually are. However, while you can say that a String object is simply one that has methods +,<<, concat, length, split, sub etc, it's somewhat harder to say what the argument and return types of those methods are (of course that is a somewhat bad example given that the return values/types are given for the very base classes and their methods, but you get the idea). This is ultimately the main reason for me wanting some degree of pre-runtime typing (the return types more than the arguments) and I can't see any way to calculate these types without type inference, which itself I see snags with.
>>
>> I'm just wondering if you have any thoughts about getting this method type information? I could just be overlooking something that a fresh (and far more experienced with Ruby) pair of eyes can see, but I'm just struggling a bit with reliable ways to get the type info needed.
>>
>> Thanks
>>
>> Martin
>>
>>
>> On 27 Sep 2010, at 4:29PM, Yukihiro Matsumoto wrote:
>>
>>> Hi,
>>>
>>> In message "Re: [ruby-core:32585] Proposal for Optional Static Typing for Ruby"
>>>    on Mon, 27 Sep 2010 20:58:51 +0900, Martin Pilkington<pilky / mcubedsw.com>  writes:
>>>
>>> |I know this is my first post on this list and that I'm relatively new to the Ruby community, and that this can be a somewhat controversial topic (as I've found by asking about it on the #ruby-lang channel).
>>>
>>> Short response:
>>>
>>> "I'm not against types, but I don't know of any type systems that
>>> aren't a complete pain, so I still like dynamic typing." - Alan Kay
>>>
>>> Static typing surely has its benefit, but on the other hand, Ruby the
>>> language strongly encourages duck typing, so that its type system
>>> should not hinder duck typing.  As a result, the type checking should
>>> be based on structural types, not nominal types.  I don't think your
>>> proposal cares about duck typing or considered structural type
>>> conformance.
>>>
>>> Although I like your<type>  notation, that reminds me the scheme
>>> object system, iff we don't have to write them often.  I don't think I
>>> could stand to write<type>  everywhere.
>>>
>>> 							matz.
>>>
>>
>