Timeline for Why do dynamic languages make it more difficult to maintain large codebases?
Current License: CC BY-SA 3.0
44 events
when toggle format | what | by | license | comment | |
---|---|---|---|---|---|
Jun 16, 2016 at 8:38 | comment | added | Jas | As a maintainer I would also add that if in a dynamic language I see a variable named sp as a parameter to a function, lets say I see a function function myfunction(sp) then I have no idea what this variable is. On the other hand on a static language I would see this function myfunction(sp: SocketProvider) I would then be able to click SockerProvider and see its declaration! life much easier this way for a code maintainer!!! | |
Jun 2, 2016 at 3:04 | comment | added | Jus12 | @DirkBoer By "no one" I assume you mean "I don't". Just see the listed links where such code has been checked in. :) | |
May 31, 2016 at 11:07 | comment | added | Jus12 | @Ark-kun so do JS devs github.com/… | |
May 10, 2016 at 6:11 | comment | added | Kartick Vaddadi | I agree with you, that dynamically typed languages don't handle this case in an ideal manner, and that interface contracts are beneficial. But in statically typed languages like Java, C++ or Objective-C, contracts are often over-specified. In the above example, the function that prints a List doesn't NEED it to be a List, just that it happened to be declared that way. Ideally, you'd have type inference — the compiler should enforce that the object you're passing as an argument has the methods you're invoking and no others. Then you can reuse the above function to print a Set. | |
May 10, 2016 at 5:17 | comment | added | ruakh | @VaddadiKartick: On the other hand, suppose that tomorrow someone wants to modify the method in a way that relies on it being not just iterable, but actually a List? In Java, if it's declared as taking a List, then you know you can safely assume that its argument is actually a List. In a dynamically typed language, you can't easily tell if such a change is safe. (In other words: interface contracts are beneficial for programming in the large, and static types are frequently a valuable component of such contracts.) | |
Apr 23, 2016 at 11:11 | comment | added | Kartick Vaddadi | This is an insightful post. One point you mention is reuse, and statically typed languages often have rigid type specifications. If you have a Java function that takes in a List, iterates over it, and prints out each entry, that function may also work for a Set, but unfortunately you've specified that it takes a List, so the compiler won't let you pass a Set. Dynamically typed languages don't have type specifications (generally), so you can't over-specify the type and rule out opportunities for reuse. | |
Nov 16, 2015 at 8:39 | comment | added | Dirk Boer | I always suprised how often typo's are brought up in these discussions about static typing. Typo's is not a practical problem - it means that you're code actually has never properly run. No one writes code and then doesn't run it's code path at least once. Renaming and refactoring on the other hand is for me by far the biggest argument for static typing. | |
Jun 16, 2015 at 9:11 | vote | accept | Jus12 | ||
Jun 29, 2014 at 13:39 | comment | added | MgSam | I think this post left out a major benefit of static typing- the ability to refactor. Try renaming a variable in a million line JS application or finding all references of a variable. Without static analysis your IDE cannot possibly do an effective job with such an operation. | |
Jun 28, 2014 at 16:41 | comment | added | Jedai | C# is evolving in this direction but is not quite there yet. (there are other advantages to using C# though...) | |
Jun 28, 2014 at 16:40 | comment | added | Jedai | Clearly a certain number of the posters here are still thinking of "static typing" as equivalent to "weak manifest typing" like in C or Java... There are much better languages now like Haskell, Scala, OCaml and so on (and their more recent descendants) that provides the programmer with a very strong type system that allows to enforce not only structures but some behaviors too and do that while minimizing the burden on the programmer of specifying types by inferring most if not all types (though specifying top-level type signature is good documentation as well as good practice). | |
SJun 27, 2014 at 23:44 | history | suggested | samthebrand | CC BY-SA 3.0 | Minor formatting. Great answer that will be featured at Ars Technica this weekend. |
Jun 27, 2014 at 23:23 | review | Suggested edits | |||
SJun 27, 2014 at 23:44 | |||||
Apr 7, 2014 at 17:49 | comment | added | Ark-kun | @BenjaminGruenbaum PHP devs love writing breokn code github.com/… | |
Feb 11, 2014 at 6:07 | comment | added | robject | Still surprised that this discussion still rages on. Nothing wrong with typing. It's just that programmers suck at it. "Proper" dynamic languages are not untyped, but just smarter doing it (that is, the runtime environment has more information at its disposal). Optimising code is much easier with dynamic languages as compiler writers will confirm. And as to the readability … well that is an argument that confuses me since my experience is the opposite, having worked in both C-syntax languages and Smalltalk. | |
Jan 28, 2014 at 23:38 | comment | added | SolutionYogi | @BenjaminGruenbaum I completely agree that the type system can only capture structure and not the behavior (for now). We disagree on how much value one can get by enforced structure. Also, I feel that static type system tools will be getting smarter and help us enforce behavior as well. E.g. look at Code Contracts and Pex. Please look at this: pexforfun.com Pex will not be possible without static type system. | |
Jan 28, 2014 at 22:55 | comment | added | Eric Lippert | @configurator: Since that was the intention of the design committee in adding almost all of those features, I would certainly hope so! | |
Jan 28, 2014 at 22:03 | comment | added | configurator | @EricLippert: With Javascript Harmony (pretty much ECMAScript vNext), we get block scoping for variables with let (instead of var 's function scope), modules (with encapsulation and the whole shebang), iterators, generators, arrow function syntax, destructuring assignment, and other goodies. With that, and with "use strict" semantics (which affect eval, undeclared variables, and other issues with the original JavaScript), and with full suites of unit testing tools, how do you feel about modern server-side JavaScript? Do you feel it's now easier to maintain large projects with? | |
Jan 28, 2014 at 17:47 | comment | added | Benjamin Gruenbaum | Yes, but in the code above in JavaScript is the equivalent of forgetting a field in IMetaProvider , something the typecheck would not have found for you. My main issue with these type systems is that they do not really enforce behavior and enforcing structure is usually not really that big of a deal. The thing is while unit tests for behavior and CI is something you'd do anyway, having to slow down to specify types can be frustrating and type inference is not nearly good enough (yet!). Anyway, I think we've derailed from the issue of JavaScript enough :) | |
Jan 28, 2014 at 17:13 | comment | added | SolutionYogi | I can not give you a direct C# equivalent for the code I linked, but if I expected all set of 'Meta' classes to have property called 'proto', I will design an interface called 'IMetaProvider' and let compiler ensure that every implementation provides definition for 'proto'. | |
Jan 28, 2014 at 17:12 | comment | added | SolutionYogi | @BenjaminGruenbaum It depends on your definition of 'prohibitive defaults'. At the end of the day, purpose of any type system is to let you write set of rules/constraints to solve your business problem. You are suggesting that unit testing and tools like static analysis, CI should be used to enforce these rules. I am suggesting that one should use every available tool at their disposal (including static type system). I personally find that static type system provides me with more tools to design/enforce rules. Yes, I do give up some flexibility but the trade off is worth for me and my team. | |
Jan 28, 2014 at 17:06 | comment | added | Benjamin Gruenbaum | @SolutionYogi so your point is that a really bad dev team benefits from prohibitive defaults? Can't disagree with that, also, don't care much about bad teams. My point was that these issues are an education problem and not a language problem. JSHint is a very basic static analysis tools (there are much better ones available like closure compiler for example, jshint was given as an example for braek or conitnue ). In your example the developer forgot something in a configuration object (like a Dictionary in C#) - I fail to how a see static type check would have helped (a test would). | |
Jan 28, 2014 at 16:49 | comment | added | SolutionYogi | And you wanted an example, check this commit: github.com/emberjs/ember.js/commit/… The developer forgot to follow certain rule and had to go back and fix it. In statically typed language, you can enforce certain set of rules so that a developer never 'forgets'. Mind you, I am not trying to knock this developer. Developers are humans at the end and sometimes we will 'forget' to do certain things. But if you have huge set of rules and a decent sized team, it's simply better to have a compiler/static analyzer enforce those rules. | |
Jan 28, 2014 at 16:45 | comment | added | SolutionYogi | Benjamin, if you are talking about a mature development team who uses IDE, static analysis tool and CI server, you can definitely workaround the limitations of a dynamically typed language. But in a world where there are teams who haven't moved to DVCS and CI server tools, having the language enforce the rules while you are writing code is tremendously useful. And jslint is useful, but it can NEVER be as powerful as a static analysis tool targeting a statically typed language simply because there is not enough type information to analyze. | |
Jan 28, 2014 at 15:18 | comment | added | Benjamin Gruenbaum | @EricLippert Please name some such codebases. JavaScript codebases I've worked with would have caught that error at three different steps (before check in). First in the IDE, second with static analysis commit hooks (jshint for example) and third in the CI server. JavaScript has not changed much, but the culture certainly has. People write poor code in any language when they do not understand the underlying issues and actual challenges (it's also a repeating motif in your blog, I'm a fan). How many C# code bases abuse GC.Collect() ? Or casting? It is mainly education that promotes good code. | |
Jan 28, 2014 at 14:57 | comment | added | Eric Lippert | @BenjaminGruenbaum: Your criticisms are warranted; however, I would suggest to you that a close look at many large modern JS codebases finds many examples of the sorts of problems I cite; just because disciplines exist does not imply that everyone knows about them and uses them. And you might also be surprised at the number of times a JS loop contains a braek; or cotninue; statement -- perfectly legal! Doesn't do what was intended. Still got checked in. | |
Jan 28, 2014 at 13:39 | comment | added | Benjamin Gruenbaum | Also, I just want to add that hearing an uninformed answer from someone usually as knowledgable as you is very surprising and somewhat disappointing. There are plenty of problems with JS but you simply listed ones that do not exist today. | |
Jan 28, 2014 at 11:10 | comment | added | Will Buck | Incredibly well explained. What was described explains well how to compensate for added complexity in dynamic languages | |
Jan 28, 2014 at 8:29 | comment | added | John Dvorak | EEK. Even new Object() is bad javascript. And the rationale is... be sure to set prototype.constructor when you're providing the default one, lest one won't be set. | |
Jan 28, 2014 at 8:25 | comment | added | Benjamin Gruenbaum | Aside from JavaScript, I agree with the general sentiment of the answer (that is "Typing is not the issue but poor infrastructure is"). Only now languages like JavaScript and Python are getting things like proper DI containers and modern testing frameworks and even more importantly - only now the community is adopting these concepts. Evolved design practices in the community are just as important as the language itself (if not more) and the adoption rates of best practices are certainly something that has been really improving in Python, Ruby and JavaScript these last few years. | |
Jan 28, 2014 at 8:22 | comment | added | Benjamin Gruenbaum | While I generally agree with your opinions, you're way off here. Modern JavaScript is very very different from what Microsoft did in 1996-2001. You have module systems (AMD, CommonJS) , you have encapsulation by convention like in Python (or closures, but I don't find that necessary), there are ways to annotate storage on variables (by using getters/setters for example) and the inheritance system is a lot better understood than it was 13 years ago. It's trivial to build strong robust applications in JavaScript today. Your example should read "let's take JavaScript from 2001 for example". | |
Jan 27, 2014 at 23:12 | comment | added | Eric Lippert | @kieran: As an example of what I mean, consider function Reptile(){ } Reptile.prototype = new Object(); var lizard = new Reptile(); var b = lizard.constructor == Reptile; Even sophisticated JS developers would be forgiven for assuming that b is true , but thanks to the crazy way JS does prototypes, that's false . | |
Jan 27, 2014 at 23:10 | comment | added | Eric Lippert | @kieran: "weak" is a bad choice of words on my part, since it implies a criticism without stating it, or even describing what would be "strong". Prototype inheritance is I think conceptually quite reasonable, but I think the way it has been implemented in JS is confusing. | |
Jan 27, 2014 at 22:45 | comment | added | B Robster | "a language that was dynamically typed but also had namespaces, modules, inheritance, libraries, private members, and so on . . . such a language would be both dynamic and highly suited for programming in the large". Python & Ruby? | |
Jan 27, 2014 at 22:38 | comment | added | kieran | Hey @EricLippert, great answer, but I was wondering if you could clarify what you mean by "weak" in "...prototype inheritance -- is both weak..."? I think it is a fairly widely held view since the introduction of self even that prototype based inheritance is more expressive than class based. In particular Delegation is inheritance suggests maybe there is more to it than only an ontology (the "deep hierarchies" that don't come out-of-the-box)? | |
Jan 27, 2014 at 20:38 | comment | added | Eric Lippert | @JoshuaClanton: Thanks for that clarification; I have not been keeping up with the changes in the specification since I stopped being on the committee in 2001. | |
Jan 27, 2014 at 20:05 | comment | added | Rag | @JoshuaClanton And anyway, you can easily get encapsulation using closures: gist.github.com/briangordon/8656177 | |
Jan 27, 2014 at 19:27 | comment | added | Joshua Clanton | One minor correction. You stated that "every property of every object is yielded up to the for-in construct." This is not true in ECMAScript 5, which adds the concept of property enumerability. For instance, Object.defineProperty will allow you to create a non-enumerable property which is not yielded to for-in. | |
Jan 27, 2014 at 18:27 | comment | added | Chris Adams | It would be interesting to compare this with other dynamic languages than JavaScript where all of the sticking points which you mentioned are far less critical and there's much better tool support. For example, I primarily develop in Python where I have static analysis tools, a robust module system, culture of unit testing, etc. and the language has been adding features like annotation support to improve this. There's an interesting discussion in how different languages have adopted features to encourage that kind of practice, irrespective of the static/dynamic divide. | |
Dec 18, 2013 at 19:15 | comment | added | Thiago Silva | I agree when you point where cost increases for dynamic langs. I can see that there might be a correlation of some dynamic langs and the lack of corresponding reliable tools available to tame correctness. But those things by themselves do not indicate in any way that dynamic lang based systems are more expensive / hard-to-maintain than "static" counterparts (what about the points where "static" systems cost/complexity increases?). "Strong correlation" is a strong statement so I was looking for data. The only related study I know of is this: goo.gl/FnszYZ | |
Dec 18, 2013 at 15:53 | comment | added | Eric Lippert | @ThiagoSilva: Languages are purpose-built. If you are building a language for programming in the large you are highly likely to add all the features that make programming in the large cheaper, which then entails a lot of "ceremony" and restrictions in what you can write. If you are building a language for, say, making the monkey dance when you mouse over it then you want a one-line program to be one line. Dynamic typing is natural for such a scenario because it is gives a lot of flexibility to the developer. | |
Dec 18, 2013 at 4:42 | comment | added | Thiago Silva | Eric, can you provide details on where the strong correlations you mention come from? | |
Dec 17, 2013 at 16:49 | history | edited | Eric Lippert | CC BY-SA 3.0 | added 520 characters in body |
Dec 17, 2013 at 16:43 | history | answered | Eric Lippert | CC BY-SA 3.0 |