\setlength
is defined as:
\def\setlength#1#2{#1 #2\relax}
so it uses TeX's plain assignment \register1=\register2
, omitting the optional =
sign.
Your code then does, after the expansion of \setlength
:
\newLen \columnwidth-\tabcolsep-\doublerulesep-\arrayrulewidth
which, newlines added for clarity, is the same as:
\newLen=\columnwidth
-
\tabcolsep=-\doublerulesep
-
\arrayrulewidth=\relax % error
and the final \arrayrulewidth
errors because it's misused there, and if you look at the PDF you'll see two -
typeset. The other versions don't actually work: they just don't throw errors, but still typeset spurious -
. They don't error because the number of registers is even, so none is misused.
The right way would be to tell TeX that is a dimension expression with \dimexpr
:
\setlength\newLen{\dimexpr\columnwidth-\tabcolsep-\doublerulesep-\arrayrulewidth}
or \usepackage{calc}
, as campa said in the comment, which redefines \setlength
to understand expressions and some other goodies not available with \dimexpr
only (check out the documentation).
By the way, expl3
's equivalent \dim_set:Nn
already does \dimexpr
on the argument (though it doesn't add the calc
syntax):
\ExplSyntaxOn
\dim_set:Nn \newLen {\columnwidth-\tabcolsep-\doublerulesep-\arrayrulewidth}
\ExplSyntaxOff
\usepackage{calc}
.\setlength