What are some advantages of duck-typing vs. static typing?

12,625

Solution 1

Next, which is better: EMACS or vi? This is one of the running religious wars.

Think of it this way: any program that is correct, will be correct if the language is statically typed. What static typing does is let the compiler have enough information to detect type mismatches at compile time instead of run time. This can be an annoyance if your doing incremental sorts of programming, although (I maintain) if you're thinking clearly about your program it doesn't much matter; on the other hand, if you're building a really big program, like an operating system or a telephone switch, with dozens or hundreds or thousands of people working on it, or with really high reliability requirements, then having he compiler be able to detect a large class of problems for you without needing a test case to exercise just the right code path.

It's not as if dynamic typing is a new and different thing: C, for example, is effectively dynamically typed, since I can always cast a foo* to a bar*. It just means it's then my responsibility as a C programmer never to use code that is appropriate on a bar* when the address is really pointing to a foo*. But as a result of the issues with large programs, C grew tools like lint(1), strengthened its type system with typedef and eventually developed a strongly typed variant in C++. (And, of course, C++ in turn developed ways around the strong typing, with all the varieties of casts and generics/templates and with RTTI.

One other thing, though --- don't confuse "agile programming" with "dynamic languages". Agile programming is about the way people work together in a project: can the project adapt to changing requirements to meet the customers' needs while maintaining a humane environment for the programmers? It can be done with dynamically typed languages, and often is, because they can be more productive (eg, Ruby, Smalltalk), but it can be done, has been done successfully, in C and even assembler. In fact, Rally Development even uses agile methods (SCRUM in particular) to do marketing and documentation.

Solution 2

A lot of the comments for duck typing don't really substantiate the claims. Not "having to worry" about a type is not sustainable for maintenance or making an application extendable. I've really had a good opportunity to see Grails in action over my last contract and its quite funny to watch really. Everyone is happy about the gains in being able to "create-app" and get going - sadly it all catches up to you on the back end.

Groovy seems the same way to me. Sure you can write very succinct code and definitely there is some nice sugar in how we get to work with properties, collections, etc... But the cost of not knowing what the heck is being passed back and forth just gets worse and worse. At some point your scratching your head wondering why the project has become 80% testing and 20% work. The lesson here is that "smaller" does not make for "more readable" code. Sorry folks, its simple logic - the more you have to know intuitively then the more complex the process of understanding that code becomes. It's why GUI's have backed off becoming overly iconic over the years - sure looks pretty but WTH is going on is not always obvious.

People on that project seemed to have troubles "nailing down" the lessons learned, but when you have methods returning either a single element of type T, an array of T, an ErrorResult or a null ... it becomes rather apparent.

One thing working with Groovy has done for me however - awesome billable hours woot!

Solution 3

Duck typing cripples most modern IDE's static checking, which can point out errors as you type. Some consider this an advantage. I want the IDE/Compiler to tell me I've made a stupid programmer trick as soon as possible.

My most recent favorite argument against duck typing comes from a Grails project DTO:

class SimpleResults {
    def results
    def total
    def categories
}

where results turns out to be something like Map<String, List<ComplexType>>, which can be discovered only by following a trail of method calls in different classes until you find where it was created. For the terminally curious, total is the sum of the sizes of the List<ComplexType>s and categories is the size of the Map

It may have been clear to the original developer, but the poor maintenance guy (ME) lost a lot of hair tracking this one down.

Solution 4

It's a little bit difficult to see the value of duck typing until you've used it for a little while. Once you get used to it, you'll realize how much of a load off your mind it is to not have to deal with interfaces or having to worry about exactly what type something is.

Solution 5

There is nothing wrong with static typing if you are using Haskell, which has an incredible static type system. However, if you are using languages like Java and C++ that have terribly crippling type systems, duck typing is definitely an improvement.

Imagine trying to use something so simple as "map" in Java (and no, I don't mean the data structure). Even generics are rather poorly supported.

Share:
12,625
codeLes
Author by

codeLes

I'm a programmer. I'm currently working in: - ASP.Net/C# - Java and have no distaste for any platform. Interested in Groovy and Grails. I use and promote Linux/Ubuntu. I like guitar and music in general. I'm married and have a son. I like to play video games, of course.

Updated on June 27, 2022

Comments

  • codeLes
    codeLes almost 2 years

    I'm researching and experimenting more with Groovy and I'm trying to wrap my mind around the pros and cons of implementing things in Groovy that I can't/don't do in Java. Dynamic programming is still just a concept to me since I've been deeply steeped static and strongly typed languages.

    Groovy gives me the ability to duck-type, but I can't really see the value. How is duck-typing more productive than static typing? What kind of things can I do in my code practice to help me grasp the benefits of it?

    I ask this question with Groovy in mind but I understand it isn't necessarily a Groovy question so I welcome answers from every code camp.

  • mipadi
    mipadi over 15 years
    Haskell does have a great type system -- it would be awesome if more languages utilized a similar mechanism.
  • Doug McClean
    Doug McClean about 15 years
    It's not true that any program that is correct will be correct under static typing. Static typing is a conservative approximation to the runtime behavior. This is why some programs with casts can still be type correct (by preserving an invariant which the type checker is unable to prove).
  • postfuturist
    postfuturist about 15 years
    Sorry, C's weak type system is not the same thing as dynamic typing. It's not even close. There is no late binding. Casting pointers like your example will cause the program to assume a different underlying structure leading to bugs, not functionality.
  • postfuturist
    postfuturist about 15 years
    There is plenty of anecdotal evidence suggesting that duck typing is significantly more productive than static typing.
  • Charlie Martin
    Charlie Martin about 15 years
    Doug, I believe that's a theorem. Assume contrary: then you have a program you have a program which is correct, ie, meets postcondition, but where exists a statement for which no static typing is correct. But that's equivalent to exists a statement w/o defined semantics in correct prg, Contradicts
  • Charlie Martin
    Charlie Martin about 15 years
    Sorry, Steve, that's not correct either. Consider the case of a void* pointing to different structures.
  • Tomato
    Tomato about 14 years
    There's nothing wrong with Java's Map type. The problem is Java's lack of a fluent syntax to deal with Maps. That's something Groovy addresses, but it's not really related to Groovy's duck typing.
  • Nick Retallack
    Nick Retallack about 14 years
    @slim: I'm not talking about the 'map' type, I'm talking about the 'map' higher order function. I'll add a link to my answer.
  • Nick Retallack
    Nick Retallack about 14 years
    Although explicit type declarations can be instructive, reflection is often a decent substitute. Open an interactive session and ask those objects what type they are.
  • Tomato
    Tomato about 14 years
    Oh, OK. In Groovy that's collect(): List doubled = x.collect { it * 2 }. Scala calls it map() and has strong typing. I don't see how Java's type system gets in the way of this. Java will get closures soon, and I'm sure the Collections framework will get collect/map.
  • Tomato
    Tomato about 14 years
    Two aspects of agile programming are plentiful unit tests and merciless refactoring. There's anecdotal evidence at least, that dynamically typed languages are helpful in both these areas. Having said that, static typing really helps with IDE-assisted refactoring.
  • Totti
    Totti over 13 years
    -1: You are talking about a specific kind of nominal static type system and assuming (incorrectly) that your observations apply to all static type systems. They do not
  • Totti
    Totti over 13 years
    @postfuturist: Only for nominal static type systems.
  • Ben
    Ben about 12 years
    Your example points out the problems with poor documentation, not with dynamic typing (and there's no duck typing in sight here). Under static typing I would know (because it's declared) that results is a Map<String, List<ComplexType>>, and that total is an int and categories is an int. That doesn't tell me me much about how to use this class.
  • jeremyjjbrown
    jeremyjjbrown about 11 years
    The problem with this code is not typing but the fact that those are non-descriptive reference names. If the developer had called results something expressive like mapOfFooToListOfBar then you would have never had this problem. Naming just about anything results or total is a code smell and the mark of a poor craftsman. This code also suffers from primitive obsession.
  • jeremyjjbrown
    jeremyjjbrown about 11 years
    Does anyone actually get to use Haskell at work? I'm not even sure some of the Java developers I work with could learn Haskell.
  • Ken Gentle
    Ken Gentle about 11 years
    @jeremyjjbrown, of course it's a code smell, unprofessional and the mark of a poor craftsman - but it "works" solely because of "duck typing" in Groovy. Yes, descriptive names would help. Remember, we're talking about the poor schmuck who has to pick this up after the developer is long gone, and even having the long names isn't enough to know how to manipulate the content of results WITHOUT FURTHER INVESTIGATION (read that: time, money and resources)
  • jeremyjjbrown
    jeremyjjbrown about 11 years
    @ Ken, "how to manipulate the content of results". So I assume there are no tests either. I'm having the same exact problem your having right now (today) with stinky code with no tests, written in plain Java. Static typing hasn't added to it's maintainability at all. But if what you are saying is that Duck typing allows developers to be even more irresponsible, then I totally agree with you.
  • Ken Gentle
    Ken Gentle about 11 years
    @jeremyjjbrown we're in violent agreement. :)
  • Andrew Thaddeus Martin
    Andrew Thaddeus Martin almost 10 years
    I was contracted to work on a project for the last two years, and after having awful problems with PHP, I switched to developing in Haskell. You're right though, most programmers probably couldn't learn how to use Haskell effectively. It took me six weeks of reading tutorials before I could do anything remotely useful.
  • dallin
    dallin about 2 years
    You say that duck typing is not more productive but then end by saying "it just eliminates a lot of the hassle of casting and conversions between types." I think it's quite clear that it's more productive (assuming you don't have to spend a ton of time debugging behind a programmer with poor practices), and your answer describes why quite well.