If you do
m:= l**{-1};
you create an expression 'm' (a Python object) which contains the mathematical expression $l^{-1}$. The thing on the left of the :=
is a Python name, while the thing on the right is a Cadabra expression.
Now if you write
ex:= m l;
you create another expression, called 'ex', which contains the mathematical expression $m l$.
If you want to tell Cadabra that it should use the content of the m
object to build this expression, you need to do
ex:= @(m) l;
collect_factors(_);
(the 2nd line is there to reduce $l^{-1} l$ to $1$).
A cleaner (more Cadabra-esque) way of writing this is
mrule:= m = l^{-1};
ex:= m l;
substitute(ex, mrule);
collect_factors(ex);
Here I defined an object which contains the rule which tells Cadabra how to replace $m$. The reason why this is cleaner is that it generalises better to replacement rules with indices. You cannot write
A_{\mu} := B_{\mu}; # not possible
(to replace $A{\mu}$ with $B{\mu}$), because Python objects need to have names consisting of alphanumeric characters only (and $A_{\mu}$ contains other stuff as well). But you can write
Arule:= A_{\mu} = B_{\mu};
and then
ex:= A_{\mu} C^{\mu};
substitute(ex, Arule);
to get $B_{\mu} C^{\mu}$.