Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

So we write:

Customer c = new Customer();

Why is the design not such that we write:

c = new Customer();
c.CreditLimit = 1000;

The compiler can work out c points to a Customer and allow Customer's members to be invoked on c?

I know we may want to write:

IPerson c = new Customer();
IPerson e = new Employee();

so as to be able to write:

public string GetName(IPerson object)
{
    return object.Name
}

string name = GetName(c); // or GetName(e);

But if we wrote:

c = new Customer();
e = new Employee();

we could still write:

public string GetName(object)
{
    return object.Name
}    

string name = GetName(c); // or GetName(e);

The compiler could complain about the code immediately above if the type of object c references does not support a Name property (as it can check which members are used on the argument/parameter within the method), or the runtime could complain.

Even with C#'s dynamic keyword, we are still using a variable 'type' (determined at runtime). But why does a variable need a type at all? I am sure there must be a good reason, but I can't think of it!

share|improve this question
10  
This is why there are dynamic languages like Python and Ruby (and others). There's no answer to this question. It's a fact that some languages use type declarations and some languages do not. –  S.Lott Feb 10 '12 at 23:42
1  
"variables in those languages do not have a type at all?" Correct. variables do not have a type in Python. Objects have a type and variables are simply references to objects. Your question is really just an observation. Specifically "not all languages require variable declarations". There's no answer. So it's likely that it will get closed as not constructive. –  S.Lott Feb 10 '12 at 23:55
1  
You might want to take a look at Boo, which lets you declare variables without any type declarations but uses type inference to figure out types so you don't sacrifice the correctness and performance benefits of strong typing. –  Mason Wheeler Feb 11 '12 at 0:07
2  
var x = 1; - did you mean 32 bit, 64 bit, 16 bit number? byte? float? double? decimal? This is just dealing with primitives. –  Job Feb 11 '12 at 1:18
4  
You can use var in C# and being exlicit about where you want to declare a variable is always good. –  Daniel Little Feb 11 '12 at 1:45
show 8 more comments

migrated from stackoverflow.com Feb 10 '12 at 23:20

This question came from our site for professional and enthusiast programmers.

9 Answers

But why does a variable need a type at all?

  1. This may catch bugs where an invalid, wrongly typed expression is assigned to a variable. Some languages have dynamic typing, which sacrifices the correctness guarantees of a type per variable for the kind of flexibility that you seem to desire.
  2. Types may allow the compiler to generate more efficient code. Dynamic typing means type checks have to be performed at runtime.
share|improve this answer
    
Please explain the downvote. –  larsmans Feb 10 '12 at 23:30
4  
Also, dynamic typing comes at a performance cost, because the type information needs to be checked during runtime. –  Charles Salvia Feb 10 '12 at 23:30
    
@CharlesSalvia: good point, added that to the answer. –  larsmans Feb 10 '12 at 23:31
2  
@sturdytree: as for "if it does not have a type, then it cannot be wrongly typed" -- as far as the language rules go, that's true. But the variable may still be assigned the wrong type from a semantic point of view, e.g. you mistyped a constructor name and the program still runs, but doesn't do what you want. –  larsmans Feb 10 '12 at 23:51
5  
@sturdytree While it is true that there are no languages that have truly typeless variables with type checking, there are languages that have type inference. That is to say, the language looks at your usage of the variable and deduces the type from your usage. If there is a conflict (e.g. you perform a = new Bar() and then later call a method from class Baz), the compiler raises an error. Languages like Haskell and OCaml pioneered type inference, but it is present in C#, with the var keyword. –  quanticle Feb 11 '12 at 1:10
show 11 more comments

You have a perfectly valid point, languages that do not keep track of the type of a variable exist, and are called "dynamically-typed". The category includes languages such as JavaScript, Perl, Lisp, and Python.

The advantage that we get from a statically typed language is some additional compile-time error checking.

Suppose, for example, that you have the following method:

public addCustomerContact(Customer client, Employee contact) {
   ...
} 

It would be possible, if you have a customer bob and an employee james in your code, to mistakenly call addCustomerContact(james, bob), which is invalid. But if the compiler doesn't know the types of the variables, it can't warn you that you've made an invalid call, instead, an error occurs at runtime...and since dynamically-typed languages don't check the type of parameters passed in to methods, that problem occurs whenever your code attempts to use customer-only properties of the james object, or employee-only properties of the bob object. That may be long after the pair (james, bob) was added to the list of customer contacts.

Now, you might wonder, why can't the compiler still infer the type of james and bob, and still warn us? That may sometimes be possible, but if variables really have no type, then we could do the following:

var james;
var bob;
if (getRandomNumber() > 0.5) {
   james = new Customer();
   bob = new Employee();
} else {
   james = new Employee();
   bob = new Customer();
}

It's perfectly legal to assign any value to any variable, since we said variables have no type. That also means we can't always know the type of a variable, because it could be of different types based on different paths of execution.

In general, dynamically typed languages are used for scripting languages, where there is no compilation step, and so compilation errors don't exist, meaning the extra keystrokes needed to give variables type wouldn't be very useful.

There are some distinct advantages to dynamically typed languages as well, mostly in terms of less code being needed to implement the same design: interfaces need not be written, because everything is "duck typed" (we only care what methods/properties an object has, not what class the object belongs to), variables need not be given explicit type...with the trade off that we find out about somewhat fewer bugs before we start running our code.

share|improve this answer
    
Thanks Theodore. "But if the compiler doesn't know the types of the variables, it can't warn you that you've made an invalid call" As you mention, the compiler can know the types of the objects the variables point to. –  sturdytree Feb 11 '12 at 0:10
    
Theodore: In your example james/bob, we should as programmers know how we have used our variables (and good naming helps) and so I don't see a problem with it. When you say "we can't always know the type of a variable" I assume you mean we can't always know the type of the object the variable points to, but the compiler can work this out and so warn about incorrect members being applied (i.e. we can have static checking). –  sturdytree Feb 11 '12 at 0:10
2  
I've given an example above in which you can't know the types of the objects statically...depending on the path of execution, the type of object stored in a variable with no type information can be different. You can have a language like C# where the compile-time type information can be inferred, but, so far as I know, there's no language with both static type-checking and truly typeless variables, the computational complexity of the static analysis is likely too great. –  Theodore Murdock Feb 11 '12 at 0:29
    
Theodore, thanks, you've understood correctly that what I am talking about is a language with static type checking (based on type of object) and typeless variables. Sad to hear there are none - I'm told Python has typeless variables, but sounds like it does not have static type checking. –  sturdytree Feb 11 '12 at 0:37
1  
-1; strong/weak typing is orthogonal to static/dynamic typing. C is statically weakly typed; Lisp and Python are both dynamically strongly typed. –  larsmans Feb 11 '12 at 10:58
show 2 more comments

So professional programmers don't have to figure out whether

10 + "10"

is "1010" or 20....

What it is a an error, at compile time with a statically typed language or run time witha dynamically typed one. Well sane ones anyway.

share|improve this answer
2  
I.e., Perl is not a sane language? :) –  larsmans Feb 10 '12 at 23:20
5  
@larsmans: as a matter of fact, no, it's not. but that's purely opinion. –  Chris Lively Feb 10 '12 at 23:22
2  
@ChrisLively: I'm glad it's a matter of fact now. Please come by my workplace anytime to convince my Perl-loving colleagues ;) –  larsmans Feb 10 '12 at 23:23
2  
10 + "10" is using a '+' operator on object of type integer and object of type string. Compiler would issue an error. My question is to do with type of variable, not the object. –  sturdytree Feb 10 '12 at 23:56
2  
It is valid C: It's pointer arithmetic. –  dan04 Feb 11 '12 at 8:54
show 4 more comments

Assuming you had a variable one (set to 1) and attempted to evaluate one + one. If you had no idea of type, then 1 + 1 will be ambiguous. You can argue that 2 or 11 could be correct answers. It becomes ambiguous if context isn't given.

I've seen this happen in SQLite where the databases types were inadvertently set to VARCHAR instead of INT and when operations were done people were getting unexpected results.

In c# if context infers a type, you can use the var keyword.

var c = new Customer();
var e = new Employer();

Will compile c and e with the inferred types at compile time.

share|improve this answer
1  
In Python, 1 + 1 always has the type int, but there's no need to declare that. The question is about why variables have a type, not values. –  larsmans Feb 10 '12 at 23:19
    
Sorry you were meant to see variables not values when I used 1 + 1 in my example. I guess it wasn't clear. –  Stephen Quan Feb 10 '12 at 23:36
    
Still, dynamically typed languages can deal with this. In Python, one=1; print(one+one) prints 2. one="1"; print(one+one) prints 11. The SQLite example is more convincing, but the problem there is one of weak typing, so it's not really relevant to C#. –  larsmans Feb 10 '12 at 23:42
    
In my suggested scheme, one = 1 mean a variable pointing to an integer type (I am not suggesting no types at all - objects would have a type). one + one would then not be ambigous (we are adding two integer objects/values) –  sturdytree Feb 10 '12 at 23:54
    
+1 I actually wanted to ask whether LISP and SQL should be type-safe and statically compiled. –  Job Feb 11 '12 at 3:10
show 2 more comments

A variable does not need to have an associated type. Languages where this is true include Lisp, Scheme, Erlang, Prolog, Smalltalk, Perl, Python, Ruby, and others.

It's also possible for a variable to have a type, but you might not have to write the type in the program. This is usually called type inference. ML, Haskell, and their descendants have powerful type inference; some other languages have it in lesser forms, such as C++'s auto declarations.

The main argument against type inference is that it damages readability. It's usually easier to understand code when the types are written down.

share|improve this answer
add comment

When you identify the type that your variable represents, you are making a statement about a couple of things. You are identifying the memory allocation requirements for your variable, and you are defining compatibility and range rules for your variable. It provides a way to avoid confusion about your intentions for the data you are storing, and to provide you with a relatively cheap means to identify potential problems in your code at compile time.

If you declare the following variables:

myVar      = 5;
myOtherVar = "C";

What can you infer about these variables? Is myVar signed or unsigned? Is it 8-bit, 64-bit, or something in between? Is myOtherVar a String (effectively an array) or a Char? Is it ANSI or Unicode?

By supplying specific data types, you provide the compiler with clues as to how it can optimize the memory requirements for your application. Some languages don't bother to much with this sort of thing, allowing those matters to be dealt with at runtime, while other languages will allow a certain amount of dynamic typing because by analyzing the code the data types can be inferred.

Another point with strongly typed languages, is that it saves you from needing to provide instructions to the compiler every time you use a variable. Can you imagine how horrible and unreadable your code would become if every time you accessed a variable, you were force to effectively cast it to tell the compiler what type of value it was?!!

share|improve this answer
    
Good point, although the compiler could just use the most efficient type (e.g. small int) based on the value, I can see that we may want "C" to be a string object rather than char so as to be able to perform certain operations. In such cases though, we could just specify a = (string)"C". This creates a string object and 'a' (untyped variable) just points to it. I don't see this as more horrible than string a = "C"; –  sturdytree Feb 11 '12 at 0:28
add comment

A computer program is a graph of process nodes describing what a "machine", represented by the language runtime (extended with toolkits in most cases) should do, in what order or under what conditions. This graph is represented by a text file (or a bunch of text files) written in a specific language, and (partially or fully) created when the compiler/interpreter reads (deserializes) this file. Also, there are some environments (UML or graphical program generating tools) where you can actually build this graph, and generate the source code in a target language.

Why do I say this? Because this leads to the answer to your question.

Your program text is your directions on how the computer should solve the actual task, containing both the process steps (conditions, actions) AND the structure (what components do you use in the solution). The latter means that you get or create some instances of other components, put them into named boxes (variables) and use them: access their data and services.

Some languages gives you uniform boxes, where only the label is important, but you can put just anything into them, you can even use a variable named "target" to store a "Person" at the beginning and "Car" at the end of the same algorithm. Others requires you to create "shaped" boxes, therefore different ones for a Person or a Car - although they still let you create a "generic box" (Java Object, C/C++ void*, Objective C "id"...) and cast it as you like. Typed languages let you express your structure in finer details, creating "type contracts" for your variables (although you can hack around this limitation), while untyped languages support this "I will surely know what I have put into that box this time" approach as the default and only behavior.

Both approaches are viable, have their compiler intelligence, many programming books, practices and frameworks written using them (and other tons of books about those frameworks) on different levels. So today the answer seems to be more a matter of taste and the knowledge of the actual programmer team than a properly founded, measured and verified statement on whether to use or not use types.

I think it is needless to say that I prefer rules to tricks, especially for long term, big team (aka: "serious") projects. Reason: as far a I know, the most likely causes of a SW project failure/slip are: unclear requirements and poor design (80%! by a study I know), and only a few percent remains for actual coding. All rules and contracts enforce cleaner design, thinking forward, and requires the decisions to be made earlier and by the proper people. Types mean rules: less "freedom" and "coolness" - more preparation, thinking, coding standards, controlled teamwork. To me, this sounds like a required factor of success, and also "home, sweet home".

My 2 cents.

share|improve this answer
add comment

AFIAK all languages with dynamic typing are interpreted languages. That's already very inefficient, adding the inefficiency of dynamic typing isn't going to be a big loss of time. A compiled language, though, won't be actually referring to things by name when it's running. (Barring the occasional use of .net reflection or the like--features which are very slow compared to the underlying language.) Searching for all those names is going to be slow, slow, slow.

share|improve this answer
3  
You know wrong. There are many compilers for dynamically-typed languages, and some of them are quite fast. Examples include Common Lisp, Scheme, and Erlang. –  Ryan Culpepper Feb 11 '12 at 3:59
2  
There is no such thing as an "interpreted language". A language is an abstract set of mathematical rules. A language is neither compiled nor interpreted. A language just is. Compilation and interpretation are traits of the implementation, not the language. Every language can be implemented with an interpreter, and every language can be implemented with a compiler. And pretty much every language has both interpreted and compiled implementations, e.g. there are interpreters for C and compilers for ECMAScript, Ruby and Python. –  Jörg W Mittag Feb 12 '12 at 6:01
add comment

Dynamically typed languages are often touted as "object-oriented". They are not. They may be encapsulation-oriented, but never object-oriented. Object orientation is all about types.

"The boy rides his brother's bike to the grocery store and buys a loaf of bread from the grocer". Using object orientation, one can immediately write a set of classes (types) to describe this real-world scenario.

In a dynamically-typed language, the scenario could only be represented thusly:

"The object rides his object's object to the object and buys an object from the object".

The power of object orientation is in its ability to model the world in natural terms, so that the software developer can use both sides of the brain to write software, and solve problems more as a human being, less as a computer programmer. This power is absent in dynamically typed languages.

Static typing permits better coding efficiency, re-usability and maintainability, because integrated development environments know the types of variables. Knowing the types of variables, an IDE can provide auto completion so that the programmer doesn't have to refer back to the class definition in order to remember whether the member property was spelled "backlightControl" or "backLightControl" or "bkLightCtrl".

Static typing permits automated refactoring, because the IDE knows every place where a variable holds an instance of the object being refactored.

Static typing permits greater re-usability and maintainability. Dynamic typing is better for disposable code. Suppose a new developer comes in off the street, and looks at an existing piece of code. If the code is statically typed, the developer can, in two mouse clicks, examine the class definition of each of the variables involved, knows what the class is for, knows what other methods and properties are available. If the code is dynamically typed, the developer has to use global searching to figure out what is going on.

share|improve this answer
2  
I'm afraid I have to disagree with you on the first part of your argument. Dynamically-typed languages are usually "object oriented", but not "class oriented". This is an important distinction. In you example, you are actually living in an illusion. You may have a Boy class, but I doubt it can do everything a real world "boy" does. However, in you dynamic example ( The object rides... ), we know the only important thing about this "boy" object - it can ride. That is the basic philosophy of dynamic-type languages. It has +ve s and -ve s. Which one you like is your opinion. –  Chip Aug 12 '12 at 8:23
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.