Predicting Variable Types in Dynamically Typed Programming Languages
arxiv.org
arxiv.org
Modern compilers for statically typed languages are really good at inferring types of various identifiers based on multiple hints in a deterministic way (see Kotlin, Swift etc). Mentioned statically typed languages C,C++ and Java are pretty old and therefore carry some baggage of verbosity that is no longer needed.
> ...since the variable types are not declared in the source code, the source code becomes difficult to understand and extend
> For programmers working on the large code base written in dynamic languages, it is hard to understand the control flow of the program if the types are not available at the compile time.
Dynamic languages as a result of their "dynamicness" tend to allow much better expression of control flow when compared to static languages. Only recently available statically typed languages have targeted expressiveness as a first class goal in designing the language. In fact, statically typed languages are notorious for obtuse control flows as a result of their type enforcement (see C, C++, Golang)
I think it’s importatnt to mention that in Swift this lookup has exponential behavior, and can time out if the expression is too complex.
hahaha. Just getting people to adopt `auto` in C++ is an uphill battle. People want to write types.
e.g. it more or less looks like this in a trivial case :
#include <cstdio>
template<typename T1, typename T2>
struct add {
add(const T1& t1, const T2& t2): lhs{t1}, rhs{t2} { }
const T1& lhs;
const T2& rhs;
constexpr auto get() const { return lhs.get() + rhs.get(); }
};
struct integer
{
const int& i;
constexpr const int& get() const { return i; }
};
int f();
int main()
{
auto x = add{add{integer{f()}, integer{f()}}, add{integer{f()}, integer{f()}}};
}
Here, storing the value in `auto` is wrong because by the time the expression has ended, the references point to stuff that isn't in scope anymoreHence the solution is to introduce a type that will actually do the computation or store the result during the expression ; but before C++11 you had to introduce a type here anyways, which is what was done and of course it worked.
As an honest question, if types are good, why would you put auto, instead of telling me the type?
For context, I'm a neanderthal and just use a boring text editor, so I'm not getting any tool assisted type information if you write auto everywhere.
So I don't need to write additional unit tests to do the compiler's work that would have prevented Joe to check in his code.
It also makes refactoring easier. If you use var then you don't need to change all your declarations if you change a class name.
It is incredible the FUD in C# and Java against var, you see endless threads of how they are now dynamically typed like JavaScript.
Sometimes I wonder how did those ended up learning to program, don't people read books any more?!
Hell, in Haskell inference can take you pretty far, and you can defer type errors til runtime in development and basically get an opt-in dynamically typed experience!
I learned functional programming at my last job with Ocaml, and did rely quite a bit on editor tooling to give the type of things which could have been annotated, so it’s definitely a tricky balance in teams.
But I use Scala now and I wish it inferred types half as well, giving almost every type is really verbose and does feel like Java sometimes. The compiler speed is probably an issue for providing the same kind of tooling there though even if you could avoid giving most types.
I guess I’m basically agreeing with you - the combination of an ultra fast compiler and complete type inference is amazing to work with.
That may be, but I'll be damned if Golang's verbose type casting hasn't saved me from some bugs over the years.
Also, I think there's an argument for type declarations being expressive in their own right. I like seeing what types a function receives and returns. It's a quick jumping off point when trying to understand what the function does.
"FIXME: The material in the CMUCL manual about getting good performance from the compiler should be reviewed, reformatted in Texinfo, lightly edited for SBCL, and substituted into this manual. In the meantime, the original CMUCL manual is still 95+% correct for the SBCL version of the Python compiler."
Whole program analysis is too expensive for type inference (or much of anything for that matter) even with its precision ramped all the way down via something like CFA0. Type inference with sub typing is a very similar problem to alias analysis, which hints at why doing it in any but very restrictive contexts is too expensive.
It's not perfect, but it's the only way I've found that makes sense in combination with Forth-like stack semantics where function parameters are never specified explicitly. And that runs fast enough to make sense in an interpreted language. I also like that it's implemented as a transformation on VM code, which makes it flexible and easy to debug.