Slide with text: “Rust teams at Google are as productive as ones using Go, and more than twice as productive as teams using C++.”
In small print it says the data is collected over 2022 and 2023.
Slide with text: “Rust teams at Google are as productive as ones using Go, and more than twice as productive as teams using C++.”
In small print it says the data is collected over 2022 and 2023.
if random() > 0.5: x = 2 else: x = "hello"
Where is the definition of x? What is the type of x? If you can’t identify it, neither can the LSP.
This kind of thing actually happens when implementing interfaces, inheritance, etc. Thus, LSPs in dynamic languages are best effort both theoretically and in practice.
Tbf this example can be deducted as
string | int
just fine.The real problem is when you start using runtime reflection, like
getattr(obj, "x")
Types are not necessary at all.
Saying “x is defined somewhere in the entire program” isn’t satisfactory to many users. Also, you didn’t tell me what type x has. Can I do
x + 5
?It absolutely does. Without static types an IDE/LSP can’t reliably find all the references / definition and therefore can’t refactor reliably either.
Consider something like this:
class Foo: bar: int class Baz: bar: str def a(f: Foo) -> int: return f.bar + 1 def b(f: Baz) -> str: return f.bar + "1"
Now imagine you want to rename
Foo.bar
or find all references to it. Impossible without the type annotations.