Disclaimer: I don’t want this to become a flame war in the comments. I’m coming from a position of ignorance, and well aware of it. While I’d like this post to provoke thought, it’s not meant to be provocative in the common use of the term.
Chapter 14 of C# in Depth is about dynamic typing in C#. A couple of reviewers have justifiably said that I’m fairly keen on the mantra of "don’t use dynamic typing unless you need it" – and that possibly I’m doing dynamic typing a disservice by not pointing out more of its positive aspects. I completely agree, and I’d love to be more positive – but the problem is that I’m not (yet) convinced about why dynamic typing is something I would want to embrace.
Now I want to start off by making something clear: this is meant to be about dynamic typing. Often advocates for dynamically typed languages will mention:
- REPL (read-eval-print-loop) abilities which allow for a very fast feedback loop while experimenting
- Terseness – the lack of type names everywhere makes code shorter
- Code evaluated at execution time (so config files can be scripts etc)
I don’t count any of these as benefits of dynamic typing per se. They’re benefits which often come alongside dynamic typing, but they’re not dependent on dynamic typing. The terseness argument is the one most closely tied to their dynamic nature, but various languages with powerful type inference show that being statically typed doesn’t mean having to specify type names everywhere. (C#’s var keyword is a very restricted form of type inference, compared with – say – that of F#.)
What I’m talking about is binding being performed at execution time and only at execution time. That allows for:
- Duck typing
- Dynamic reaction to previously undeclared messages
- Other parts of dynamic typing I’m unaware of (how could there not be any?)
What I’m interested in is how often these are used within real world (rather than demonstration) code. It may well be that I’m suffering from Blub’s paradox – that I can’t see the valid uses of these features simply because I haven’t used them enough. Just to be clear, I’m not saying that I never encounter problems where I would welcome dynamic typing – but I don’t run into them every day, whereas I get help from the compiler every day.
Just as an indicator of how set in my statically typed ways I am, at the recent Stack Overflow DevDays event in London, Michael Sparks went through Peter Norvig’s spelling corrector. It’s a neat piece of code (and yes, I’ll finish that port some time) but I kept finding it hard to understand simply because the types weren’t spelled out. Terseness can certainly be beneficial, but in this case I would personally have found it simpler if the variable and method types had been explicitly declared.
So, for the dynamic typing fans (and I’m sure several readers will come into that category):
- How often do you take advantage of dynamic typing in a way that really wouldn’t be feasible (or would be very clunky) in a statically typed language?
- Is it usually the same single problem which crops up regularly, or do you find a wide variety of problems benefit from dynamic typing?
- When you declare a variable (or first assign a value to a variable, if your language doesn’t use explicit declarations) how often do you really either not know its type or want to use some aspect of it which wouldn’t typically have been available in a statically typed environment?
- What balance do you find in your use of duck typing (the same method/member/message has already been declared on multiple types, but there’s no common type or interface) vs truly dynamic reaction based on introspection of the message within code (e.g. building a query based on the name of the method, such as FindBooksByAuthor("Josh Bloch"))?
- What aspects of dynamic typing do I appear to be completely unaware of?
Hopefully someone will be able to turn the light bulb on for me, so I can be more genuinely enthusiastic about dynamic typing, and perhaps even diversify from my comfort zone of C#…
I think you’re mostly right: dynamic binding is largely for niche scenarios.
There are some good uses, though. For instance, multiple dispatch (i.e., dynamic member overload resolution). With multiple dispatch you can implement patterns such as Visitor, for instance, very easily and without modifying the visited class.
Another good use for dynamic typing is when you want very low coupling. For instance, take a look at the extensibility point described here (ICustomMemberProvider):
http://www.linqpad.net/FAQ.aspx#extensibility
Static typing is a no-go here because it would require consumers to create a dependency on the LINQPad executable. To avoid this in C# 3.0, LINQPad must access the members of this interface via reflection which is really clumsy. Dynamic typing in C# 4.0 will make such things much easier.
LikeLike
Granted, I’m not the audience you’re hoping for responses from, not being that experienced using dynamic typing. That said…
It seems to me that one obvious context is where you want to implement some interface-like behavior, but you’re dealing with classes that are already defined. I believe Joe’s comment about the Visitor pattern would be a subset of this more general category?
An example different from implementing the Visitor pattern might be loading objects from files. Lots of types define a “Load(string)” method where the “string” is a file path. But there’s no interface that these types all implement with that method in it. If you’ve got a system where you want to be able to load a wide variety of object types based on their own implementations of the “Load(string)” method, it seems to me dynamic typing would be useful.
In other words, situations where by convention, a variety of classes have implemented what is essentially an interface, but where no interface has been declared or implemented per se (and for whatever reason, it’s impractical to go back and add the interface).
Now, _that_ said…
In C#, dynamic typing is as I understand it mainly a concession to interop. As a language design choice, other languages may follow dynamic typing as the rule rather than the exception, for specific reasons related to the expected/intended use of that language. But clearly that’s not really the case for C#. And just as clearly, there is _significant_ overhead involved in any use of dynamic typing, both in terms of performance and in terms of code maintenance (all of the sudden, the compiler can’t catch things, including simple things that don’t immediately seem related to the dynamic nature of the call site).
I would say that at least in the context of C#, dynamic typing really is one of those “use only when absolutely necessary” things. For COM interop, Office interop, etc. I’m sure it’s very useful. But as an everyday construct in C# code, I would be very much against it, because C# already provides a good, performant static type system.
LikeLike
@Joe Albahari:
For your linqpad comment, it is a failure by design, that the Interface is only availlable in the executable of linqpad. It should be exportet by an external dll, that both, linqpad and and the extensions can reference – no need for dynamic typing here.
LikeLike
@beowulfof
You would still be asking the developer to take an external dependency (it matters not whether it is a executable or dll) rather than just pasting a tiny interface definition in. I think Joe made the right call.
LikeLike
beowulfof: regarding the LINQPad interface, if that type was moved into a separate assembly, the dependency would become smaller in terms of KB – but the essential problem of the dependency would remain.
IOW, people wanting to implement that interface in their types would need to deploy the LINQPad interface assembly with their applications – even though that interface may only ever be used in development situations.
LikeLike
I work in php for my day job (yes yes, make your jokes) and C# for my hobby projects at night.
To me, dynamic typing ends up hurting me more than it helps a lot of times. A number get interpreted as a string when it shouldn’t or some other small bug that bites you in the butt at some point.
I will have to agree with the Terseness part though as I quite often have code like this:
// Code taken out of context purely for example
if($options !== null)
{
if(is_object($options) &&
method_exists(array($options, ‘toArray’))
{
$options = $options->toArray();
} else {
$options = array($options);
}
if(is_array($options)) {
$this->setOptions($options);
}
}
I can pass in an object with a toArray method, an array, or I can wrap it in an array. Php also has some basic type safety so I could say in the method that the argument must be an array otherwise crash the script.
That could of course also be done in C# but you would have to write many more methods.
LikeLike
I think that adding dynamic typing to C# in this limited capacity doesn’t hurt things but I think its usage is very restricted to COM interop. In other words I don’t really see dynamic typing solving problems (outside of COM interop) in normal day-to-day activities of C# developers.
What I would have loved to see would have been some kind of structural typing (http://en.wikipedia.org/wiki/Structural_type_system) support in C# that would have been an interesting compromise between C#’s static type checking and the flexibility of dynamic typing. I just don’t see C#’s dynamic typing being used that much outside of interop (COM, Python, etc.) and as such I am somewhat disappointed at the narrow focus of the new language feature.
LikeLike
I think we need some of the Linux Ruby-on-Rails type of folks here to answer these (brilliant) questions convincingly, but I’m not sure many of them read C#-oriented blogs (in my experience most of them like to pretend they don’t know what C# is).
LikeLike
Testing legacy code. I’m not sure if this is dynamic or mixins. I write a lot of code that depends on legacy Java code that is impossible to mock out db access for example. What I do is using JRuby, create the object, and while I have the object in memory, swap out the method that accesses the database for one of my own choosing. Very useful.
LikeLike
I find that the interest of dynamic typing is usually inversely proportional to the easiness of refactoring in the language’s IDE.
LikeLike
dynamic typing is not a niche feature. it is useful to simplify the language so that it can be used by inexperienced people. _thats_ why python and ruby are getting some attention these days. statically typed languages might be more productive but the concepts are much harder to understand.
as most programmers are frankly idiots dynamic typing is not a niche feature. unfortunately.
LikeLike
Also the fact that most people in the comments of this blog seem to agree that dynamic typing is generally inferior to static typing is a sign of quality for this blog. People who hang out here know what they are doing when they type in a program. congrats jon.
LikeLike
I like what Erik Meijer said: “Static when possible; dynamic when necessary.”
Some food for thought (you can draw your own conclusions):
1. Some problems are inherently dynamic. E.g., web requests. You can’t compile the internet! MVC uses reflection for this today. I think that dynamic typing is a more expressive approach to the same problem.
2. The expressivity I mentioned above is itself compelling: Reflection introduces a strong dependency on a mechanism. Dynamic invocation says, “Here’s my intention; please do this in the fastest way possible.”
3. Higher order types with complex constraints can be intimidating to mere mortals. Read the Scala spec for an example. Even C# “pros” frequently don’t understand the subtleties of contravariance and covariance, and frankly C# gives you only the “easy” parts of higher-ordre typing. By contrast, dynamic typing “just works.” When it works, that is!
4. Static vs. dynamic typing is not the be-all and end all of program correctness. They are part of a spectrum of tests over time which include, but are not limited to: Compiler checking, unit tests, assertions, static analysis, runtime verification, etc.
LikeLike
@Joe Albahari
>regarding the LINQPad interface, if that type was moved into a separate assembly, the dependency would become smaller in terms of KB – but the essential problem of the dependency would remain.
Not Quite, but if the plugin references the executable you have a circular reference.
>IOW, people wanting to implement that interface in their types would need to deploy the LINQPad interface assembly with their applications – even though that interface may only ever be used in development situations.
Not really, they should reference the dll of the hosting app, but need not to deliver it with themselves.
>You would still be asking the developer to take an external dependency (it matters not whether it is a executable or dll) rather than just pasting a tiny interface definition in. I think Joe made the right call.
Sure the developer of a plugin would have the need to reference the interface dll, but self-implementing an Interface that has same properties and methods as the one in the executable does not make it the same interface!
LikeLike
They are great for Object-Relational Mapping. Consider this bit of code:
var customer = conn.CallProc.CustomerSelect(AccountKey:1234);
Console.WriteLine(customer.FirstName, customer.LastName);
I have a library that allows you to write code like that without any ORM mapping files. It understands that anything that follows “CallProc.” should be translated into a stored procedure of the same name. And then it returns dynamically typed objects containing the results.
I feel comfortable using this because it is no more dangerous than what you would get if you were passing around DataTables and reading columns using string.
The source code is quite simple, less than 700 lines for the whole ORM, and should be posted on InfoQ later this week.
LikeLike
@Jonathan: Is that better than generating code from the database metadata, which would then give you intellisense and prevent typos? I’m not trying to be argumentative – I’m genuinely trying to understand the benefits.
I can certainly see them for spiking – avoid all the roundtrip time of the code generation etc. But in a stable database where I don’t mind spending a little time upfront in code generation for the sake of long-term maintainability, is the dynamic approach better in some way that I’m missing?
LikeLike
Appendix. A few more ideas I missed in my first post.
5. Unit testing in dynamic languages is dead easy. Mocking frameworks? Don’t need ’em. Test frameworks? They’re icing on the cake, but not really a requirement.
Relevant to dynamic types in .NET, but not really an advantage of dynamic typing per se, and not really relevant to C#:
6. In the DLR, you can support type semantics foreign to .NET without introducing a parallel hierarchy. So if your language has immutable string references, you can have that on top of the standard System.String.
Relevant to dynamic types in C#, but not really an advantage of dynamic typing per se:
7. Interoperability with dynamic languages. Inter-language interoperability is one of the tenets of .NET. So you can run that Python spell-corrector if you need to, or (more likely) can allow user scripting in your app.
LikeLike
Jon, regarding DBs and code generation, I agree, but there are schema-free DBs. Not surprisingly, they seem to be popular with the same folks who like schema-free source code. :)
LikeLike
Personally, I see dynamic typing as primarily a workaround for lack of features in _existing_ statically-typed languages, and secondarily a way to improve _writability_ at the expense of _readability_ (which may be good for shell scripts, hacks, experimentation w/ REPL, etc., but bad for building large, robust, reusable systems).
But I could also be suffering from Blub’s Paradox.
LikeLike
Personally, I feel that I tend to have much less time dealing with inheritance hierarchies in dynamically typed languages. I have spend much less time moving methods between interfaces and casting and whatnot. So perhaps a reason to use dynamic typing is to simplify classes that would otherwise have a lot of interfaces or require a lot of needless casting?
Secondly, there are some syntactical benefits of dynamic typing. For example, in Python, you can generate an XML-RPC client that would work like this:
xmlclient.some_method(some_arg=’foo’)
Lastly, I’d like to point out that you’re kind of stacking the deck against dynamic typing. It shouldn’t be reduced to “don’t use dynamic typing unless you need it” any more than it should be reduced to “don’t use static typing unless you need it”.
This is about choosing the best tool for the job. Does static typing simplify your code and make it more maintainable? Use it. Does dynamic typing simplify your code and make it more maintainable? Use it instead. Trying to choose a “default” is going to make you choose static typing in cases where dynamic typing is
LikeLike
Have you seen Kevin Hazzard’s fluent XML parsing using C#’s dynamic type? It’s a pretty nifty use of dynamic typing.
http://www.gotnet.biz/Blog/post/Fluent-XML-Parsing-Using-CSharp-Dynamic-Type-Part-1.aspx
LikeLike
My company has a product in which a ‘type system’ in terms of properties and values are pulled dynamically at runtime from a dll that provides description information.
Currently, we have a complex TypeProvider implementation that allows WPF to see these dynamic properties as regular properties with respect to databinding, however, the rest of the code must work with the raw dictionaries and cannot treat these items as properties.
Our spikes with VS 2010 and the dynamic keyword have allowed us to create a much simpler model for the creation of the properties and the rest of our code can treat these dynamic elements as properties.
LikeLike
@Al Tenhunfeld: I hadn’t, but ironically it’s very similar to the example I’ve used in C# in Depth (down to the very idea of the XML containing books and authors!).
Of course, it won’t work with XML namespaces, but yet, it’s kinda neat. I’m not sure that much of the *real world* code I write that deals with XML would benefit much, but maybe…
LikeLike
@Jason: Why do you have a lot of casting anyway? I don’t find I need much.
For the XML RPC side of things – if a service doesn’t publish a schema of some description letting you create a statically typed proxy, dynamic typing does indeed help. However, that kind of thing doesn’t fill me with confidence in the first place.
Finally, in terms of “stacking the deck” – there are obvious benefits to static code: better tooling support, problems are found earlier, and performance. To me, that suggests that dynamic typing needs to show a benefit which outweighs those ones. I’m certainly amenable to the idea of using dynamic typing *if* it simplifies my code and makes it more maintainable – which is why I’m asking where that comes up in the real world.
LikeLike
@Steven: That’s an excellent example, thanks. I think it’s fair to say that in many/most of the cases where you’re *already* working dynamically (using reflection etc) the dynamic typing in C# 4 is likely to be a good fit.
I’m just struggling to understand why something I personally find useful so rarely is worth abandoning the benefits of static typing for *throughout the language*. I feel I must be missing out on why dynamic typing would be useful *every day*.
LikeLike
@Max C
Here’s a good Rubyist perspective on dynamic vs. static typing:
http://weblog.jamisbuck.org/2008/11/9/legos-play-doh-and-programming
It’s about Ruby vs. Java, but I think what’s said is applicable to this discussion. Jamis prefers Ruby, and I think he does a fair job of comparing Ruby & Java development techniques.
LikeLike
“17.3” * 3
LikeLike
@Alan: I don’t see much in there about dynamic typing specifically. (I’m also somewhat bemused by the line “You’d never see a Java program that was configured by writing Java code” – someone hasn’t used Guice…)
It seems mostly to be about trying to avoid writing Ruby with a Java accent, which is all very well but it doesn’t give me much idea of why dynamic typing is a good thing.
LikeLike
I see C#’s dynamic keyword as so much more than just dynamic (duck) typing. There’s a whole world of fun stuff to do with DynamicObject.
For instance, someone asked about an equivalent to HLSL swizzles in C#. Now, these don’t use duck typing, infact it’s very clear at compile time by examination of the code exactly what types are being thrown around (even though the compiler can’t because it’s using the dynamic keyword)
For an explanation of the code I wrote and some usage, you can see http://matt.scharley.me/portfolio/project/view/swizzle or for direct download of the code, http://matt.scharley.me/links/links/goto/24
LikeLike
@Matthew: dynamic is only to do with dynamic typing, but there’s more to dynamic typing than duck typing. I’ll have a look at the swizzle stuff later on :)
LikeLike
I have been waiting for dynamic for some time to fill the IDispatch void.
I am building .net components on a c++ plugin framework and some of the event driven subscriptions fail due to lack of IDispatch support.
with .Net 4.0 I should be able to easily register a derived dynamicobject type.
LikeLike
(1) It is easier to write higher-order code with dynamic types. For example, I have a set of operations that each use different subsets of the methods on interface A. If I just want to use one operation on my new type, I have to implement all methods on A even though it’s not necessary. With dynamic types, you just use the operation and hope it works.
(2) In rapid prototyping, one can make changes quickly without having to update type signatures everywhere. Type inference reduces this burden in ML, but C#/Java is still a pain.
Dynamic types are too dangerous, but C# is too verbose. The right balance is static typeing with type inference.
LikeLike
@skeet – Yeah, but you’re Jon Skeet. :-)
In all seriousness though, I’m a bit of a newb when it comes to typing in Java/C# and I seem to have issues with typing in C#. Although I’m sure I can get around this issue with some experience, that at least makes dynamic typing more approachable.
I suppose what it ultimately boils down to is reduced complexity. Interfaces? Don’t need ’em. XML schemas for XML-RPC calls? Don’ t need ’em. True, none of these add a huge amount of complexity, but my experience is that programming is ultimately more a game of hiding a bunch of little details more than it is about fighting huge complexity issues.
The biggest benefit is that with dynamic typing, I don’t usually think about types. If I name something people, then I think of it as representing people. Type inferencing is a two-edged sword for this problem. The majority of the time, I don’t have problems. But when I do something wrong, it can be difficult to figure out exactly what went wrong because all of the type information is obscured. With dynamic typing I can at least hit it with a debugger when I get typing issues.
Lastly, I don’t disagree with you regarding the benefits of static typing. The difference is that now you’re thinking in terms of pros and cons of *both* static and dynamic typing. By reading just the blog post, it comes off as though you’re only thinking about the pros and cons of dynamic typing. It’s difficult to do a comparison when you’re only thinking about one side of the story. :-)
LikeLike
“A number get interpreted as a string when it shouldn’t”
Those sorts of things are more a failure of PHP than of dynamic typing. PHP does very odd things and likes to interpret too many things as strings.
Whilst not strictly relevant, http://www.pphsg.org/cdsmith/types.html is an interesting read.
To me the benefit of dynamic in C# is that it provides a uniform way of doing what we already do a dozen different ways — communicate with IronPython, XML, JSON, web services etc.
LikeLike
“Those sorts of things are more a failure of PHP than of dynamic typing”
But is the concept *truly* separable from the language? In the end, we’re talking about the way that the compiler (or interpreter) handles the code. By some standards, VB.NET supports “dynamic typing” with Option Strict off. Clearly its reflective late binding is…um…less than performant, but the concept of not having a clear inheritance hierarchy (that’s visible at that point in the code, anyway) to prove or disprove the existence of a type member is still there.
LikeLike
To me dynamic typing is useful when the domain you are dealing with is itself untyped in nature. As have been pointed out several times in the comments XML (XML-RPC, etc.) is such a domain. If you are dealing with such a domain you need to cast all the time which means that you are practically using dynamic typing because your code can fail at runtime if you did not made the right assumptions when casting.
It seems that especially in web programming people tend to use many untyped representations of the data like XML, HTML, JSON. This is why I believe that JavaScript is so well suited for the web and DOM manipulation in C# (without dynamic) will be much more painful. Also it seems that UI code tends to be untyped. HTML is one example but you can look at WPF or even Win Forms. Usually you have a tree of controls, you don’t know the exact type of the control and you need to cast. What is more UI code does not need to be strongly typed that much because usually nothing depends on it so a bug in it will not propagate to any other layers in the application and you are not likely to have unexpected branches of the code.
On the other hand the backend needs to use static typing. It will help with the performance and it will help track all the dependencies when you make a change. Also static typing should not serve as an excuse not to have unit tests (as it happens in my projects :) ) and if you have unit tests why bother with type safety. To me the biggest benefit of static typing is BRUTAL intellisense and refactoring capabilities.
LikeLike
@Stilgar: Thanks for that comment, it’s very interesting. I agree with you about untyped environments, although not so much about the UI side of things – even if you don’t have *total* type knowledge, you still often know that you have “a control” which will have certain properties etc.
I also disagree about: “If you have unit tests why bother with type safety” – to me the answer is “because it makes it easier to be correct about how I use a component”. If that component is written using dynamic typing, I have to pore over the documentation and unit tests to know what I can expect to pass in and what it should mean. Static typing gives me that information in a much more efficient form, IME.
Also, “having unit tests” isn’t a binary condition – I’ve often seen suggestions that dynamic environments require *more* unit tests than static environments. Thus type safety (not quite the same as static typing, of course) reduces the testing burden. You still need unit tests, but potentially fewer.
LikeLike
“If that component is written using dynamic typing, I have to pore over the documentation and unit tests to know what I can expect to pass in and what it should mean. Static typing gives me that information in a much more efficient form, IME.”
This is one of the things I had in mind when I pointed out BRUTAL intellisense. I believe it can save enough time to compensate for the additional code you write when using static typing.
I am not really sure whether dynamic typing requires more unit test. I can see it allowing more branches => the need for more tests but I am not sure if this is what happens in practice. My experience with unit testing is limited and I’m ashamed of that :(
LikeLike
As an example, i need (really often) to have Mix-Ins or multiple inheritance.
For instance, i have a class that describes how my page (or user control) should be rendered. I want it to be extensible.
public class HowToRenderControlA {
public bool ShowThis {get;set;}
public bool ShowThat {get;set;}
}
Then i want to show how to Control B. I create another class.
Then i have a control C, that has lot in common with A and B, and it would be great if i could have those classes all together and their properties accessible.
Or just add a custom something to A or B in some cases.
It’s easy implementable in Python, Ruby, Scala, but takes reflection (or Lin-fu, Castle) in c#. And, btw, if i even dared to use lin-fu, i need to call my methods / access properties not thorugh .CallMethod(), but through (“CallMethod”, object[] {}). You know what i mean? :)
LikeLike
I’d like to stress the importance of duck typing when doing rapid development (eg prototyping): strict type hierarchies are something you don’t want to bother with when using a bottom-up approach.
This can be achieved in a statically typed language with a structural type system where there’s no need for explicit interface declaration: if a class has all the methods required for an interface, it is automatically of the apropriate type.
A consequence of this is the possibility for decoupling of functionality from class definitions: Eg in JavaScript, you can use the generic array methods with any array-like objects (basically anything which has a numeric length property): Call them explicitly via `Array.prototype.slice.call(foo, 13, 42)` or just assign the method to the object (ie `foo.slice = Array.prototype.slice; foo.slice(13, 42);`).
One of the main features of Google Go is such a type system; this isn’t really something new as some functional languages (I might be wrong here, but I think OCaml and Dylan; might even date back to ML) have supported this for ages.
LikeLike
@Joe and Paul: I’m with beowulfof on this one. The reason is simple: You have a dependency nevertheless. Extracting the interface into an own DLL makes this dependency explicit such that it is clear. With duck-typing in place, you have to trust that the interface doesn’t change and there’s nowhere a clear note or whatever about the importance of the original interface to remain unchanged.
To dynamic typing I second the opinion that it depends on the context. So, for example in production code I’m a strong opponent of it as it opens up the box for a whole lot of errors and hard-to-reproduce bugs. But still, dynamic typing is good in a lot of scenarios such as tests, where duck typing can be used etc. Please note that I wrote ‘tests’ and not ‘unit tests’ because tests are so much more. You need integration tests etc., which are often tightly integrated into a whole environment with shell scripts etc. and dynamic typing is a godsend there.
LikeLike
There is the classic interview with the BDFL here http://www.artima.com/intv/strongweakP.html.
Bottomline for me is: static typing won’t support you anyway the whole way down when describing allowed values for variables, so why start bothering at all. That’s true at least for business applications, e.g. how many business app developers really understand C++ templates or covariance, what’s the canonical solution in C++/C#/Java for nulls and how many validation libraries do you find for each of these languages? Typing a variable and being able to compile with that type is fine, but you’ll still get NPEs and have to check values.
Admitting that, a dynamically typed language helps you to start quickly – especially if you’re used to prototype in a REPL – and part of the time saved can be used for interface documentation, unit testing, and more thorough runtime type checks.
The last decades I went back and force between Perl, C++, Java, Python, and C#. I still use Python when I’m prototyping in code since then Python’s shortcuts pay off immensely, but C# shifts me more and more back to the static camp, because newer versions don’t add too much ceremony. And intellisense is a nice thing to have. If only the otherwise brilliant Anders would have avoided “The Billion Dollar Mistake”…
LikeLike
@Frank,
“static typing won’t support you anyway the whole way down…so why start bothering at all”
That’s like saying “A seat belt doesn’t guarantee that I won’t die in a car wreck, so I won’t bother wearing one.” Just because a type system can’t statically prevent every possible type of run time error doesn’t mean that it isn’t very useful.
Do people really save a ton of time using a dynamic language for “prototyping”? You still have to deal with type problems in prototype code, and in my experience the actual percentage of the code I write that is dedicated to satisfying the type system is extraordinarily low.
LikeLike
@David
First, that was my summary when reading Guido’s post at that time, and was/is not necessarily my position. At the time reading this, I was a very pedantic private/final/const coder. But nevertheless Guido’s thoughts were and are very convincing for me. Mostly working on business apps, the code ratio dedicated to satisfy the type system is confessedly often low, but the code ratio to check for correct values and handle validation errors is frustratingly high: All these nice types and I still can’t make compile-time sure that my pH value is just between 0 and 14 (as I could in PASCAL decades ago), my string is between 1 and 10 characters, and I still have to maintain code which starts with 10 lines of null-checking.
Sure, writing ‘var’ instead of ‘string’ doesn’t save a lot of time, but prototyping in python with ‘*args’ and ‘**kw’ arguments without having to overload a dozen methods or simply defining a ‘names’ argument without bothering about covariance or list/array conversion can – not for saving a few keystrokes but for being able to braindump your mental model without getting lost in details.
On the other hand, once the model becomes more firm and more code uses the model, types checked by the compiler could save time. But now that won’t work in Python, but as I’ve learned, it quite often works in C# with type inference and optional dynamic typing.
Jon was asking for the pro’s of dynamic typing – I know and stated some and I wanted to share the exhilarating effect of Guido’s article. Funnily I still feel this flame war inside me, after all these years, so why not also share that with you ;)
LikeLike
@Frank
I am not trying to start a flame war. I am just looking for an answer to the same question that Jon has asked. I still haven’t seen any practical pro’s of dynamic typing listed, nor does Guido’s interview present any compelling arguments for me. He makes a lot of unfounded assertions and basically takes it for granted that dynamic type systems are somehow “easier” to program in, without offering any evidence of that.
LikeLike
I’d say the most prominent places where dynamic typing is useful are in interop, use of dynamic language runtimes, and for very loosely bound service interfaces. The combination of loosely bound services could be interesting… Pass your request and frobber/filter to the service… the service does an overlying pass based on the request, and runs it through a frobber or filter than is passed as a dynamic language for execution, then sending back the results. The last point would probably be best limited to trusted resources for the request though. There are many times where internal business units have to communicate and control different application, or data domains. The use of dynamically typed relations allow for data structures to grow/change in one system without breaking others.
LikeLike
I think dynamic typing could be usefull for attached properties. A Canvas would like to set the Canvas.X and Canvas.Y property on anything that can be draw, where as a grid would probably want to set the Grid.Column an Grid.Row.
LikeLike
Regarding XML, it could allow for a dynamic object that takes a CLR XML data type, and wraps it into a selector class that supports E4X or similar notation. That could be done pretty easily.
LikeLike
Dynamic typing doesn’t give you anything if you are approaching it from a static typing mindset. You should get out of C# and Java and write a non-trivial app in Ruby or Python to really understand the benefits.
In other words, the benefits are more about what the language enables you to do. Change the language, change the type system, change your approach.
LikeLike
@Mike: I realise that throwing myself into the deep end would be the best way of understanding the benefits… but I tend to be loathe to do that unless those who *do* understand the benefits can at least explain them in a fairly appealing way beforehand.
This post was an attempt to get those explanations – if there’s really no way of appreciating why it’s worth having dynamic typing “on” all the time when programming (instead of only in specific situations) without investing a huge chunk of time to it, I’ll be somewhat disappointed :(
LikeLike