Question:

Why do we need parameterized contracts? Can't we just use datum?

Oliver: 09 May 2022

While writing validation as:

mkValidator :: SomeContractParam -> SomeDatum -> () -> ScriptContext -> Bool 

Could't we pass the same thing to Datum instead of using Contract Parameter?

Answer:
Noah: 09 May 2022

Yes. It's important to have both options though.

Remember that the script address is derived from a hash of the compiled script code. So, if you parameterize parts of the script, the script address will be different with each parameter.

An example Lars gives in the PPP is an NFT (https://github.com/input-output-hk/plutus-pioneer-program/blob/main/code/week05/src/Week05/NFT.hs#L35). If you parameterize the forging policy to take a specific UTxO, and that script consumes that UTxO, you guarantee that there is only one instance of that policy. Only the person who owned that UTxO could possibly create that token, thus guaranteeing the creation only happens once.

If you had the same UTxO field in the datum, any instantiator of the script could specify some UTxO they own and the script address would be the same. Since the Currency Symbol is in fact the Script Address, any caller could create duplicates of the token and those tokens would be fungible.