The Artima Developer Community
Sponsored Link

Weblogs Forum
Is Static Typing a Form of Bad Coupling?

74 replies on 5 pages. Most recent reply: Apr 23, 2006 1:52 PM by Isaac Gouy

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 74 replies on 5 pages [ 1 2 3 4 5 | » ]
Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Is Static Typing a Form of Bad Coupling? (View in Weblogs)
Posted: Apr 11, 2006 4:43 PM
Reply to this message Reply
Summary
If it is, maybe there's something we can do to decouple static types and the languages which use them.
Advertisement

The battle between static and dynamic typing enthusiasts rages on and on. Java "upped the ante" by introducing generics and increasing the amount of verbiage in our source files. The dynamicists have responded with Rails and various Python frameworks, showing the world that you can write powerful web applications with an extremely small number of keystrokes. Personally, I'm more in the dynamicists camp, but I do think that there are some problems in the dynamic language world and some of them are political.

Let's play out a scenario. You've just graduated from school. You and your best friend look at the landscape and you figure "hey, we're young, let's make a go at this Web 2.0 thing." You sell your bicycle and some aluminum scrap that you find on the side of the road and you have your seed money. You buy a server, a development machine and download Rails. You and your friend code something up and go live in a week. It's flimsy but it works. You have your first users. Now, you're the only programmer. Your friend is sleeping at the door with a shotgun to keep venture capitalists away from you. Your user community grows, and your first big shopper comes by.. a big public company, with people in suits. They want to buy you.. they start doing their diligence.. they walk in and they are amazed that you are running a 50,000 user system on a simple server using a dynamic language, and it's handling real money. Their technical guru turns around and says "We can't buy this! It could have all sorts of errors in it and we'd never know!" You point to your tests, but he's adamant. "They're hackers!!" he whispers, "you can't buy this!"

Far fetched? Probably. Dynamically typed languages are growing in acceptance, but there are many cautious people in this post-Sarbanes Oxley legislation world.

Now, let's put aside the static versus dynamic language debate.. I think everyone on both sides of it will admit that dynamic languages offer some advantages during development. And, most people would agree that there are some times when it would be nice to check some things at compile time. Can we have the best of both worlds?

It turns out we can. Some languages allow optional type declarations. Visual Basic is the most prominent example of this (not that I've seen anyone work with it this way), but you can type a variable as an Object and send it any message. At runtime a lookup function is called it will attempt to resolve the message against the object. If you like static typing, you simply use types when you declare your variables: ''Dim count as Integer''

The interesting thing is, this feature can move us to a different style of development: write your program using dynamic typing, and when things are stable, fill in the types afterward; I imagine it would be like doing a Sudoko puzzle.

But.. there is a problem.. once you fill in the types, they are everywhere. They annotate each variable declaration, all your method arguments.. changing them is a pain. They nail down your program. It's hard to refactor, it's hard to get tests in after the fact. Your program and its types are snarled together.

Let's go back to first principles.. software design principles and apply them to directly to language design. We should consider the idea that static typing, as we currently do it, may be bad coupling. When we litter a program with type annotations, we're tightly binding an error detection scheme to the form of the program. We can't work with the form of the program independently of that error detection scheme. What if we tried to decouple them? What would we end up with?

Take a look at this piece of Ruby code:

class Word
  attr_reader :text

  @@random_number_generator = Proc.new { | exc_upper_bound | (rand * exc_upper_bound).to_i }

  def initialize(words,text,successor)
    @text = text
    @words = words
    @successors = {}
    @words[text] = self unless @words.has_key? text
    @words[text].add_successor(successor)
  end

  def add_successor(successor)
    @successors[successor] = 0 unless @successors.has_key? successor
    @successors[successor] += 1
  end

  def sum_of_successors
    @successors.values.inject(0) {| sum, current | sum + current }  
  end

  def next_position
    scaled_rand(sum_of_successors)
  end

  def scaled_rand(exc_upper_bound)
    @@random_number_generator.call(exc_upper_bound)
  end
  
  ...
  
end

I have in mind exactly the types that I would like to use for each of the variables here, but I hate the idea of putting them in the source. What would happen if I could put them in a separate file like this?

class Word
      text : String
      words : Hash<String,Word>
      successors : Hash<String,Integer>


      def initialize( : Hash<String,Word>, : String, : Word)
      def add_successor( : String)
      def sum_of_successors : Integer
                                                                                                     

Yes, it's ugly. We're repeating outselves. But here's the trick. We don't have to specify everything. Note, for instance, that I didn't give a type declaration for the last method in the class: scaled_rand. It's all optional.

Think it's still bad? Okay, here's the next piece. We can let our IDEs manage things for us. Our IDE can read both files and show us a view where we see the types in the source (if they are present), and we can toggle off their display when we don't want to see them. The compiler will check all of the types for us, but they are independent of the source. We can delete all the types for a particular class if we want to, rename them.. alias them, etc. We can also take the code for the Word class above and give it another set of type signatures in a different program -- we can reuse the form with different types.

I suspect someone has thought of this before, but I haven't researched it. I think it might be a workable way to progressively add static typing to a program on an as-needed basis. What do you think?


Bill Venners

Posts: 2248
Nickname: bv
Registered: Jan, 2002

Re: Is Static Typing a Form of Bad Coupling? Posted: Apr 11, 2006 6:57 PM
Reply to this message Reply
I was doing a bit of research to compose a reply to Michael's post. I remembered Gosling had said something about safety being freedom. So I searched Google for it and one of the hits took me to this page:

http://www.jroller.com/page/bloritsch?entry=james_gosling_asserts_that_safety

And on the page it said something that seemed appropriate to share here:

Unexpected Exception

Roller has encountered and logged an unexpected exception.


That's all the page contained other than a copyright notice. The problem seems to have been temporary, because the page is working now.

Gosling's actual blog entry entitled, "Safety is Freedom" is here:

http://blogs.sun.com/roller/page/jag?entry=safety_is_freedom

And it is a follow-up to this short and thoughtful commentary on the static versus dynamic language debate:

http://blogs.sun.com/roller/page/jag?entry=radlab_scripting_and_scale

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Is Static Typing a Form of Bad Coupling? Posted: Apr 11, 2006 7:11 PM
Reply to this message Reply
What does that mean in relation to decoupling types and programming text? It seems that we could write a program in a dynamic language and end up with it completely static, having all of the benefits of static typing (plus a few others) while keeping the program text free of type annotations.

Bill Venners

Posts: 2248
Nickname: bv
Registered: Jan, 2002

Re: Is Static Typing a Form of Bad Coupling? Posted: Apr 11, 2006 7:22 PM
Reply to this message Reply
> <p>Think it's still bad? Okay, here's the next piece. We
> can let our IDEs manage things for us. Our IDE can read
> both files and show us a view where we see the types in
> the source (if they are present), and we can toggle them
> out when we don't want to see them. Better, we can delete
> all the types for a particular class if we want to, rename
> them.. alias them, etc. We can also take the code for the
> Word class above and give it another set of type
> signatures in a different program -- we can reuse the form
> with different types.</p>
>
I am suspicious that optional typing would be useful. The trouble is that there are two kinds of freedoms provided by these two kinds of languages, and you can't mix one with the other.

Static typing gives you Gosling's "safety is freedom" kind of freedom (see my previous message in this forum). It allows optimizers to do a better job, potentially letting your program run faster. It allows static analyzers to do a better job, helping you find and prevent certain kinds of bugs, helping your IDE perform error-free refactors, and so on.

Dynamic typing gives you a lot of freedom to make changes to classes and objects at runtime. If you add a bunch of methods to an object at runtime in Ruby, say an ActiveRecord from Rails, exactly how would you go back and add a type to it? In Java, it would be a subclass of ActiveRecord, and all the calls into it would be checked. To be able to add type information later to a Ruby program, you'd have to write it like a Java program. That to me makes little sense, because you would not be getting the best of either approach.

A more practical in-between approach might be a static language that does type inference. This allows you to not have to type or look at all the types everywhere, though if you were confused, your IDE could certainly pop up a type for it. Because the language would need to define a type everywhere with no ambiguity. Scala is I think an example of this. It's syntax is quite concise, in part because of type inference, but also because it gives a lot of shorthand ways to get at commonly used functionality. But it is statically typed so I don't expect you'll be able to do the kind of object morphing in Scala that you can do in Ruby. So it isn't really in-between, it is just a more user-friendly static language. I'm still learning about Scala, which is here:

http://scala.epfl.ch/

Lastly, Guido van Rossum wrote some thoughts in his weblog about adding optional static typing to Python at one point:

http://www.artima.com/weblogs/viewpost.jsp?thread=85551

Bill Venners

Posts: 2248
Nickname: bv
Registered: Jan, 2002

Re: Is Static Typing a Form of Bad Coupling? Posted: Apr 11, 2006 7:30 PM
Reply to this message Reply
> What does that mean in relation to decoupling types and
> programming text? It seems that we could write a
> program in a dynamic language and end up with it
> completely static, having all of the benefits of static
> typing (plus a few others) while keeping the program text
> free of type annotations.

Gosling's post had nothing per se to say about decoupling types, it was just something I was looking up when posting my actual reply, in which I suggest that to "write a program in a dynamic language and end up with it completely static," you'd have to write it in a very static way, which would mean you'd miss out on much of the stuff that makes the dynamic language compelling. I just thought it was funny that when I was looking at a post about James Gosling's "Safety is Freedom" idea I got an exception from a JVM. That guy's post is pro-dynamic, so maybe he did it on purpose to make a point. But probably not.

Marc Abramowitz

Posts: 1
Nickname: msabramo
Registered: Apr, 2006

Re: Is Static Typing a Form of Bad Coupling? Posted: Apr 11, 2006 7:35 PM
Reply to this message Reply
I think you're spot on.

Specifying types is an inherent tradeoff between error checking and flexibility. I would argue that for Web apps, especially with the startup scenario that you mentioned, flexibility is much more important.

It seems to me that static typing is more appropriate for traditional software that gets shrink wrapped or placed in a satellite that goes into space. There correctness far outweighs flexibility. The same is probably also true if you are a library developer, where you want your API to be very stable.

Incidentally, another language that seems to have optional typing is Dylan. By default, you get the dynamic typing of Lisp, but you can specify types to constrain things or to assist the compiler in generating efficient code.

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Is Static Typing a Form of Bad Coupling? Posted: Apr 11, 2006 7:41 PM
Reply to this message Reply
> Gosling's post had nothing per se to say about decoupling
> types, it was just something I was looking up when posting
> my actual reply, in which I suggest that to "write a
> program in a dynamic language and end up with it
> completely static," you'd have to write it in a very
> static way, which would mean you'd miss out on much of the
> stuff that makes the dynamic language compelling. I just
> thought it was funny that when I was looking at a post
> about James Gosling's "Safety is Freedom" idea I got an
> exception from a JVM. That guy's post is pro-dynamic, so
> maybe he did it on purpose to make a point. But probably
> not.

Yeah, that is funny. :)

Re writing your program in a static way, though, I wonder.. There would be a hole in this system with regard to creating type on the fly, etc., but I think you can take most programs that don't use those features and make them statically typed if you, for instance, could introduce an interface for each method and then glom them together to make union types for whatever methods a particular calling context needs. Maybe not. It would be interesting to try.

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Is Static Typing a Form of Bad Coupling? Posted: Apr 11, 2006 8:04 PM
Reply to this message Reply
> I am suspicious that optional typing would be useful. The
> trouble is that there are two kinds of freedoms provided
> by these two kinds of languages, and you can't mix one
> with the other.
>
> Static typing gives you Gosling's "safety is freedom" kind
> of freedom (see my previous message in this forum). It
> allows optimizers to do a better job, potentially letting
> your program run faster. It allows static analyzers to do
> a better job, helping you find and prevent certain kinds
> of bugs, helping your IDE perform error-free refactors,
> and so on.

Yes, but if I remember correctly, the developers of C-omega and VB9 were looking at stronger roles for dynamic typing, and all commonly used static typing schemes do have holes in them.

In any case, I think I made a mistake in framing this idea in the context of dynamic vs. static. The thing I was proposing could also be used in program where static types are mandatory past a certain point in development. It could be a compiler switch.

The thing we could get if we decouple types from program text is a degree of freedom that we don't have when they are mixed in the language. Like the example that I gave above, you could have code for a class in one file and use two different type annotation files for it in two different programs. I suspect an IDE could add the construction of these files by attempting to infer types. In cases where they couldn't, they could query us to select from a set of candidate types or introduce another.

Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: Is Static Typing a Form of Bad Coupling? Posted: Apr 11, 2006 11:20 PM
Reply to this message Reply
Optional typing is in plenty of languages, Haskell, Clean, ML, Scala, Fortress, etc. The inventors of these languages, user guides, etc. normally advice you to declare the types for function arguments, but not to bother for local variables. The reason for declaring types for functions is that the types are a nice peice of information for someone wanting to use the function and it enables overloading.

For example in a numerical API an add method is ambiguous for:
d = 1.5
i = 2
i.add( d )

Does the above produce: 3.5 or 3 or Error. With typing you can distinguish cleanly between the cases and allow the user of add to select which one they want.

Just to 'stir the pot' a bit and to 'show my colours':

0. I use: typed languages; e.g. Java, optionally typed languages; e.g. Haskell, and dynamically typed languages; e.g. Matlab.

1. I find I really need a declaration line, otherwise it is too easy to make a silly typo and that the typo declares a new variable instead of throwing an error. E.g. I don't like:
someVariableName = 1
...
someVariableName = someVariebleName + 1 // No error :(

Not throwing an error (there is a typo). Therefore I prefer:
var someVariableName = 1
...
someVariableName = someVariebleName + 1 // ERROR

Then I don't think it is that much different from:
int someVariableName = 1
...
someVariableName = someVariebleName + 1 // ERROR


2. Type systems can become too fine grained in their control and then their value is diminished, e.g. is:
void makeEmpty( List< ? super HashSet > l, int i ) {
   l.set( i, new HashSet() );
}
...
List< LinkedHashSet > l = new ArrayList< LinkedHashSet >();
l.add( new LinkedHashSet() );
makeEmpty( 0, l ); // Compiletime error 

Really worth the trouble! How often does:
void makeEmpty( HashSet[] l, int i ) {
   l[ i ] = new HashSet();
}
...
LinkedHashSet[] l = new LinkedHashSet[ 1 ];
makeEmpty( 0, l ); // Runtime error 

Actually happen? (LinkedHashSet extends HashSet in Java.)

3. I find a strong correlation between: wanting to use a scripting language and:

A. Not wanting to test the program

B. Not wanting to write documention

C. Using every feature of the language in every program (to the point where simple features are shunned and something that saves a line but is hardly used by other programmers is favoured). Think: APL one line challenges.

This is possibly why scripting languages have a bad reputation.

4. Initial write speed is far from the dominant cost of a program. Far longer is spent maintaining that program and the advantages of no type declarations in that case a far from proven (in my experiance).

5. The error messages without typing information can be very obscure and can be a long way from the problem, e.g. C++ templates.

6. Python is thinking of adding type information, see Guido's latest few post on Artima, e.g.:

http://www.artima.com/weblogs/viewpost.jsp?thread=155514

Bill Venners

Posts: 2248
Nickname: bv
Registered: Jan, 2002

Re: Is Static Typing a Form of Bad Coupling? Posted: Apr 12, 2006 1:22 AM
Reply to this message Reply
> Optional typing is in plenty of languages, Haskell, Clean,
> ML, Scala, Fortress, etc. The inventors of these
> languages, user guides, etc. normally advice you to
> declare the types for function arguments, but not to
> bother for local variables. The reason for declaring types
> for functions is that the types are a nice peice of
> information for someone wanting to use the function and it
> enables overloading.
>
I don't know much about the languages you listed, though I have been reading about Scala this week, and I don't see that it has optional typing. As far as I can see, what's optional is whether you need to explicitly specify the type. If the compiler can infer it from context, then you don't have to specify.

What I don't understand about how optional typing would work is if the types aren't everywhere, then exactly what do they mean? For example, if I must declare types for function args, but need not for local variables, does that mean I can't use a local variable as a parameter in a call to a function? Because the local variable doesn't have a type, but the function arg does. That seems draconian, but if you say you can use a local variable to pass a value to a function, then that means the value need not be the specified type. Which means the type means nothing I can count on. How does that work?

Oh wait, does it mean that at runtime I check the type? Ah. That might make sense. Is that what they do?

Tom Moertel

Posts: 2
Nickname: tmoertel
Registered: Apr, 2006

Re: Is Static Typing a Form of Bad Coupling? Posted: Apr 12, 2006 1:24 AM
Reply to this message Reply
> But.. there is a problem.. once you fill in the types,
> they are everywhere. They annotate each variable
> declaration, all your method arguments.. changing them is
> a pain. They nail down your program. It's hard to
> refactor, it's hard to get tests in after the fact. Your
> program and its types are snarled together.

This is mostly a solved problem in languages such as Haskell that have powerful type systems featuring type inference. For example, here are two small programs I wrote recently:

http://blog.moertel.com/articles/2006/04/05/the-bowling-game-kata-in-haskell
http://blog.moertel.com/articles/2006/03/23/the-perfect-shuffles-puzzle-solved-in-haskell

All types were checked at compile time, and yet I didn't have to pay an annotation tax.

In contrast, Java-style type checking is confining and syntactically expensive -- the worst-case scenario. For this reason, it's probably best not to infer too much about the general merits of compile-time type checking from Java and its ilk.

Cheers,
Tom

Kay Schluehr

Posts: 302
Nickname: schluehk
Registered: Jan, 2005

Re: Is Static Typing a Form of Bad Coupling? Posted: Apr 12, 2006 2:49 AM
Reply to this message Reply
> > Optional typing is in plenty of languages, Haskell,
> Clean,
> > ML, Scala, Fortress, etc. The inventors of these
> > languages, user guides, etc. normally advice you to
> > declare the types for function arguments, but not to
> > bother for local variables. The reason for declaring
> types
> > for functions is that the types are a nice peice of
> > information for someone wanting to use the function and
> it
> > enables overloading.
> >
> I don't know much about the languages you listed, though I
> have been reading about Scala this week, and I don't see
> that it has optional typing. As far as I can see, what's
> optional is whether you need to explicitly specify the
> type. If the compiler can infer it from context, then you
> don't have to specify.
>
> What I don't understand about how optional typing would
> work is if the types aren't everywhere, then exactly what
> do they mean? For example, if I must declare types for
> function args, but need not for local variables, does that
> mean I can't use a local variable as a parameter in a call
> to a function? Because the local variable doesn't have a
> type, but the function arg does. That seems draconian, but
> if you say you can use a local variable to pass a value to
> a function, then that means the value need not be the
> specified type. Which means the type means nothing I can
> count on. How does that work?
>
> Oh wait, does it mean that at runtime I check the type?
> Ah. That might make sense. Is that what they do?

I assume one can refuse optional type declarations completely in the first development phase in favour for freezing some "type profile" after performing unit tests with reasonable code coverage. In a sense a code coverage is some "statement visitor" and you can derive a type profile i.e. function signatures as well as the types of local variables pragmatically. After having derived a type profile from a particular program it can be merged together with an AST of the program and passed to the compiler to generate an optimized version. It would be the exact equivalent of a program with static type annotations but created post hoc. I guess this procedure could avoid Michaels "premature coupling" concern. From each point of development you can proceed with two versions of your program, the type annotated and the type free or dynamically type checked one.

Vesa Karvonen

Posts: 116
Nickname: vkarvone
Registered: Jun, 2004

Re: Is Static Typing a Form of Bad Coupling? Posted: Apr 12, 2006 3:35 AM
Reply to this message Reply
Like others have already pointed out, the way you describe first doing an implementation without type annotations and then specifying a signature for the "public" methods is pretty much exactly how one can work using ML modules (either Standard ML or Ocaml). Things work similarly in Haskell and many other statically typed functional languages. The difference is that types are not optional, but are inferred by the compiler. Working in ML, the compiler would actually give you the precise signature of the implementation that you could then abstract (by removing private implementation details) to a "public" signature.

People, before starting yet another static vs dynamic debate, do yourself a favour and spend one month hacking in ML or Haskell.

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Is Static Typing a Form of Bad Coupling? Posted: Apr 12, 2006 8:30 AM
Reply to this message Reply
> Like others have already pointed out, the way you describe
> first doing an implementation without type annotations and
> then specifying a signature for the "public" methods is
> pretty much exactly how one can work using ML modules
> (either Standard ML or Ocaml). Things work similarly in
> Haskell and many other statically typed functional
> languages. The difference is that types are not optional,
> but are inferred by the compiler. Working in ML, the
> compiler would actually give you the precise signature of
> the implementation that you could then abstract (by
> removing private implementation details) to a "public"
> signature.
>
> People, before starting yet another static vs dynamic
> debate, do yourself a favour and spend one month hacking
> in ML or Haskell.

I like type inferencing languages, but languages have to be constrained in a particular way if you want to use it pervasively. You can have local type inference in a language like Scala (C# and C++ are looking at doing some of that too), but if you want global inference, I think that the state of the art is that your language ends up looking like ML or Haskell by necessity. It just doesn't fly well with subtype polymorphism.

Michael Stover

Posts: 28
Nickname: mstover
Registered: Jul, 2005

New refactoring type Posted: Apr 12, 2006 9:22 AM
Reply to this message Reply
Ruby code ==> Java code
or, more generally
dynamic language ==> static language

:-)

Also, I'm not sure why I'd ever not want to see the type info in code I'm reading? I can understand not wanting to type it all, but looking at variables and not knowing their types never strikes me as useful.

Flat View: This topic has 74 replies on 5 pages [ 1  2  3  4  5 | » ]
Topic: Is Static Typing a Form of Bad Coupling? Previous Topic   Next Topic Topic: Python seeks mentors and students for Google Summer of Code


Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us