DenkzeitWiki

Suchen:

Aktuelle Änderungen Printable View Änderungen Bearbeiten

SmartDataAndDumbCode > ProgrammingLanguages > ProgrammierSprachen > JavaEnterpriseEdition > DataDrivenProgramming > TestDrivenDevelopment > ClojureReferenceTypes > VersionControlSystems > VersionControl > FunctionalProgramming > SomeOfMyPythonScripts > CommonLanguageRuntime > GlobalInterpreterLock > SoftwareCraftsmanship > PrematureOptimization > ConcurrentProgramming > StaticVsDynamicTypingClear Trail
Main /

Static Vs Dynamic Typing

OptionalStaticTyping
RefactoringInDynamicLanguages

DynamicLanguages
LanguageWars
DynamicTyping
DuckTyping
PythonTyping

PythonIDEs

StaticVsDynamicTypingArguments

Alternatives



The general argument for static types is that it catches bugs that are otherwise hard to find.

Self Testing Code is the name I used in Refactoring to refer to the practice of writing comprehensive automated tests in conjunction with the functional software.[1]

TestDrivenDevelopment is my preferred way of writing Self Testing Code, however it isn't the only way. You can get many advantages of tests by writing them just after the functional code rather than before. The important point of Self Testing Code is that you have the tests, not how you got to them.[2]


And you bring up an interesting question in suggesting that a dynamically-typed language may require more unit testing than a statically typed language. Of this I am not convinced; I suspect the amount may be roughly the same and if I am correct it implies that the extra effort required to jump through the static type-checking hoops may be less fruitful than we might believe.

The only guarantee of correctness, regardless of whether your language is strongly or weakly typed, is whether it passes all the tests that define the correctness of your program.


All that attention to getting the types right doesn't necessarily mean you don't have other bugs in your program. A type is a narrow piece of information about your data. When you look at large programs that deal with a lot of strong typing, you see that many words are spent working around strong typing.

Runtime typing works differently, because you can easily make a mistake where you pass the wrong argument to a method, and you will only find out when that method is actually called. On the other hand, when you find out, you find out in a very good way.


There are better ways to comment a program, to add metadata for tools and libraries, or to verify program correctness; but type declarations, in many languages, are a passable way to do all of these jobs at once.


  • Refactoring?

Optional type annotations were added to Common Lisp in the early 1980's. Compiler strategies have improved a lot since then, as have machine capabilities. I think a better return would come from investing in the implementation of the current Python language rather than changing the Python language itself.


Not for class attributes (unless you put them on a metaclass), and not for local or global variables. Just functions, methods, and instance attributes. These are the only places where it makes sense to add them;

I'm not doing this with code optimization in mind. I like many of the reasons for type declarations that were given by various proponents: they can be useful for documentation, for runtime introspection (including adaptation), to help intelligent IDEs do their magic (name completion, find uses, refactoring, etc.), and to help find certain bugs earlier.

Indirectly, optimization is also served: the best way to optimize code is probably to use type inference, and type declarations can sometimes help the type inferencing algorithm overcome dark spots.

But I don't want to lose duck typing; I think that when I declare an argument's type to be some interface, any object that happens to implement the set of methods defined by that interface should be acceptable, whether or not its class explicitly declares conformance to that interface.

This isn't a justification for type declarations, but for interface declarations.

But we don't need that level of static analysis to support source checkers (like PyChecker or PyLint) or to allow auto-completion in IDEs.

About two years ago I noticed something. I was depending less and less on the type system for safety. My unit tests were preventing me from making type errors. The more I depended upon the unit tests, the less I depended upon the type safety of Java or C++ (my languages of choice).


I had sided with the "Static" side. Recall however, my arguments were not for more correctness checking rather it was a realization that being more explicit allows a compiler to do a lot of the thinking for you. That is, the navigation, auto completion, on the fly checking, quick fix capabilities that you find in Eclipse and IDEA tend to outweigh the productivity benefits of any dynamic typed language.

  • From the comments:

I know no such thing. I use IDEA for java development. Its just OK. Not great. Compared to working in a Smalltalk development environment its still no contest. Smalltalk is a live environment with a debugger that supports fix and continue available.


So it boils down to this - do you want to be constrained in terms of flexibility or provably, formally, "correct" at some probably academic level?
I'll take flexibility thank you very much!

Here is a bold statement. By 2010 "compilers" will be a quaint anachronism. A throwback to the days when illusions of speed and illusions of correctness held sway over real speed (massive parallelism such as XGrids) and flexibility-based-design.


However, good developers do not use simple text editors to write their code. They use IDEs like Visual Studio and Eclipse. These tools not only colour highlight your code, but often can assist you in many other ways.


Auto Completion is often touted these days as the main advantage of statically typed languages. Auto completion, however, only helps to type the code in. It's not the typing of the code that's the problem.

  • software rigidity
    • coupling
      • type

So, object oriented programming principles try to reduce the rigidity of software by reducing the coupling.Now, what does static typing (more specifically, manifest typing) give us? More coupling.

Auto Complete doesn't solve the problem at all. The problem is coupling, not entering code.

If you need an IDE to be productive in a language, you've got a crappy language.

Um, the main advantage of a sound static type system is safety, I would think. With a static type system you can give certain guarantees about a program and the fact that the program compiles is a mathematical proof that it fulfils given guarantees.

As said by michaelw, most changes to your classes will result in changes to your system, a static typed enviroment will tell you where these changes need to happen at compile time, a dynamic enviroment will tell you at runtime.

In my experience, the errors caught by the compiler and static typing are only a small subset of the errors that actually occur. Type mismatch errors are typically caught early and don't reach production. Good testing practices do more to ensure program correctness than compiler checks ever could.

I generally look at Smalltalk's IDE as playing with a live patient. You are in the middle of a living and breathing system that reacts immediately to you. There's no shutdown, compile, restart, and retry. It's all happening right here and now. It's an incredibly cool experience especially when you realize that you can execute any code and inspect the state of the system.


There are almost no declarative elements in the language. You have somehow to think about communicating contracts between different developers across the team.

Elements of lightweight methodologys like continous integration and early unit-testing are mandatory, not optional.

IMO Python is great for smallish apps, but its advantage over e.g. Java actually *increases* with the size of the app.


A good type system (and remember, Java/C++/C# are not what I'd call good type systems) imposes a little bit of discipline, not undue hardship, and in return the compiler saves you from writing pages and pages of tests (which also need to be debugged, and maintained) just to ensure you're not trying to do something silly like take the square root of a hash table.

Being able to run your code and make sure that this particular run covers 100% of your code (just to make sure that the method you want to rename has been invoked by all the call sites. *All* of them).

The refactoring technique outlined above is only a theoretical way of doing Rename Method in Smalltalk presented in some paper (I don't remember which). It is not how it's actually implemented in modern Smalltalk IDEs. Instead they rely on statical analysis just like the Java ones. I think they might do some runtime statistics gathering but running the app is not required to do a refactoring.

3) afaik the current Smalltalk IDEs only automate one very special case - global rename - every method named X (in any class) is renamed Y, and every call of X is changed to call Y.

4) In contrast, if we had static type information then we could automate method renaming for a method X in class A without changing method X in class B.


The compiler can and should force you to write code that handles the null case.


Most people who spent much time in the low-level trenches writing C code embraced the strong-typing anality of Java and its ilk, because it does cut off a lot of stupid errors at the pass.

But, it turns out, Test-Driven Development cuts them off better; much better. And there is no doubt whatever that you can create software a lot faster, maybe an order of magnitude faster, in high-level dynamic languages.


So the conclusion: static typed languages are thought to be safer but dynamic ones turned to be more bug-free; static typed languages "stay in your way" of expressing your thoughts in programming while dynamic ones are more naturally at expressing ideas and experimenting. So why everybody insists on static typed languages?


I have argued before that the amount of time required to add tests specifically needed because of the use of a dynamic language is less compared to the amount of time you lose to compilation and what little help you get from type safety. I honestly think type safety should be viewed more as an opportunity for optimization and less as protection against errors.

And as for the refactorings, I still lean towards the idea that this is listed as a strength while masking it as a weakness of the language. Python doesn't need this level of refactoring as much as there are so many ways to rework code to handle API changes



He seems to require static typing only because it allows reliable refactoring by an IDE. Though, in my mind, an IDE could possibly refactor decently without static typing. It's just that static typing makes the job much easier.
The problem for the IDE is that with OO languages, namespaces (class instances) can be passed around at runtime as first-class objects. When you want to rename a variable or function in a particular namespace, the IDE has to figure out all of the different locations in code that refer to that variable in that namespace, without misidentifying a variable with the same name, but in a different namespace.

I think what he's saying is that what a refactoring tool can do in a statically typed language is more than what a refactoring tool can do in a dynamic language. As far as I have been able to gather, this is true. However, he probably underestimates what refactoring tools can do in a dynamic language and ignores that Java's reflection makes it subject to those same limitations.



Only a subset of all possible programs can be written with statically typed languages. For some people that is enough.[3]


For optimisation, more is known about a program written in a dynamically typed language at runtime than is known about programs in statically typed languages at compile time.[4]




Edit - BackLinks - Tags - Page Hist - Print - Changes - Home - Orphans - Help

Zuletzt geändert am 30.12.2011 13:57 Uhr und seit 7. April 2005 3801 aufgerufen.