A thousand times this. It's so much easier to do breaking changes and refactors in a language that's supporting you, instead of working against you.
A thousand times this. It's so much easier to do breaking changes and refactors in a language that's supporting you, instead of working against you.
It also doesn't help when most codebases are using ActiveRecord or something in every complex class and wind up increasing the interface width and ancestor depth of their code significantly. The point is - I think the language does a pretty good job supporting the developers, but there are a lot of bad practices that are still in use and recommended. Can't fault the language because people are writing shit code
The “problem” with ruby is that you basically don’t know if code is valid unless you execute it, whereas a statically typed language will enforce a lot of things during compilation and simply not allow the program to compile, if API is used in the wrong way, this could be calling private functions, referencing undefined symbols (simple typos), wrong number of arguments, passing a string where integer is expected, etc.
Additionally access control is limited in Ruby, which makes it difficult to release a library and have the language enforce that people do not rely on things which are implementation details subject to change.
For example, it's possible to fetch a class's entire interface before and after a refactor and validate it is the same. It's possible to dynamically wrap every method you're refactoring track them and type check them. And if you extend that idea, now you can output this data to files and perform static analysis. Sure, it all relies on you having some safe execution context to get this information but Ruby probably has the best testing tools of any language and many projects have great test coverage
For library owners, I agree with you - there's no hope. But for application developers maintaining their monoliths with nothing depending on them there's a lot you can do to ensure safe refactoring
Having a test execute every line in your application doesn't mean your application is _covered_ or _tested_.
Coverage tools could only measure quality of a test suite if you're assuming that either the code is perfect or that the existing tests cover (logically) everything about what they test. Without either of those guarantees, it doesn't tell you anything very meaningful, as you discovered.
If you really think that the metric is meaningless and useless for deriving confidence, then you are necessarily asserting that code bases with 100% coverage have indistinguishable bug yields compared to those with 50%, 5%, or even 0% coverage. A claim like this is too extraordinary to be believed without considerable evidence.
I could agree that a high coverage score is a prerequisite for having confidence that your test suite is comprehensive (in general), but that's such a low bar, it's like saying a full bath is a prerequisite for a nice house, just knowing that shouldn't do much to convince you it's a mansion.
Personally, I'm a fan of very strong, static type systems, so I would prefer to annotate all the things, but I understand other people have different views.
function foo(a, b) {
if (a != 3) {
return a + b
} else {
return "hello"
}
}
console.log(foo(2, 5)); //prints 7
console.log(foo(3, 5)); //prints "hello"
You can compile it and run it on the typescript playground: https://www.typescriptlang.org/play/This is not like C#, where would be required to specify that every type is "dynamic". Here, you can optionally choose to specify that the types are "Any", but it's still gradual typing.
EDIT: you said "implicit opt-out"... which sounds like a synonym for "opt-in". I don't think "implicit opt-out" is a term.
[1]: https://www.typescriptlang.org/docs/handbook/compiler-option...
function foo() {
return 1;
}
let x = foo().substring(1, 2);It still compiles the code to JavaScript even with the error, and you can still run it, which makes this more of a warning than anything else.
That warning based on type inference seems like a positive feature... because there's no situation in which that code is right. You can add `: any` to the function declaration and it will stop complaining, but I wouldn't contend that the language is not dynamic because it encourages you not to make a mistake.