15 ms·
Why do dynamic languages make it more difficult to maintain large codebases?
- justinzollars 13y agoIts difficult to maintain large codebases period.
- humanrebar 13y agoFrom the link: "Let me begin by saying that it is hard to maintain a large codebase, period.... That said, there are reasons why the effort expended in maintaining a large codebase in a dynamic language is somewhat larger than the effort expended for statically typed languages. I'll explore a few of those in this post."
- Beliavsky 13y agoMaybe 100K LOC in a dynamic language is more difficult to maintain than 100K LOC in a statically typed language, but what if the same functionality requires 500K LOC in the statically typed language? It is easier to maintain a small code base, other things being equal.
- ori_b 13y agoWhy would a dynamic language be five times shorter, given a modern statically typed language such as Haskell, Ocaml, Scala, or even Go? Even C++11 has powerful abstractions that can cut down the size of a codebase significantly.
- fleitz 13y agoWell for Haskell and ocaml, it's more the type inference and functional nature than the static typing that saves code. As for scala, it's not quite as functional or well typed inferred as the others... interested in what the LOC savings would be. Realistically though what's being compared is Ruby/Python vs. Java. It's much more than just the language it's the culture, java is just plain bureaucratic, a lot of routine paperwork for not a lot of functionality.
- Cthulhu_ 13y agoBecause often 'static language' is used in place of 'Java'; pretty sure those languages are much more succinct and readable than Java is, thus they're not as likely to become 'large' codebases. I'm probably wrong though. Whenever I recall programming in Java though, I remember highly verbose, boilerplate-ridden codebases, and bits of code that are little more than abstractions for bits of code underneath them (with unit tests alongside them that test bit of code A calls functions B and C, which of course has no value whatsoever). Nowadays I do Javascript, much better. Today I frowned upon a colleague who is used to Objective-C who proposed writing documentation. Pfff.
- kasey_junk 13y agoBut this is a very big problem. It seems to me that the popularity of dynamic languages recently is almost entirely driven by Java backlash. So developers with limited experience encounter some big "enterprise" Java code base and recoil in horror. Instead of making the deduction that enterprise Java is terrible, they jump all the way to compile time types being horrible.
- fit2rule 13y agoI'd say its because its easier to get on with human-friendly abstractions in a dynamic language. For example you spend less time packing structs into something that can be used by a customer with a dynamic language. Things happen faster, if all you've got is a number, string, and table type. So, you end up with abstractions that do more.
- pnathan 13y agoHonestly, "statically typed language" often means C#/C++/Java. All languages which trend verbose. While Scala/Haskell/F#/etc are great at concision, they aren't that common in traditional SW industrial applications.
- GyrosOfWar 13y agoModern C# and C++ both have facilities that make the languages much more concise (lambdas in combination with std::algorithm resp. LINQ, type inference and the like). Java 8 will also have some of that and I can see it becoming a much nicer language to work with because of those changes.
- pnathan 13y agoQuite correct. But historically - and worse, codebases with a Standard Style that is perhaps older - these languages trend verbose. IME, I've tried to make super concise modern C#, and it simply isn't concise compared to Haskell or even Python. YMMV, of course.
- _random_ 13y ago1. C# is not as verbose as Java and C++. Latest versions especially. 2. C# supports dynamic typing as well as static. 3. C# and F# are the easiest to mix and match within one solution.
- marcosdumay 13y ago> C# supports dynamic typing as well as static. Are you talking about automatic types? Because that's the only thing that resembles dynamic typing I ever found in C#. And it misses about all the reflection available in most dynamic types languages, thus, even if it's somehow possible to not define types, it's useless.
- danbruc 13y agoC# fully supports dynamic types [1] and has very good reflection support [2] since version one. [1] http://msdn.microsoft.com/en-us/library/dd264736.aspx http://msdn.microsoft.com/en-us/library/dd264736.aspx [2] http://msdn.microsoft.com/en-us/library/system.type.aspx http://msdn.microsoft.com/en-us/library/system.type.aspx
- dnd 13y agoLoC is already a poor measure, but if a good effort at solving a problem meant you ended up with 500K LoC in a static language, and you could somehow know that solving the same problem in a dynamic language would have produced just 100K, the take away there is that in that instance you probably chose the wrong tool. I don't think it says too much about static vs dynamic languages and maintaining a given size program over time.
- asdasf 13y agoMaybe 100K LOC in a static language is more difficult to maintain than 100K LOC in a dynamically typed language, but what if the same functionality requires 500K LOC in the dynamically typed language?
- acdha 13y agoTalk about begging the question. It would be far more interesting to talk about the characteristics which make large codebases easier or harder to work with and how to encourage those practices in different environments.
- humanrebar 13y agoI thought the linked answer did pretty much what you suggest. Was it missing something?
- acdha 13y agoThe first paragraph started out reasonably well but then it detoured into a bunch of discussion about details which were specific to JavaScript rather than the class of dynamic languages as a whole. It felt a lot like saying static languages were hard to write maintainable, secure programs using C as the only example.
- fit2rule 13y agoI maintain a large set of codebases right now, and the most easy to maintain is certainly the components written in a dynamic language (Lua). Its so darned pleasant to return to that module, after dire straits suffered in Java- and C#- realms, that I'm seriously considering just moving everything to Lua, from here onwards. So I don't know if I have an answer to this question -but certainly it appears, to me, that the more dynamic the language is - the easier it is to maintain .. certainly the mere fact of lighter tooling means this is true?
- humanrebar 13y ago> I maintain a large set of codebases right now... Does that mean you have a large set of small-to-medium-size code bases? Because, though that's also a hard problem, it's different than maintaining one huge code base.
- fit2rule 13y agoThe Java codebase is 170k lines. C#, about the same. Lua, about 45k. I don't know if thats a lot of little codebases, but sometimes it feels seriously dystopic moving around the Java stuff.
- humanrebar 13y agoWell, huge is relative to many things. Thanks for the ballpark numbers though. Pain points change and intensify over different orders of magnitude.
- _random_ 13y agoSo how do you refactor a method signature to swap argument order in Lua? Please don't answer "manually".
- malyk 13y agoWhat's wrong with doing it manually, especially if you have good tests?
- VeejayRampay 13y agoDo we have actual studies about this? Does it take into account the cost of initial development? The cost of fixing bugs? The maintainability and the learning curve?
- agentultra 13y agoNot many that I'm aware of. One commentator on the answer on SO asked for references for the claim of a, "strong correlation," but none was given by the OP. The commentator produced one link that they're aware of.
- VeejayRampay 13y agoNot saying it's not true by the way. Even as a programmer that primarily uses a dynamic language (Ruby) I can totally see how types, a good compiler, enforced interfaces and more control mechanisms can benefit the development cycle, but in general, I tend to prefer hard cold facts and numbers over anything else.
- badman_ting 13y agoWhy, that's simply an indication that you haven't chosen the right tool for the job! Remember, using the right tool for the job is paramount. That's why every blog post on HN about libraries/frameworks/languages ultimately boils down to "use the best tool for the job". So if dynamic languages are making it harder to maintain your code, that means you chose wrong, tool-wise and/or job-wise. Remember, great software can be made with any programming language! This is why all your favorite apps are written in Visual Basic. Hope this helps!
- humanrebar 13y agoIsn't the question about choosing the right tool for the job? > So if dynamic languages are making it harder to maintain your code, that means you chose wrong, tool-wise and/or job-wise. The issue with large code bases is that rewriting everything is too expensive, so by the time you have data and experience showing your code base is difficult to maintain, it's already too late.
- humanrebar 13y agoFrom the link: "Rather it is also everything else [correctness facilities besides static typing] that is frequently missing from a dynamic language that increases costs in a large codebase. Dynamic languages which also include facilities for good testing, for modularization, reuse, encapsulation, and so on, can indeed decrease costs when programming in the large, but many frequently-used dynamic languages do not have these facilities built in. Someone has to build them, and that adds cost." ...I think that's a little generous to statically typed languages. C and C++, both heavy-hitters in the static language world, have anemic modularization, reuse, encapsulation, mocking frameworks, etc.
- trjordan 13y agoThe core of the argument is that the features of static code bases are something you need anyway when programming in the large, and I basically agree with that. I'm not totally convinced, though. Take the simple case of "tell me what range of values to expect here". Java / C++ deal with this with their types, and you can be reasonably confident that you're getting the object you expect. As I'm sure somebody will mention, those types are a bit weak, and can't guarantee the object you get is exactly what you expect. What if you don't test with the right sub-class? What if it's an int, but it's out of the range you expect? "No, that's not what types guarantee!" you may say. And it's true. I think one of the problems is that language features aren't perfect. Forcing everybody to admit they're dealing with integers is more desirable than no contract at all, but would it be better if you dealt with Scores, which where integers in the range of 0-100? In a big enough codebase, the language is never powerful enough to handle all your checking for you, so you need some level of discipline. I worry that by having something "good enough" when your code base is moderate, it allows teams to slip by into "large" without ever considering what their tools, conventions, and limitations should be.
- gaius 13y agoBetter than that, you can enforce that a Score is a Score, not just any integer between 0 and 100. You can put units in there, so a Score must be in Points. This is all normal in Ada and off the top of my head, F# has it too.
- platz 13y agoJust create a type in any language and you can do it there too
- gaius 13y agoWell, yes and no. You could in Java create a class called Score with get() and set() methods, set() taking another class called a Point as its input, and throw an exception if the value of Point is outside the range, but the overhead of that would be huge both at development and at runtime. With expressive types in the language, there's minimal extra effort in development (in many cases much less since now the compiler can do things that otherwise you'd need unit tests for) and none at all at runtime.
- samatman 13y agoStatic and dynamic are nearly orthogonal to strong and weak typing. A language with strong typing facilitates communication about the intent of code as well as its function. Strong typing is easier to build into a static compilation phase, but this is not an absolute requirement. Granted, three of the four quadrants are well covered. Dynamic, strongly-typed languages will take a speed hit unless designed by a wizard.
- danbruc 13y agoStrong and weak typing don't even have commonly accepted definitions...
- michaelochurch 13y agoStatic and dynamic typing tend to fall down in different ways at Big Code. Dynamic typing can make some kinds of versioning hell in distributed systems less of a problem (which is why languages designed for distribution, like Erlang) tend to be dynamic, and compile speed can be a massive PITA in a language with a static type system worth using (like Scala). If you're using Java or C++ or mainstream OOP, you're not getting the benefits out of static typing anyway and a Python or Clojure is a big improvement. That said, there are domains where compile-time static typing is extremely useful (and justifies the associated costs due to, e.g., the loss of a Lisp's intuitive macro system and first-class REPL) but those are going to call for a Hindley-Milner type system, not Java's weird mess of one.
- scott_s 13y agoIf you're programming in Java, C++ or another OOP language, you are still getting benefits from static typing. It's not as strong as if you were programming in a language with a more robust type system, but I cannot agree that there is no benefit.
- _random_ 13y agoCorrect, dynamic languages are very good for scripting and as a glue between components.
- detrino 13y ago> If you're using Java or C++ or mainstream OOP, you're not getting the benefits out of static typing anyway What is it that about Java or C++ or OOP that you think makes their static typing useless? > but those are going to call for a Hindley-Milner type system, not Java's weird mess of one. Hindley-Milner is actually a poor type system. It trades away powerful features like overloading and subtyping in exchange for global type inference. Scala, like C++ and C#, does not use Hindley-Milner but a kind of local type inference.
- mightybyte 13y ago> What is it that about Java or C++ or OOP that you think makes their static typing useless? He's not saying their static typing is useless. He's saying it's not an accurate representation of the state-of-the-art in static type systems. > Hindley-Milner is actually a poor type system. It trades away powerful features like overloading and subtyping in exchange for global type inference. Something that you may think is a good idea in one context may not be such a good idea in another context. I'll take Haskell's type classes over subtyping any day.
- frou_dh 13y agoStatic typing is a blanket of testing that covers the entire project. Likely not thick enough to be sufficiently warm, but still a better base layer than a patchy sprinkling of straw.
- ldarcyftw 13y ago(Unit)-tests are mostly procedural while types are declarative (describe intentions) so good IDE can speculate about those intentions and enable better refactoring.
- MikeTaylor 13y agoFor a contrary perspective, see my blog-post "We can’t afford to write safe software" (http://reprog.wordpress.com/2010/06/05/we-cant-afford-to-write-safe-software/ http://reprog.wordpress.com/2010/06/05/we-cant-afford-to-wri...) in which I make the rather obvious point that all the scaffolding you have to erect in statically typed languages is itself a cost, and that ignoring that is misleading. ("You have to fill in a form in triplicate before you can throw an exception", as one of our poets has written.) Please note (if you can't be bothered to read the actual post before responding), I am _not_ saying that static typing has no value. I'm saying it has both a value _and_ a cost, and too many arguments seem to consider only one of these.
- ggchappell 13y agoI don't think you are really arguing against static type checking in that post, but rather the explicit type declarations that often accompany it. These are not the same thing. See Haskell for a counterexample. EDIT: I see that Haskell is mentioned in the comments. Still, I don't see any understanding there that static vs. dynamic is not the issue.
- Buttons840 13y agoHaskell is inspiring, I did the interactive "Try Haskell" tutorial and though "Oh, it's dynamically typed." Later I found it it's just really good and inferring types. From what I've read, it sounds like good Haskell practice is explicitly declare types on functions, but otherwise never declare types. The compiler can then use the few explicit declarations you have made to infer all the other types.
- IsTom 13y agoMost of the time compiler can do without most top-level declarations too. They're a form of documentation enforced by the compiler.
- asdasf 13y agoThe compiler can already infer all the types anyways, you don't need to declare types. It is considered good practice (and -Wall warns for it) to provide types for top level definitions, as they are usually important enough to warrant this form of machine checked documentation. note: Yes I know the compiler can't actually infer all types all the time, but the exceptions are obvious and require type information in dynamically typed languages too (ie. convert a string to an int: you have to tell it you want an int, you can't just say "convert this string" and have it guess what you want it converted to).
- hawleyal 13y agoWow, that author has not been keeping up with changes in the JavaScript scene.
- BlackDeath3 13y agoI find that hard to believe.
- morganherlocker 13y agoOften times I find large static code bases to be lacking tests. When you have type safety, the tendency is to test less, and in many organizations, forgo testing entirely. A dynamic language will force you to write tests a lot sooner, before the whole codebase turns into a bad game of jenga. In my experience, testing seems to be a lot easier in a dynamic language as well. I would say that the most stable codebase would be a static one with lots of tests, but I would also guess that this would be the slowest to develop, and would be the most difficult to implement in a real world team of developers. I know most of us would balk at a huge codebase with zero tests, but it happens all the time. I would definitely prefer a dynamic code base in which I could get my team to write decent tests, but give up type safety, than to have type safety at the cost of decent tests.
- leobelle 13y agoWhat research exists that testing actually is worth it? I feel like people seem to take it for granted and speak about personal experience and personal values but I never read about any actual convincing research that shows TDD as actually being beneficial. It's more like a cargo cult: Write tests and things will be well.
- jasonwocky 13y agoWhat alternative do you propose, and what "actual convincing research" shows that your approach is actually beneficial? In the context of software engineering approaches, "What research exists?" is basically a conversation killer of a question. The scientific method, when applied to medium-number, complex-interaction systems like most business settings, offers very little in the way of predictive power. At best, it may illuminate some dynamics and raise some questions to ask, but rarely predict the future in the way that hard sciences research does. This is why, if you a predisposed to label something like TDD as "cargo cult", you will likely never find any published research to be "convincing". But that said, a simple search for "published tdd research" turns up quite a few hits, including this one from Microsoft right at the top: http://research.microsoft.com/en-us/groups/ese/nagappan_tdd.pdf http://research.microsoft.com/en-us/groups/ese/nagappan_tdd....
- 13y ago
- kenster07 13y agoSo after reading through the comments, a lot of devs apparently do not make the distinction between static typing and Java.
- kansface 13y agoWould you elaborate?
- mattgreenrocks 13y agoI'm curious what the experience is of maintaining larger codebases in functional languages. I ask this because it seems like a lot of "big code" issues stem from poor development practices polluting the codebase over a long period of time, destroying any sort of design that once existed. Does it help if the language takes a hardline stance against mutable state and side effects? I'm certain you can screw those up, but it's confined to a single place.
- taf2 13y ago# randomly placed in an initialization file Object.class_eval do def to_s "a" end end # in some other context perhaps a controller action... def lookup_user user = User.find_by_name(params[:name].to_s) if user.blank? flash[:error] = "No user found by that name" redirect_to "/users" return end # good stuff goes here end # # try debugging it... it's tricky... use grep? # the thing is this is actually not too bad... in C++ try debugging a memory leak... (formatting...)
- pjmlp 13y ago> C++ try debugging a memory leak... On a codebase writen by a team scattered around the globe, with the customer shouting on technical support and on site support team to know when the fix is ready. I like C++, but I don't miss manual memory management.
- SixSigma 13y agoThis question is begged.
- adrianlmm 13y agoIn my own experience, the problem has been dedugging.
- phamilton 13y agoIn my experience this all comes down to proper decomposition of services. Don't have large codebases. Break it down into individual services, libraries, etc. Version your APIs. Use proper semantic versioning in your libraries. Most of the trouble I've found has been in changing code that is coupled to a lot of other code. That sucks in every language. It's worse in dynamic languages only because detection is harder and tooling is weaker. Sounds great on paper, I know, and is much harder in practice. But if done correctly then dynamic languages are awesome boosts to productivity.
- apaprocki 13y agoI have a pretty different experience here.. we have 30+ million lines of JS in production (2k+ devs and tens of thousands of files -- it isn't as scary as it sounds). Prior to converting app development to JS in 2005, development was mostly done in C/C++ and the boost in productivity by writing things in JS has been clear as day. This isn't to say that it is easy to maintain; in our case, a core infrastructure team maintains the guts reasonably well (+dev/test tools) and it allows higher-level teams to build the product. The best feature of the script when it comes to higher-level product is that large portions (if not the entire thing) can be scrapped and started anew in a different way without a significant loss of investment. I suppose a distinction could be made between referring to a single large product/codebase versus a much larger amount of physical code but split between many teams/products. There are probably only a handful of apps that wind up being "large" (in the 10k+ LoC range).
- mightybyte 13y agoThere are several things about this post that make me really question its validity. "The best feature of the script when it comes to higher-level product is that large portions (if not the entire thing) can be scrapped and started anew in a different way without a significant loss of investment." Large portions can be scrapped and started anew without significant loss of investment?!? Is this code being auto-generated somehow? If it's legit actual lines being written by your developers, then that is the definition of a significant investment. And if you're redoing it, then that's by definition loss of the original investment. "There are probably only a handful of apps that wind up being 'large' (in the 10k+ LoC range)." What are you smoking? I've got more than 10k LoC in an app that has only been under development by < 2 developers for a few months. My company has another app built by one guy that's more than 30k LoC. And you say you have 30+ million LoC in production?!? If 10k is "large" for you, then you must have a shitload of apps out there. Also, there's a huge difference between maintaining 3000 apps with 10k LoC and maintaining even one app with >1m LoC.
- frankc 13y agoThey have thousands of apps. Maybe 10s of thousands by now. It's been many years since I worked there. It's a pretty unique setup.
- agentultra 13y agoGiven the lack of evidence to support the claim I find the argument specious. There are large code bases written in dynamic languages that are well maintained by thousands of contributors that could weaken such a claim without strong data backing it up (OpenStack comes to mind). The author fails to provide a link to a single study and relies purely on intuition for eir argument. I only see one link to that answer on SO that points to a single study. It was provided by another commentator asking for the OP to provide evidence for the "strong correlation," claim. Not very good. Though I'd hate to work with a team that used a statically typed language and tools that didn't write tests for their software. It's not magic soya-sauce that frees you from ever introducing bugs into your software. Most static analyzers I've seen for C-like languages involve computing the fixed-point from a graph (ie: looking for convergence). Generics makes things a little trickier. Tests are as much about specification as they are about correctness. In my experience there are some things you will only ever know at run-time and the trade-off in flexibility for static analysis is not very beneficial in most cases. Some interesting areas in program analysis are, imho, the intersection of logic programming, decomposition methods and constraint programming as applied to whole-program analysis. Projects like kibit in Clojure-land are neat and it would be cool to see them applied more generally to other problems such as, "correctness," and the like.
- Peaker 13y agoMy experience with Python had been that scaling to large code bases is possible, but the burden of the late runtime errors and lack of type documentation accumulates. The beginning of the project is wonderfully productive. By the time you regret having chosen a dynamic language for the project, it's too late to switch.
- coolsunglasses 13y agoThis is why I've been describing untyped/uni-typed languages as tantamount to taking a pay-day loan against your own project.
- jokoon 13y agoI guess we should just understand what's the goal of scripting versus what's the goal of statically typed languages. Statically typed languages should just provides code that need to be reused often. Also needed when you need performance or low power consumption. Scripting should be about using those libraries together. People should try to understand how gmail works, because I think javascript is just used for presenting data to a browser, while gmail servers do the heavilifting.
- puppetmaster3 13y agoWow, what disinformation. My background in static like Java has been that moving to dynamic makes it easier to do large.
- njharman 13y agoCode base is incorrect metric. (Good) Dynamic languages enable smaller code bases. And you really, really should try harder to make small isolated components (services, daemons, sites, commands, whatever) and avoid large codebases.
- msane 13y agoSeems a bit trolling. http://en.wikipedia.org/wiki/Complex_question http://en.wikipedia.org/wiki/Complex_question
- jrockway 13y agoUnfortunately, everyone uses statically-typed languages wrong, so they get about the same protection with their compiler that you get with Ruby or Perl or Python. Consider this common mistake: interface Greet { void sayHello(String firstName, String lastName) } class PrintGreeter implements Greet { public void sayHello(String lastName, String firstName) { ... } } Where's your compiler NOW?
- kasey_junk 13y agoThis is a classic example of when to use the Value type pattern. You are in fact arguing for stronger typing (String is too limited here). If you language makes that problematic, it is the fault of the language implementation, not a problem with static typing.
- jrockway 13y agoThe people writing "dynamic languages suck" blog posts are merely unaware of how much dynamic typing they do every day in their statically-typed languages. And yes, I am arguing for stronger typing. And for getting rid of null. (I've seen plenty of Haskell programs that are not compile-time checked for, say, XSS problems, even though it's trivial to do that with the type system. The problem is that nothing is ever automatic; if you want to write the best possible code, you have to make it a goal and carefully execute that goal. There is no silver bullet.)
- robrenaud 13y agoAnd that's how to piss off staff engineers, bring down production bigtables, and get to write your first regression test :). (I swapped key and value in a string, string API and ended up writing 5+ MB "keys".)
- deleted 13y ago[deleted]
- coolsunglasses 13y agoHaskell libraries and programmers are good about using type synonyms to avoid this problem. Notice http://hackage.haskell.org/package/happstack-server-7.3.2/docs/Happstack-Server-Types.html#t:Method http://hackage.haskell.org/package/happstack-server-7.3.2/do... isn't a string like "GET" or "POST".
- danbruc 13y agoWhy needs this to be discussed again and again? It is such an obvious thing. Use a statically typed language and you get a proof that your program does not contain bugs of a certain class for free. Use a dynamically typed language and you lose this proof or you have to do it on your own. Does this proof come with price tag attached? Yes, but a very small one - sometimes type inference fails and you are forced to manually specify the type. I don't see why this is worth any discussion.
- adamlett 13y agoMy theory: Many proponents of various dynamic languages simply cannot find a statically typed language that is appealing to them. You say the price tag of statically typed languages is small, and while that may be true in theory, in practice it is not if it means that a language is more verbose (Java, C#), properitary (C#), complex/obscure (Scala, Haskell) and/or immature (Scala/Go).
- midas007 13y agoTL;DR - most dynamic languages allow most things to change at any time. So with a large codebase, it's hard to know where a particular something is getting changed (or not). IOTW, it makes error traceability of the codebase more difficult.
- 10098 13y agoThis aligns well with my experience. Maintaining even medium-sized projects in Python, Javascript and PHP has been a very frustrating experience. In practice, nobody ever writes detailed comments or tests (well, not tests that test for type errors anyway. If you're lucky, you'll inherit something that tests the basic functionality of the system and that's about it.), and types are sometimes about the only thing that can help you navigate through the code. Just being able to see what types of arguments a function receives and what it can do with them has saved me tons of time.
- erikpukinskis 13y agoMaybe the kind of people who like standards and practices tend to shy away from dynamic languages. Maybe C coders are just more likely to be Style Guide people. Maybe the idea that you can avoid side effects is a fiction that the horror of manual memory management cures you of.
- c2u 13y agoReally? I don't think so.
- hurturk 13y agoManaging large codebase is nothing to do with typed property. Untyped languages just give you more freedom (see lambda calculus) but you can shoot yourself if you are not ready to use it.
- deleted 13y ago[deleted]
- voidr 13y ago> So for that reason alone, dynamically typed languages make it harder to maintain a large codebase, because the work that is done by the compiler "for free" is now work that you must do in the form of writing test suites. Static types are not enough to ensure that your algorithm receives correct input, to ensure you that you will need to write tests anyway. So with static languages you get one check "for free" out of the many that you will have to write yourself. If you rigorously write tests for a JavaScript code as you would have for a Java code, it becomes just as reliable.