programacion-deduccion-tipo-por-contexto

Type Deduction by Context

  • 5 min

Type deduction by context is a modern feature of several programming languages that allows compilers or interpreters to automatically infer the type of a variable based on the context in which it is declared.

The choice between typed and untyped languages has been a constant topic of debate in the programming world (and it’s now more boring than carrying a camel in your arms 🐫).

One undeniable advantage of dynamically typed languages like JavaScript or Python is that the syntax is more concise and simpler, by avoiding having to specify the type of the variables we create.

However, as programming languages evolve, mechanisms have also emerged that seek to simplify the verbosity of typed languages, without sacrificing the safety and robustness that typing provides.

Thus, languages like C# and C++ use the reserved words var or auto, respectively, to tell the compiler that we want it to deduce the variable’s type during compilation.

Type deduction by context allows declaring variables in typed languages almost as conveniently as in untyped languages.

In fact, “untyped” languages internally are typed. They simply make very intensive use of these mechanisms.

Examples of type deduction in different languages

Let’s see some examples of type deduction by context in different programming languages.

In C#, the var keyword is used to deduce a variable’s type based on the initialization expression.

var number = 42; // The compiler infers that 'number' is of type int
var text = "Hello, world"; // The compiler infers that 'text' is of type string
var list = new List<string> { "one", "two", "three" }; // The compiler infers that 'list' is of type List<string>
Copied!

In C++, the auto keyword is used to indicate that the variable’s type should be deduced from the initialization value. This is especially useful for long or complicated types.

auto number = 42; // The compiler infers that 'number' is of type int
auto text = std::string("Hello, world"); // The compiler infers that 'text' is of type std::string
auto list = std::vector<std::string>{"one", "two", "three"}; // The compiler infers that 'list' is of type std::vector<std::string>
Copied!

In JavaScript, type deduction is implicit and does not require special keywords. A variable’s type is automatically inferred based on the assigned value.

let number = 42; // The interpreter infers that 'number' is of type Number
let text = "Hello, world"; // The interpreter infers that 'text' is of type String
let list = ["one", "two", "three"]; // The interpreter infers that 'list' is of type Array
Copied!

In Python, variable types are automatically inferred at the moment of assignment. It is not necessary to specify the type, as Python is a dynamically typed language.

number = 42 # Python infers that 'number' is of type int
text = "Hello, world" # Python infers that 'text' is of type str
list = ["one", "two", "three"] # Python infers that 'list' is of type list
Copied!

Best Practices Tips

Type deduction by context reduces repetitive code and avoids the redundancy of having to specify the type explicitly when it is already evident from the assignment.

Furthermore, it improves code readability. For example, consider the following case in C#.

// it's easier to read 
var list = new List<string> { "one", "two", "three" }; 

// than this
List<string> list = new List<string> { "one", "two", "three" }; 
Copied!

On the other hand, it also facilitates maintenance. By not relying on an explicit declaration, changes in data types are automatically propagated if the initial assignment changes.

For example, if we have a function that returns a type,

// method that returns an object of type myClass
myClass DoSomething()
{
	// ... function content	
}

// many lines down, create an object with the method
var myObject = DoSomething();
Copied!

If at some point someone changes DoSomething to return something else (for example, ImyInterface), it is not necessary to change var myObject = DoSomething();, the changes are automatically “propagated”.

However, there are also many detractors of type deduction by context. Mainly people who are very accustomed to traditional strongly typed programming.

Thus, it is often advised not to use it in situations where the type is not obvious. For example,

// here the type is obvious
var myList = new List<string>();

// here the type is not obvious
List<string> myList = myMethod();
Copied!

In the end, the decision is yours. Personally, I recommend using type deduction by context even in soup. But it’s not an absolute truth. The best thing is for you to form your own criteria.