<story><title>Google Python Style Guide</title><url>https://google.github.io/styleguide/pyguide.html</url></story><parent_chain><item><author>gorgoiler</author><text>It is a shame that &lt;i&gt;default arguments&lt;/i&gt; isn’t a bit longer.  Perhaps it’s out of scope to talk about anti-patterns but in my experience default arguments cause a lot of distress to a good code base.&lt;p&gt;Defaults are useful when you are providing a library function for other teams to use.  If you’re inside a more private code base and doing work on the implementation of your team’s service then it is wise to avoid default arguments.&lt;p&gt;The problem is they provide a point after which it seems acceptable to add a flood of more default arguments.  This is particularly the case for junior developers who lack confidence to refactor instead of patch.  Default arguments go hand in hand with conditional logic and cause functions to bloat into do-everything multi-page monsters without any focus and no tractable flow of logic.&lt;p&gt;Forgive the contrived example, but what was once this:&lt;p&gt;&lt;pre&gt;&lt;code&gt;  def greet(name):
    print(f”Hello {name}”)
&lt;/code&gt;&lt;/pre&gt;
ends up becoming this, all because no one would bite the bullet and pick this apart into individual functions:&lt;p&gt;&lt;pre&gt;&lt;code&gt;  def greet(
    name,
    language=None,
    io=None,
    is_ci=False,
    and_return=False,
  ):
    greeting = “Hello”
    if language:
      greeting = translate(greeting)
    message = f”{greeting} {name}”
    fn = print
    flush = False
    if is_ci:
      fn = log
      flush = True
    fn(
      greeting,
      flush=flush,
      io=io if io else stdout,
    )
  if and_return:
    return greeting

&lt;/code&gt;&lt;/pre&gt;
The slow rot of more and more defaults makes the function longer and longer.  Moreover, each time someone adds a new option it gets harder to justify why they shouldn’t do it when the previous person &lt;i&gt;was&lt;/i&gt; allowed.</text></item></parent_chain><comment><author>aerhardt</author><text>I think the example is indeed contrived - you said it yourself!&lt;p&gt;To me it doesn&amp;#x27;t illustrate the problem with default parameters specifically.&lt;p&gt;For example it shows that the programmer doesn&amp;#x27;t know dependency injection and first-class functions. Printing could be passed in as a function param, but then it might actually be sensible to provide a default callable (eg, print), depending on how the greet function is going to be called.&lt;p&gt;Language seems to be a perfectly sensible thing to have a default on.&lt;p&gt;Then, and_return... That is, like, &lt;i&gt;super&lt;/i&gt; contrived, man... I mean if a programmer doesn&amp;#x27;t know that a function caller can simply call for side effects and ignore the return value, they likely have much bigger problems than their judgement to use defaults or not.&lt;p&gt;I empathize with your plight though - you&amp;#x27;re probably a great programmer, and I think it&amp;#x27;s very difficult for someone who is good at their craft to come up with genuinely but subtly shitty examples.</text></comment>
<story><title>Google Python Style Guide</title><url>https://google.github.io/styleguide/pyguide.html</url></story><parent_chain><item><author>gorgoiler</author><text>It is a shame that &lt;i&gt;default arguments&lt;/i&gt; isn’t a bit longer.  Perhaps it’s out of scope to talk about anti-patterns but in my experience default arguments cause a lot of distress to a good code base.&lt;p&gt;Defaults are useful when you are providing a library function for other teams to use.  If you’re inside a more private code base and doing work on the implementation of your team’s service then it is wise to avoid default arguments.&lt;p&gt;The problem is they provide a point after which it seems acceptable to add a flood of more default arguments.  This is particularly the case for junior developers who lack confidence to refactor instead of patch.  Default arguments go hand in hand with conditional logic and cause functions to bloat into do-everything multi-page monsters without any focus and no tractable flow of logic.&lt;p&gt;Forgive the contrived example, but what was once this:&lt;p&gt;&lt;pre&gt;&lt;code&gt;  def greet(name):
    print(f”Hello {name}”)
&lt;/code&gt;&lt;/pre&gt;
ends up becoming this, all because no one would bite the bullet and pick this apart into individual functions:&lt;p&gt;&lt;pre&gt;&lt;code&gt;  def greet(
    name,
    language=None,
    io=None,
    is_ci=False,
    and_return=False,
  ):
    greeting = “Hello”
    if language:
      greeting = translate(greeting)
    message = f”{greeting} {name}”
    fn = print
    flush = False
    if is_ci:
      fn = log
      flush = True
    fn(
      greeting,
      flush=flush,
      io=io if io else stdout,
    )
  if and_return:
    return greeting

&lt;/code&gt;&lt;/pre&gt;
The slow rot of more and more defaults makes the function longer and longer.  Moreover, each time someone adds a new option it gets harder to justify why they shouldn’t do it when the previous person &lt;i&gt;was&lt;/i&gt; allowed.</text></item></parent_chain><comment><author>rightbyte</author><text>You don&amp;#x27;t suggest any solution. Do you want more function overloading or maybe config objects?&lt;p&gt;Adding default parameters works well with existing code. It is not bad and lazy because it is easy.</text></comment>