From 02e84cb34302bca589c97efe0051f4b9021577ae Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauldmccarthy@gmail.com>
Date: Thu, 1 Feb 2018 17:00:56 +0000
Subject: [PATCH] Little more work on args prac

---
 .../function_inputs_and_outputs.ipynb         | 64 +++++++++++++++++--
 .../function_inputs_and_outputs.md            | 36 ++++++++++-
 2 files changed, 94 insertions(+), 6 deletions(-)

diff --git a/advanced_topics/function_inputs_and_outputs.ipynb b/advanced_topics/function_inputs_and_outputs.ipynb
index 335cb06..2306f9e 100644
--- a/advanced_topics/function_inputs_and_outputs.ipynb
+++ b/advanced_topics/function_inputs_and_outputs.ipynb
@@ -180,10 +180,66 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "> Pitfall: mutable argument values\n",
-    "\n",
-    "\n",
-    "You can see here that"
+    "__WARNING:__ _Never_ define a function with a mutable default value, such as a\n",
+    "`list`, `dict` or other non-primitive type. Let's see what happens when we do:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def badfunc(a=[]):\n",
+    "    a.append('end of sequence')\n",
+    "    output = ', '.join([str(elem) for elem in a])\n",
+    "    print(output)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "With this function, all is well and good if we pass in our own value for `a`:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "badfunc([1, 2, 3, 4])\n",
+    "badfunc([2, 4, 6])"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "But what happens when we let `badfunc` use the default value for `a`?"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "badfunc()\n",
+    "badfunc()\n",
+    "badfunc()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "This happens because default argument values are created when the function is\n",
+    "defined, and will persist for the duration of your program. So in this\n",
+    "example, the default value for `a`, a Python `list`, gets created when\n",
+    "`badfunc` is defined, and hangs around for the lifetime of the `badfunc`\n",
+    "function!"
    ]
   }
  ],
diff --git a/advanced_topics/function_inputs_and_outputs.md b/advanced_topics/function_inputs_and_outputs.md
index 0a5ee93..5777da1 100644
--- a/advanced_topics/function_inputs_and_outputs.md
+++ b/advanced_topics/function_inputs_and_outputs.md
@@ -106,7 +106,39 @@ myfunc(c=300)
 ```
 
 
-> Pitfall: mutable argument values
+__WARNING:__ _Never_ define a function with a mutable default value, such as a
+`list`, `dict` or other non-primitive type. Let's see what happens when we do:
 
 
-You can see here that
+```
+def badfunc(a=[]):
+    a.append('end of sequence')
+    output = ', '.join([str(elem) for elem in a])
+    print(output)
+```
+
+
+With this function, all is well and good if we pass in our own value for `a`:
+
+
+```
+badfunc([1, 2, 3, 4])
+badfunc([2, 4, 6])
+```
+
+
+But what happens when we let `badfunc` use the default value for `a`?
+
+
+```
+badfunc()
+badfunc()
+badfunc()
+```
+
+
+This happens because default argument values are created when the function is
+defined, and will persist for the duration of your program. So in this
+example, the default value for `a`, a Python `list`, gets created when
+`badfunc` is defined, and hangs around for the lifetime of the `badfunc`
+function!
\ No newline at end of file
-- 
GitLab