Remember from a while ago that I've explained \mathchoice and discussed a macro for flexible function notation. If you don't, I refer you to How to let a command automatically adapt to the current mathematical style? Today I'm going to extend its functionality. When using the macro in real life I felt the need to display injective and surjective maps. And I needed both a function and a map macro. The first only mentions the name, domain and codomain while the latter displays how elements are mapped. I'll solve both issues (not that the second is an issue though).

What I wanted is an optional parameter, indicating whether a map is injective or surjective. The easiest but maybe semantically speaking not the cleanest one is just specifying the kind of arrow through the optional parameter. I've opted for this approach, TeX isn't a semantic mark-up language, but in my solution the non-semantic approach happens nicely. First a word on how TeX handles optional parameter. It handles them in an awful way. It basically boils down to saying "hey, there is an extra parameter" and specifying a default value for it. Now either the optional parameter or the default is assigned to the first variable. That's all there is.

The optional parameter will be either twohead or hook, indicating surjective respectively injective. The macro

\newcommand*\map@arrow[1][]{\csname#1rightarrow\endcsname{}}
now expands to the correct \rightarrow: either \twoheadrightarrow or \hookrightarrow. We've defined a command that takes one parameter, the default value is empty and it expands to the control sequence corresponding to the desired command. Notice how you only have to specify the optional prefix to rightarrow, \csname \endcsname is macro expansion at its best.

So we've arrived at

\makeatletter
\newcommand*\map@arrow[1][]{\csname#1rightarrow\endcsname{}}

\newcommand*\function@textstyle[4][]{#2\colon#3\map@arrow[#1]#4}
\newcommand*\function[4][]{%
  \mathchoice
  {\function@textstyle[long#1]{#2}{#3}{#4}}
  {\function@textstyle[#1]{#2}{#3}{#4}}
  {\function@textstyle[#1]{#2}{#3}{#4}}
  {\function@textstyle[#1]{#2}{#3}{#4}}
}
\newcommand*\map@textstyle[6][]{#2\colon#3\rightarrow#4:#5\mapsto#6}
\newcommand*\map[6][]{%
  \mathchoice
    {#2\colon\
      \begin{array}{ccc}
        #3&~\map@arrow[long#1]~&#4 \\
        #5&~\longmapsto~&#6
      \end{array}
    }
  {\map@textstyle[#1]{#2}{#3}{#4}{#5}{#6}}
  {\map@textstyle[#1]{#2}{#3}{#4}{#5}{#6}}
  {\map@textstyle[#1]{#2}{#3}{#4}{#5}{#6}}
}
\makeatother

Notice that in display style, the long versions of arrows are used. But there is no \longtwoheadrightarrow nor \longhookrightarrow! Let's make them then:

\newcommand*\longhookrightarrow{\ensuremath{\lhook\joinrel\relbar\joinrel\rightarrow}}
\newcommand*\longtwoheadrightarrow{\ensuremath{\relbar\joinrel\twoheadrightarrow}}

The command \ensuremath typesets its parameter in mathematical mode, \lhook is (obviously) the left hook, \joinreleliminates horizontal spacing between symbols, putting them directly next to eachother and \relbar is a horizontal line used to create new mathematical symbols.

Also note that I've used \newcommand*, the starred version of \newcommand. This macro assumes you won't be feeding it multiple paragraphs, as is the case here. Now when you do feed the troll macro multiple paragraphs, probably due some syntax error, it will complain at a more obvious place: namely exactly where it notices it has to consume too much and not at the end of the file.