निरंजन
Consider the following example:
```#
\documentclass[border=1cm]{standalone}
\usepackage{array,booktabs}
\begin{document}
\ExplSyntaxOn
\begin { tabular } { l l }
\toprule
\clist_map_inline:nn {
\TeX,
\LaTeX,
PDF \LaTeX
} {
#1 & \texttt { \tl_to_str:n { #1 } } \\
\midrule
} \\ % Why is this required?
\bottomrule
\multicolumn { 2 } { r } { \emph { End~ of~ table. } } \\
\end { tabular }
\ExplSyntaxOff
\end{document}
```

As described in the comments, I am not able to understand why the `\\` on line 15 is required. The following is the expected result once `\clist_map_inline:nn` is executed:
```
\documentclass[border=1cm]{standalone}
\usepackage{array,booktabs}
\begin{document}
\ExplSyntaxOn
\begin { tabular } { l l }
\toprule
\TeX & \texttt { \tl_to_str:n { \TeX } } \\
\midrule
\LaTeX & \texttt { \tl_to_str:n { \LaTeX } } \\
\midrule
PDF \LaTeX & \texttt { \tl_to_str:n { PDF \LaTeX } } \\
\midrule
\bottomrule
\multicolumn { 2 } { r } { \emph { End~ of~ table. } } \\
\end { tabular }
\ExplSyntaxOff
\end{document}
```
Note that this code _does not_ have the `\\` that we see on line 15 in the first code. Agreed that this adds a `\midrule` over the `\bottomrule` which is not desired, but that's a separate issue and can be dealt with later. As of now, I am curious about the extra `\\` that the code requires.
Top Answer
Skillmon
The reason it's necessary is that `\noalign` (the primitive used by `\bottomrule`) must be the first unexpandable token inside an alignment row. As such, the minimal example that breaks for the same reason as yours is the following:
```
\begin{tabular}{c}
\relax\bottomrule
\end{tabular}
```
-----
# Why does `\clist_map_inline:nn` have this issue?
You need to understand how `\clist_map_inline:nn` is implemented to understand what the unexpandable contents left by it are. In short it looks something like this:
```
<setup-code defining an internal auxiliary function>
<loop>
<setup-code restoring the earlier definition of the auxiliary function>
```
(in reality that might be differently implemented with a level counter and something along the lines, but that's the gist of it, the setup has to be reverted, regardless of how that setup is done)
So, since the `inline`-mappers need to maintain and restore a state (such that you can nest loops inside each other) they need to execute some unexpandable code at the start and end of the loop. That unexpandable code breaks your `\bottomrule`, since now it's no longer the first thing in its row.
-------
# What to do?
If your table allows it the easiest fix is to put the `\\` at the start of your inline function, then you're free to put your `\\` after the end of the `inline`-mapper and have no problem with `\bottomrule`. That's not the case here.
Another possibility is to build the table body inside a variable and then expand that variable.
```
\documentclass[border=1cm]{standalone}
\usepackage{array,booktabs}
\begin{document}
\ExplSyntaxOn
\begin { tabular } { l l }
\toprule
\tl_clear:N \l_tmpa_tl
\clist_map_inline:nn {
\TeX,
\LaTeX,
PDF \LaTeX
} {
\tl_put_right:Nn \l_tmpa_tl
{
#1 & \texttt { \tl_to_str:n { #1 } } \\
\midrule
}
}% \\ % Why is this required?
\l_tmpa_tl
\bottomrule
\multicolumn { 2 } { r } { \emph { End~ of~ table. } } \\
\end { tabular }
\ExplSyntaxOff
\end{document}
```
We have to switch the `\midrule` around since otherwise you'll end up with `\midrule\bottomrule` which doesn't look nice (from now on I drop the preamble and only put the `tabular` environment into the listings):
```
\begin { tabular } { l l }
\toprule
\tl_clear:N \l_tmpa_tl
\clist_map_inline:nn {
\TeX,
\LaTeX,
PDF \LaTeX
} {
\tl_put_right:Nn \l_tmpa_tl
{
\midrule
#1 & \texttt { \tl_to_str:n { #1 } } \\
}
}% \\ % Why is this required?
\tl_tail:N \l_tmpa_tl
\bottomrule
\multicolumn { 2 } { r } { \emph { End~ of~ table. } } \\
\end { tabular }
```
In modern LaTeX with modern PCs, building the table body isn't that bad, performance and memory capacity is good enough, but for *big* table's you'll hit a wall sooner or later (if you don't use LuaTeX which can dynamically allocate more memory, but then the code will be slow nevertheless). You can get better performance using `\tl_build_...` functions, but you'll get even better performance and less memory usage if you turn to a fully expandable loop:
```
\cs_new:Npn \my_tbl_builder:n #1
{
% \exp_stop_f: doesn't hurt in front of a `\noalign`
\exp_stop_f: \midrule
#1 & \texttt { \tl_to_str:n {#1} } \\
}
\begin { tabular } { l l }
\toprule
% we could use `\exp_not:n` in the definition of `\my_tbl_builder:n` and use
% `\tl_tail:e` here, but that would use slightly more memory, and this was
% about saving memory
\exp_after:wN \use_none:n \exp:w \exp_end_continue_f:w
\clist_map_function:nN {
\TeX,
\LaTeX,
PDF \LaTeX
}
\my_tbl_builder:n
\bottomrule
\multicolumn { 2 } { r } { \emph { End~ of~ table. } } \\
\end { tabular }
```