Many (if not all?) CAS have some internal tree representation of mathematical structures, Mathematica is not the only one. I worked on such a system myself. To define data types for your expressions and then evaluate them via different algorithms is quite natural. So yes, we also used something like Integral(f, from: a, to: b) and then had like a gazillion techniques to actually evaluate that.
Proof assistants do something similar btw, they also encode mathematical expressions as (often recursive) data types and then prove things about those definitions.
edit: to be fair though, the LISP implementation proposed to use the Risch algorithm, which actually does give you symbolic antiderivatives. So that wouldn't be a valid critique of the implementation. There more salient points are a) that the Risch algorithm only works for a certain class of functions (those that have an elementary antiderivative) and b) that by not separating the definition of an integral from its evaluation, you're not able to manipulate it directly as an expression or to evaluate it via different methods (e.g. symbolic vs. numerical methods).
Just think about inputting $complicatedIntegral - $complicatedIntegral. This is clearly zero, but if your integral is "just a function", you're not able to see that and will spend an unreasonable amount of time computing it (twice, even), or worse, will fail to produce a result.