From: Jim Freeze Date: 2010-09-27T22:46:41+09:00 Subject: [ruby-core:32586] Re: Proposal for Optional Static Typing for Ruby --0015175d672030e44504913df5e4 Content-Type: text/plain; charset=ISO-8859-1 Hi This sounds interesting, but appears to only provide 'type' checking on args. Since Ruby objects can have mixins and singletons, method checking would not work. Consider the case below, where x and y are Arrays, can this type checking help me enforce #bark on Array? x = Array.new y = Array.new def y.bark "bark" end p y.bark p y.class On Mon, Sep 27, 2010 at 6:58 AM, Martin Pilkington wrote: > Hi, > > 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). > > First off, I want to explain who I am. I've been an Objective-C developer > for the past 6 years on the Mac and iOS and have used various languages such > as PHP, Python, Java etc. In the past year I've been trying to get into > Ruby. After several false starts where I've simply not had time I've managed > to make some pretty good progress. I love Ruby's functionality and how > dynamic it is, as it is very close to how I've worked the past 6 years with > my Objective-C development. As with any language there are some things that > I want to see in other languages (symbols, mixins, almost any character in > method names etc) and some things I would like to see brought from other > languages. > > I give this suggestion, not because I don't want to do things the "ruby" > way, but because I genuinely believe that it can help make ruby better, by > aiding in the development of tools that in turn aid developers in writing > code faster and with fewer mistakes. > > > If any of you have used Objective-C, you will have likely encountered two > things. In terms of objects it is duck typed, yet it also offers static > typing. Now there are many differing opinions on static typing. Some believe > everything should be statically typed and to do otherwise is to allow for > errors in your code. Some believe everything should be duck typed and that > with careful coding and testing you can have lots of flexibility with few, > if any errors. To a very large degree I am in the latter camp. However, I > also see the benefits of static typing and how it can help developers > explicitly state assumptions and as such help developers test those > assumptions. > > For those who haven't used Objective-C, I'll give a quick overview of how > it handles typing. Due to its C heritage it is largely statically, but > weakly typed. If you use any C types then you obviously need to type them as > int, float etc. Objective-C adds a few other types to this, but the key one > is the id type. The id type essentially means "anything that is an object". > The reason this exists is because you can have non-object types, so there > needs to be differentiation. In a sense, in Ruby everything is of the data > type "object", and so there is no need to explicitly state this. > > But Objective-C also has optional static typing for objects. This is used > by the compiler and other tools to perform checks and warn you if something > may be wrong. It is thrown away afterwards and doesn't exist in the runtime. > Much like Ruby, the only way to find out the type of an object at runtime is > to ask it for its class. If you don't want to use this you can just write > everything as id and treat id almost as a keyword for declaring a variable, > sort of like var in javascript. > > So why should Ruby get this? Well the best way to answer that is to > describe some of things that languages with some degree of static typing > have. The first off is pre-runtime checking of code. Have you misspelt a > method or a variable? Did you call a method on an object but forget to > implement it? These things can be warned of before you run your code, and > they can also be run over your entire code. Related to this is general > static analysis, where while not only checking for syntax errors, it can > also check for common bugs and inform you about code paths that are never > run, either because they aren't needed and you haven't yet removed them or > because you're not doing something correctly. > > Then you have editing tools such as refactoring and autocomplete. > Refactoring can be much more reliable if it knows what types it is dealing > with. If you wanted to rename a method for example, there may be similarly > named methods on multiple classes which are called throughout your code, but > you only want to rename the calls on instances of your object. And > autocomplete becomes more than filtering a list of method names that have > the same prefix as what you have currently typed, if it knows the class of > the object you're calling the method on then it can severely narrow that > down, and often provide you the correct result first time, meaning less > typing. > > > There were some questions that were asked on #ruby-lang and I thought I > would answer them here as you may also have the same questions: > > 1. What if I don't want typing? > The idea would be that this is completely optional, like much of Ruby's > syntax. In Ruby if you don't want () around your method arguments you don't > need them, if you do you can add them in. In this case, if you want to write > these types you can do, if not then you don't. You can also use typing up > until the point where it gets in the way, at which point you ignore it. Much > like with Objective-C, except the general object type is implied by default > in Ruby. > > 2. Why not just use Diamondback Ruby or Mirah or some other similar system? > These are interesting projects, but they have downsides. For one, I want to > use Ruby and all of the APIs that come with it. Rather than an entirely new > language and runtime, I'm talking about adding one thing to the language > grammar. I also don't want to add any sort of runtime checking. Code would > run exactly the same, as type information would be discarded when the code > is compiled, but it would allow for useful information for other tools at > development time. Lastly, I'd like to see it as a full language construct > rather than comments. > > 3. Why not use comments? > It could be done via comments, but then a standard comment format has to be > required and it is putting language data into what should be documentation. > By doing this as a language feature it sets a standard way of writing them > and keeps code separate from comments. > > 4. What is the point given that there is no full compilation before hand? > If all you do is write code and run it, none. While this is often how > people write small scripts, it isn't how people write applications. They > also have test suites that they run against it their application and text > editors and IDEs that they use to code this. The benefit is that the type > information can be used to create tools that run some tests for you and help > you write code. To give an example from elsewhere in life, when things are > constructed in remote places, such as dams or wind turbines, roads need to > be built up to them. They aren't actually part of the construction, but > they're needed to help the tools such as diggers, cranes and workers get > there quickly and safely. > > 5. What help is it if you can choose not to use it when static typing gets > in the way? > Yes, in cases where you don't use the typing then there is limited help > from auto complete or refactoring or static analysis. Autocomplete would > default to offering a basic filtered list, static analysis could take a > guess but may be wrong and refactoring may have to resort to asking you to > confirm. However, you find that the times that static analysis really gets > in the way are relatively few. Just because 5% of the time something doesn't > work doesn't mean that it may not be well worth it for the 95% of the time > it can. > > 6. How would you implement it in the language? > This is the trickiest part: what does the syntax look like. As someone > pointed out in #ruby-lang, C style typing is out as 'String foo = "bar"' is > another way of writing 'String(foo = "bar")'. I have come up with an idea > for the syntax, which from what I can tell wouldn't clash with any existing > syntax. I demonstrate it below by creating a variable and defining a method > (note that you would only have to type a variable once): > > my_integer = "42".to_i > > def to_i( base = 10) > end > > Now the above would be absolutely no different at runtime to the Ruby today > of: > > my_integer = "42".to_i > > def to_i(base = 10) > end > > If you wanted you could mix and match: > > my_integer = "42".to_i > > def to_i( base = 10) > end > > And to give an example of where static typing gets in the way, take > returning the first object of an array. The array can hold any objects so > you can't know the type but the first method generally takes an integer > argument, so could be defined as: > > def first( n) > end > > So any tool can check the input is in fact an integer, but there is no > return type given so it assumes it can be any type. Now in cases like this > it can be combined with a variable with a type, so while the tools can't say > what you're assigning is the correct type of object, they can work on the > assumption that it is the type of object you said and so it can make sure > that you aren't doing anything 'wrong' with that object later on. For > example: > > my_array = ["foo", "bar", "baz"] #Can check the assignment > of myArray > my_string = my_array.first #Can check that > myArray responds to first but not that it returns a string > my_string.map {|item| item.do_something} #As we are assuming aString > is in fact a string, we can tell it may not respond to map (given the nature > of message sending we can't be 100% sure, but in the vast majority of > occasions it will be the case) and warn the user > > Of course, this is just my suggestion for the syntax, there are others out > there who have different ideas for a type syntax for ruby and there may be > others on this list. > > > A final question some of you may be thinking, but which wasn't asked on > #ruby-lang: > > 7. Do you have a vested interest? > Yes. I want to invest time in learning Ruby so that I can write software > with it. I've not got masses of experience with it yet, but I know already > it is as fun to use as my current staple language, Objective-C. There's also > that I want to invest time in becoming part of a community that to some > degree has wildly differing opinions on software development to what I'm > used to, so hopefully some of those opinions will rub off on me and I can > apply what I think makes sense to coding elsewhere. Finally, if I'm going to > invest time in a platform then I want to be able to invest in great tools, > whether that means buying and/or learning existing ones, or writing new ones > myself. It is this last point which is why I'm writing this email as I > believe what I've proposed could help me or others create these great tools. > > > Hopefully I've at least given you something to think about. If you do have > any questions I'd be happy to answer them. And thanks for spending your time > reading this. > > Martin Pilkington > -- Jim Freeze --0015175d672030e44504913df5e4 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Hi

This sounds interesting, but appears to only provide 'type= 9; checking on args. Since Ruby objects can have mixins and singletons, met= hod checking would not work. Consider the case below, where x and y are Arr= ays, can this type checking help me enforce #bark on Array?

x =3D Array.new
y =3D Array.new
def y.bark
=A0 "bark"= ;
end

p y.bark
p y.class


On Mon, Sep 27, 2010 at 6:58 AM, Martin Pilkington <<= a href=3D"mailto:pilky@mcubedsw.com">pilky@mcubedsw.com> wrot= e:
Hi,

I know this is my first post on this list and that I'm relatively new t= o 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).

First off, I want to explain who I am. I've been an Objective-C develop= er for the past 6 years on the Mac and iOS and have used various languages = such as PHP, Python, Java etc. In the past year I've been trying to get= into Ruby. After several false starts where I've simply not had time I= 've managed to make some pretty good progress. I love Ruby's functi= onality and how dynamic it is, as it is very close to how I've worked t= he past 6 years with my Objective-C development. As with any language there= are some things that I want to see in other languages (symbols, mixins, al= most any character in method names etc) and some things I would like to see= brought from other languages.

I give this suggestion, not because I don't want to do things the "= ;ruby" way, but because I genuinely believe that it can help make ruby= better, by aiding in the development of tools that in turn aid developers = in writing code faster and with fewer mistakes.


If any of you have used Objective-C, you will have likely encountered two t= hings. In terms of objects it is duck typed, yet it also offers static typi= ng. Now there are many differing opinions on static typing. Some believe ev= erything should be statically typed and to do otherwise is to allow for err= ors in your code. Some believe everything should be duck typed and that wit= h careful coding and testing you can have lots of flexibility with few, if = any errors. To a very large degree I am in the latter camp. However, I also= see the benefits of static typing and how it can help developers explicitl= y state assumptions and as such help developers test those assumptions.

For those who haven't used Objective-C, I'll give a quick overview = of how it handles typing. Due to its C heritage it is largely statically, b= ut weakly typed. If you use any C types then you obviously need to type the= m as int, float etc. Objective-C adds a few other types to this, but the ke= y one is the id type. The id type essentially means "anything that is = an object". The reason this exists is because you can have non-object = types, so there needs to be differentiation. In a sense, in Ruby everything= is of the data type "object", and so there is no need to explici= tly state this.

But Objective-C also has optional static typing for objects. This is used b= y the compiler and other tools to perform checks and warn you if something = may be wrong. It is thrown away afterwards and doesn't exist in the run= time. Much like Ruby, the only way to find out the type of an object at run= time is to ask it for its class. If you don't want to use this you can = just write everything as id and treat id almost as a keyword for declaring = a variable, sort of like var in javascript.

So why should Ruby get this? Well the best way to answer that is to describ= e some of things that languages with some degree of static typing have. The= first off is pre-runtime checking of code. Have you misspelt a method or a= variable? Did you call a method on an object but forget to implement it? T= hese things can be warned of before you run your code, and they can also be= run over your entire code. Related to this is general static analysis, whe= re while not only checking for syntax errors, it can also check for common = bugs and inform you about code paths that are never run, either because the= y aren't needed and you haven't yet removed them or because you'= ;re not doing something correctly.

Then you have editing tools such as refactoring and autocomplete. Refactori= ng can be much more reliable if it knows what types it is dealing with. If = you wanted to rename a method for example, there may be similarly named met= hods on multiple classes which are called throughout your code, but you onl= y want to rename the calls on instances of your object. And autocomplete be= comes more than filtering a list of method names that have the same prefix = as what you have currently typed, if it knows the class of the object you&#= 39;re calling the method on then it can severely narrow that down, and ofte= n provide you the correct result first time, meaning less typing.


There were some questions that were asked on #ruby-lang and I thought I wou= ld answer them here as you may also have the same questions:

1. What if I don't want typing?
The idea would be that this is completely optional, like much of Ruby's= syntax. In Ruby if you don't want () around your method arguments you = don't need them, if you do you can add them in. In this case, if you wa= nt to write these types you can do, if not then you don't. You can also= use typing up until the point where it gets in the way, at which point you= ignore it. Much like with Objective-C, except the general object type is i= mplied by default in Ruby.

2. Why not just use Diamondback Ruby or Mirah or some other similar system?=
These are interesting projects, but they have downsides. For one, I want to= use Ruby and all of the APIs that come with it. Rather than an entirely ne= w language and runtime, I'm talking about adding one thing to the langu= age grammar. I also don't want to add any sort of runtime checking. Cod= e would run exactly the same, as type information would be discarded when t= he code is compiled, but it would allow for useful information for other to= ols at development time. Lastly, I'd like to see it as a full language = construct rather than comments.

3. Why not use comments?
It could be done via comments, but then a standard comment format has to be= required and it is putting language data into what should be documentation= . By doing this as a language feature it sets a standard way of writing the= m and keeps code separate from comments.

4. What is the point given that there is no full compilation before hand? If all you do is write code and run it, none. While this is often how peopl= e write small scripts, it isn't how people write applications. They als= o have test suites that they run against it their application and text edit= ors and IDEs that they use to code this. The benefit is that the type infor= mation can be used to create tools that run some tests for you and help you= write code. To give an example from elsewhere in life, when things are con= structed in remote places, such as dams or wind turbines, roads need to be = built up to them. They aren't actually part of the construction, but th= ey're needed to help the tools such as diggers, cranes and workers get = there quickly and safely.

5. What help is it if you can choose not to use it when static typing gets = in the way?
Yes, in cases where you don't use the typing then there is limited help= from auto complete or refactoring or static analysis. Autocomplete would d= efault to offering a basic filtered list, static analysis could take a gues= s but may be wrong and refactoring may have to resort to asking you to conf= irm. However, you find that the times that static analysis really gets in t= he way are relatively few. Just because 5% of the time something doesn'= t work doesn't mean that it may not be well worth it for the 95% of the= time it can.

6. How would you implement it in the language?
This is the trickiest part: what does the syntax look like. As someone poin= ted out in #ruby-lang, C style typing is out as 'String foo =3D "b= ar"' is another way of writing 'String(foo =3D "bar"= )'. I have come up with an idea for the syntax, which from what I can t= ell wouldn't clash with any existing syntax. I demonstrate it below by = creating a variable and defining a method (note that you would only have to= type a variable once):

<Integer> my_integer =3D "42".to_i

def <Integer> to_i(<Integer> base =3D 10)
end

Now the above would be absolutely no different at runtime to the Ruby today= of:

my_integer =3D "42".to_i

def to_i(base =3D 10)
end

If you wanted you could mix and match:

my_integer =3D "42".to_i

def <Integer> to_i(<Integer> base =3D 10)
end

And to give an example of where static typing gets in the way, take returni= ng the first object of an array. The array can hold any objects so you can&= #39;t know the type but the first method generally takes an integer argumen= t, so could be defined as:

def first(<Integer> n)
end

So any tool can check the input is in fact an integer, but there is no retu= rn type given so it assumes it can be any type. Now in cases like this it c= an be combined with a variable with a type, so while the tools can't sa= y what you're assigning is the correct type of object, they can work on= the assumption that it is the type of object you said and so it can make s= ure that you aren't doing anything 'wrong' with that object lat= er on. For example:

<Array> my_array =3D ["foo", "bar", "baz&quo= t;] =A0 =A0 =A0 =A0#Can check the assignment of myArray
<String> my_string =3D my_array.first =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 #Can check that myArray responds to first but not that it returns = a string
my_string.map {|item| item.do_something} =A0 =A0 =A0 =A0#As we are assuming= aString is in fact a string, we can tell it may not respond to map (given = the nature of message sending we can't be 100% sure, but in the vast ma= jority of occasions it will be the case) and warn the user

Of course, this is just my suggestion for the syntax, there are others out = there who have different ideas for a type syntax for ruby and there may be = others on this list.


A final question some of you may be thinking, but which wasn't asked on= #ruby-lang:

7. Do you have a vested interest?
Yes. I want to invest time in learning Ruby so that I can write software wi= th it. I've not got masses of experience with it yet, but I know alread= y it is as fun to use as my current staple language, Objective-C. There'= ;s also that I want to invest time in becoming part of a community that to = some degree has wildly differing opinions on software development to what I= 'm used to, so hopefully some of those opinions will rub off on me and = I can apply what I think makes sense to coding elsewhere. Finally, if I'= ;m going to invest time in a platform then I want to be able to invest in g= reat tools, whether that means buying and/or learning existing ones, or wri= ting new ones myself. It is this last point which is why I'm writing th= is email as I believe what I've proposed could help me or others create= these great tools.


Hopefully I've at least given you something to think about. If you do h= ave any questions I'd be happy to answer them. And thanks for spending = your time reading this.

Martin Pilkington



--
Jim Freeze
--0015175d672030e44504913df5e4--