and a "visitor" would calculate the tax for each liquid for me. and i see the benefit that i do not have to modify the collection of objects themselves when i want to add a new calculation. But my trouble comes when i want to add a new method. Following open closed principle i should not be adding new methods to the milk class for example. But let us imagine i want to add functionality to know what color the liquid is. So i'd like to extend the milk object to have a method called "getColor()" which would return "#FFFFFF". This seems like i would need a decorator pattern to add this functionality if i want to follow SOLID open closed principle. Is there a way to do this with visitor pattern ?

Add the function, you aren't violating O/C

You won't violate O/C by adding a new function, as long as that function does not affect any existing code. You'll be perfectly fine adding a getColor() to your liquids.

O/C is about preventing modification of existing code

The purpose of O/C is to avoid contract violations. When a developer writes software, they'll specify exactly how the software should and should not work. This is the contract.

When writing code that other developers depend on, you cannot be sure what contracts those developers have set in place. All you know about is the contract you defined for your code. Developers trust that you will not modify your contract in a way that modifies theirs.

Since you cannot be sure whether changing your contract will affect other developers' contracts, any code of yours that other developers use must be "CLOSED for modification", or you risk contract violations.

O/C doesn't prevent you from scaling up

Adding code that has no effect on existing code doesn't carry risk of interfering with other developers' contracts.

Let's say a company was using your liquid classes before getColor existed. If you released a new version that contained getColor, the company would have to update their software to use that new function. Until they've updated their software to use that function, it has no affect on their software. This is the idea behind "OPEN for extension".