Applying new Heads
Mathematica has a built-in function for applying a specific head in an expression. Both of these are (almost) equivalent:
Apply[List, expr]
List@@expr
Baby Steps and Single Use Cases
Apply replaces a head(s) in an expression with the specified head. The default levelspec is {0}, meaning it only applies to the top level (the Head of expr itself) when you don't specify anything else.

When using the curried form (List@@expr), expr is evaluated before applying your specified head. Parentheses help protect you from this.
(Note that this first one is evaluated as (List@@a)+b+c and a has no head to replace.)

Alternatively, to be certain what you're applying your new head to, you could Defer evaluation, but then you need use the curried form of MapApply (@@@) to Apply List to the expression inside Defer, not to Defer itself.

Writing A Function To Do This
To do this right, we need something stronger than Defer. We'll need Hold and ReleaseHold.
Extracting Only Addition Terms
It's easy to use Apply to replace the top level head with List. It's still relatively easy to selectively replace Plus with List when it's the level 0 head. Handling the monomials (when the head is not Plus) is a larger challenge.
- If the head is
Plus, you want it replaced with List
- If the head is not
Plus, you want to wrap List around the expression
Without building If into the function, it's tricky to satisfy both conditions at the same time. Most attempts to satisfy one condition gave one too many or one too few instances of List in the other case.
It took quite a bit of debugging, but the solution is to wrap everything in List, then if Plus is the unevaluated head, replace it with Sequence. This always applies List, and if we have Plus, we get rid of it and just pass its sequence of parameters into the outer list, without creating a second list. Because we need wrap Hold around everything, we now need Extract to get at the buried Plus.
Summary
- Use
HoldAll to ensure everything comes into the function without modification
- Wrap everything in
Hold to prevent modification while working with the expression
- Reach past
Hold and Extract the original head
- If that head is
Plus, replace it with Sequence
- Take this head and
Apply it back inside the held expression
ReleaseHold
- Put everything inside
List
Sequence will absorb into List and disappear, any other head will remain
You need both these lines to make it work.
SetAttributes[terms, HoldAll]
terms[expr_] := {ReleaseHold[Apply[Replace[Extract[Hold[expr], {1, 0}], Plus -> Sequence], Hold[expr], {1}]]}
Examples
The FullForm column shows that there aren't any spare Hold, Defer, or Unevaluated floating around.

Note
In the examples, I only used Hold to prevent 2+3 from being evaluated to 5, and to prevent the two matrices being added together in the leftmost expr column. You don't need to wrap your expression with Hold before passing it into terms. terms is defined to already wrap everything in Hold before doing anything else. This also serves to show that if you are using Hold to prevent evaluation of expr before passing it into terms, then ReleaseHold will clear all instances of Hold, whether placed there by you or terms itself.
terms[a*b*c]but terms here areaandbandc. Unless you are using your own definition of what atermis. So you can useList @@ exprto obtain the terms.expr = a^2 + a^-2 + c; List @@ exprgives{1/a^2, a^2, c}andexpr = a*b*c; List @@ exprgives{a, b, c}etc.. $\endgroup$expr = a; List @@ exprreturns justarather than{a}. $\endgroup$