How are domain and co-domain of a function useful? I'm at university and I learned linear algebra, set theory, logic, and other kind of mathematics that use functions a lot. 
Now, I know that function is very important and useful in mathematics but I never asked why we need to define the domain and co-domain of a function? How is it useful?
Thank you in advance.
 A: The domain and the codomain are intrinsic parts of a function. Consider the following examples: 
$$
f:\mathbb R\to\mathbb R,\ \ \ g:\mathbb R\to[0,\infty),\ \ \ h:[0,\infty)\to[0,\infty),\ \ \ j:[0,\infty)\to\mathbb R,\ \ \ k:\mathbb Z\to\mathbb N,
$$
where 
$$
f(x)=x^2,\ \ \ \ g(x)=x^2,\ \ \  h(x)=x^2,\ \ \ \ j(x)=x^2\ \ \ k(x)=x^2.
$$
We have that $h$ is bijective and thus invertible, $g$ is surjective but not bijective, $j$ is injective but not surjective, $k$ and $f$ are neither injective nor surjective. 
They have different properties because they are different functions. 
A: A function is a rule. You consider some input values, consider the rule, and then find an output value. But this isn't a very rigorous definition.  We require a further degree of precision necessary for good mathematics:
Consider your favorite function, $$f(x)=x^2$$ A casual observer may consider this to be a parabola defined on the real line, but is that really so? We haven't specified! To define a function, you better specify what values you can input, or your domain. Furthermore, it's awful nice to know what values could possibly be outputted. That's your codomain.
Each of the following choices provide us with a very different function, all based off the algorithm that is "take an input and square it."
$$f:\mathbb{R}\rightarrow\mathbb{R}$$
$$f: [0,1]\rightarrow\mathbb{R}$$
$$f: [0,1]\rightarrow[0,1]$$
The first is what one may expect, but note the variations in the latter two. The second and third examples differ here due to their specificity. They may provide a similar mapping, but they behave differently as functions. Notably, the third is surjective. We have different rules, no? 
As a last note, compare how wildly different the function would be if we specified it as
$$f: \mathbb{C}\rightarrow\mathbb{C}$$
A: In a lot of cases, the domain and codomain change the function itself.
The domain is clearly important, since a change of the domain changes what you're allowed to "plug into" the function.
For example, if I have a function $f(x) = 2x$, it's not a function yet since I need to define the domain first. For example, if the domain is:


*

*$\{0\}$ then the function is the trivial function that takes $0 \to 0$.

*$\{0, 1\}$, then the function is one that maps $0 \to 1$, $1 \to 2$

*$\mathbb{N}$, Then the function maps all natural numbers by doubling them

*$\mathbb{Z}/3\mathbb{Z}$, that is, the set of integers modulo $3$. In this case, it takes the numbers $\{0, 3, 6, \ldots \} \to 0$, $ \{1, 4, 7, 10, \ldots \} \to 2$, $\{2, 5, 8, \ldots\} \to 1$.


The codomain is trickier to motivate, but it lets us differentiate between "where the function is allowed to hit" and "where the function does hit"
The image is the set of all points $\{y \ | \ y = f(x) \ \forall x \in domain \}$, which is the set of all points the function hits when coming from the domain.
However, the codomain is what is supplied by the creator of the function. Hence, the codomain need not equal the image (it must be at least the image, but it can be larger)
For example, if the function is  $f(x) = 2x$, $f: \mathbb{N} \to \mathbb{N}$, then this function has a larger codomain than range. This is because a value such as $3 \in \mathbb{N}$, there is no $x \in \mathbb{N}$ such that $f(x) = 3$
However, if I had said $f(x) = 2x$, $f : \mathbb{N} \to {0, 2, 4, \ldots}$, then the function would have image = codomain.
Functions that access their entire codomain are called as "onto" or "surjective" (from french, $sur$ meaning "on") since they in some sense map "on" the entire codomain rather than just in the image.
A: Functions themselves are mathematical objects, and we need to reason with them. Not just specific functions, but also general functions of various types.
For example, consider the basic principle of recursive definition:

If you have
  
  
*
  
*An element $x$ of some set $X$
  
*A function $f$ from $X$ to $X$
  
  
  then there is a unique function $g$ from $\mathbb{N}$ to $X$ satisfying
  
  
*
  
*$g(0) = x$
  
*$g(n+1) = f(g(n))$
  

Pay attention to the type of the variable $f$: to be able to use it, we needed to know its domain and its codomain.
This is typical: to do pretty nearly any reasoning about variables of function type, you need to know their domain and codomain.
The only question, then, is whether a function should have a specific type, or if it should be allowed to be of many types simultaneously.
i.e. suppose I define a function $f:\mathbb{Z} \to \mathbb{Z}$ by the equation
$$ f(n) = n^2 $$
On one approach to the notion of function, this simultaneously defines a function from the integers to the integers, from the integers to the nonnegative integers, from integers to the nonprime integers, from the integers to the reals, from the integers to the complexes, or other sorts of things one might imagine.
The other approach to the notion of function is that those would all be different functions. However, it's easy to pass back and forth between them as necessary. (and we often do so without explicit mention, since it's easy for the reader to fill in said detail)
I personally subscribe to the latter approach — functions have a specific codomain. This is in no small part due to my experiences with typed programming languages and with category theory.
