What are some advantages of duck-typing vs. static typing?
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.
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, 2022Comments
-
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 over 15 yearsHaskell does have a great type system -- it would be awesome if more languages utilized a similar mechanism.
-
Doug McClean about 15 yearsIt'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 about 15 yearsSorry, 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 about 15 yearsThere is plenty of anecdotal evidence suggesting that duck typing is significantly more productive than static typing.
-
Charlie Martin about 15 yearsDoug, 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 about 15 yearsSorry, Steve, that's not correct either. Consider the case of a void* pointing to different structures.
-
Tomato about 14 yearsThere'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 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 about 14 yearsAlthough 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 about 14 yearsOh, 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 about 14 yearsTwo 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 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 over 13 years@postfuturist: Only for nominal static type systems.
-
Ben about 12 yearsYour 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 aMap<String, List<ComplexType>>
, and thattotal
is anint
andcategories
is anint
. That doesn't tell me me much about how to use this class. -
jeremyjjbrown about 11 yearsThe 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 about 11 yearsDoes 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 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 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 about 11 years@jeremyjjbrown we're in violent agreement. :)
-
Andrew Thaddeus Martin almost 10 yearsI 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 about 2 yearsYou 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.