Imagine two different call sites want to do two different things with the message. One wants to log() it, another wants to print() it. In my example this has been implemented by passing a flag to greet() to tell it what to do.
If greet() gave up responsibility for outputting the message and instead just constructed it, then your code would look like this:
def site1():
print(greet(“x”))
def site2():
log(greet(“y”))
And greet would be half as long.
Adding default parameters works well with existing code. It is not bad and lazy because it is easy.