We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Docstring of `functions.forget` is incorrect as `+` doesn't retain inputs anymore
The docstring says that `(x + y) + x` retains the immediate variable holding `x + y`. 

```
       Let ``f`` be a function defined as:
       >>> def f(a, b):
       ...   return a + b + a
       and, ``x`` and ``y`` be :class:`~chainer.Variable`\\ s:
       >>> x = chainer.Variable(np.random.uniform(-1, 1, 5).astype(np.float32))
       >>> y = chainer.Variable(np.random.uniform(-1, 1, 5).astype(np.float32))
       When ``z`` is calculated as ``z = f(x, y)``, its intermediate result
       ``x + y`` is stored in memory. Instead, if you call ``f`` with
       ``F.forget``:
       >>> z = F.forget(f, x, y)
       intermediate ``x + y`` is forgotten.
```

But this isn't true for new-style function of `+`, because addition don't requires book-kept inputs for backpropagation.

I checked the behavior by the following script, which traverses retained variables.

```python
import chainer
import chainer.functions as F
import numpy as np 


def f(a, b):
    return (a + b) + a


def recur_check_vars(v, x, y):
    creator = v.creator_node
    if creator is None:
        return
    for pnode in creator.inputs:
        p = pnode.get_variable()
        assert p.data is None or p is x or p is y
        print(p)
        recur_check_vars(p, x, y) 


def main():
    x = chainer.Variable(np.random.uniform(-1, 1, 5).astype(np.float32))
    y = chainer.Variable(np.random.uniform(-1, 1, 5).astype(np.float32))
    print(x)
    print(y)
    print()
    z = f(x, y) 
    recur_check_vars(z, x, y) 


if __name__ == '__main__':
    main()
```

The script doesn't fail, and the output is as follows. We can see that`x + y` is discarded. Living variables `x` and `y` are retrieved, as each `VariableNode` instance has a weakref to the corresponding variable.

```
variable([-0.7699733  -0.50523347 -0.20869003 -0.7912116   0.92058474])
variable([ 0.58832335 -0.06183117  0.1939743   0.9021316  -0.19973369])

variable(None)
variable([-0.7699733  -0.50523347 -0.20869003 -0.7912116   0.92058474])
variable([ 0.58832335 -0.06183117  0.1939743   0.9021316  -0.19973369])
variable([-0.7699733  -0.50523347 -0.20869003 -0.7912116   0.92058474])
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `chainer/functions/util/forget.py`
Content:
```
1 import chainer
2 from chainer import function
3 from chainer import function_node
4 from chainer import variable
5 
6 
7 def _call_func(func, xs):
8     outs = func(*xs)
9 
10     if isinstance(outs, tuple):
11         for i, out in enumerate(outs):
12             if isinstance(out, variable.Variable):
13                 continue
14             n = i + 1
15             suffix = {1: 'st', 2: 'nd', 3: 'rd'}.get(
16                 n if n < 20 else n % 10, 'th')
17             msg = ('{}{} element of a returned tuple is not Variable, '
18                    'but is {}').format(n, suffix, type(out))
19             raise RuntimeError(msg)
20     elif isinstance(outs, variable.Variable):
21         outs = (outs,)
22     else:
23         msg = ('A tuple of Variables or a Variable are expected, but {} '
24                'is returned.'.format(type(outs)))
25         raise RuntimeError(msg)
26 
27     return outs
28 
29 
30 class Forget(function_node.FunctionNode):
31 
32     def __init__(self, func):
33         if not callable(func):
34             raise TypeError('func must be callable')
35         self.func = func
36 
37     def forward(self, inputs):
38         self.retain_inputs(tuple(range(len(inputs))))
39         with function.no_backprop_mode():
40             xs = [variable.Variable(x) for x in inputs]
41             outs = _call_func(self.func, xs)
42         return tuple(out.data for out in outs)
43 
44     def backward(self, indexes, grad_outputs):
45         # Double backprop is not allowed
46         if chainer.config.enable_backprop:
47             raise RuntimeError('double backpropagation in functions.forget is '
48                                'not allowed.')
49 
50         inputs = self.get_retained_inputs()
51         # Create new variables that have no creators
52         dummy_inputs = tuple([variable.Variable(inp.array) for inp in inputs])
53 
54         with function.force_backprop_mode():
55             outs = _call_func(self.func, dummy_inputs)
56             assert len(outs) == len(grad_outputs)
57             if len(outs) > 1:
58                 # Avoid doing backward multiple times when `outs` is a tuple
59                 outs = chainer.functions.identity(*outs)
60 
61         for out, grad_output in zip(outs, grad_outputs):
62             out.grad_var = grad_output
63         outs[0].backward()
64 
65         return tuple([inp.grad_var for inp in dummy_inputs])
66 
67 
68 def forget(func, *xs):
69     """Calls a function without storing intermediate results.
70 
71     On a forward propagation, Chainer normally stores all intermediate results
72     of :class:`~chainer.variable.VariableNode`\\ s on a computational graph as
73     they are required on backward propagation.
74     Sometimes these results consume too much memory.
75     ``F.forget`` *forgets* such intermediate results on forward propagation,
76     and still supports backpropagation with recalculation.
77 
78     On a forward propagation, ``F.forget`` calls a given function with given
79     variables without creating a computational graph. That means, no
80     intermediate results are stored.
81     On a backward propagation, ``F.forget`` calls the given function again to
82     create a computational graph for backpropagation.
83 
84     ``F.forget`` reduces internal memory usage, whereas it requires more
85     calculation time as it calls the function twice.
86 
87     .. admonition:: Example
88 
89        Let ``f`` be a function defined as:
90 
91        >>> def f(a, b):
92        ...   return a + b + a
93 
94        and, ``x`` and ``y`` be :class:`~chainer.Variable`\\ s:
95 
96        >>> x = chainer.Variable(np.random.uniform(-1, 1, 5).astype(np.float32))
97        >>> y = chainer.Variable(np.random.uniform(-1, 1, 5).astype(np.float32))
98 
99        When ``z`` is calculated as ``z = f(x, y)``, its intermediate result
100        ``x + y`` is stored in memory. Instead, if you call ``f`` with
101        ``F.forget``:
102 
103        >>> z = F.forget(f, x, y)
104 
105        intermediate ``x + y`` is forgotten.
106 
107     .. note::
108 
109         ``F.forget`` does not support functions which behave differently in
110         multiple calls with the same inputs, such as
111         :meth:`F.dropout() <chainer.functions.dropout>` and
112         :meth:`F.negative_sampling() <chainer.functions.negative_sampling>`.
113 
114     .. note::
115 
116         In case input argument variables are of class :class:`numpy.ndarray` or
117         :class:`cupy.ndarray` objects, arguments will automatically be
118         converted to :class:`~chainer.Variable`\\ s.
119         This conversion takes place to ensure that this function is included
120         in the computational graph to enable backward computations.
121 
122     .. note::
123 
124         ``F.forget`` does not support double backpropagation.
125 
126     Args:
127         func (callable): A function to call. It needs to be called with
128             :class:`~chainer.Variable` object(s) and to return a
129             :class:`~chainer.Variable` object or a tuple of
130             :class:`~chainer.Variable` objects.
131         xs (~chainer.Variable): Argument variables of the function.
132 
133     Returns:
134         ~chainer.Variable: A variable ``func`` returns. If it returns a tuple,
135         the method returns a tuple too.
136 
137     """
138     xs = tuple(x if isinstance(x, variable.Variable) else
139                variable.Variable(x, requires_grad=True) for x in xs)
140     y = Forget(func).apply(xs)
141     if len(y) == 1:
142         y, = y
143     return y
144
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/chainer/functions/util/forget.py b/chainer/functions/util/forget.py
--- a/chainer/functions/util/forget.py
+++ b/chainer/functions/util/forget.py
@@ -89,7 +89,7 @@
        Let ``f`` be a function defined as:
 
        >>> def f(a, b):
-       ...   return a + b + a
+       ...   return (a + b) * a
 
        and, ``x`` and ``y`` be :class:`~chainer.Variable`\\ s:

{"golden_diff": "diff --git a/chainer/functions/util/forget.py b/chainer/functions/util/forget.py\n--- a/chainer/functions/util/forget.py\n+++ b/chainer/functions/util/forget.py\n@@ -89,7 +89,7 @@\n        Let ``f`` be a function defined as:\n \n        >>> def f(a, b):\n-       ...   return a + b + a\n+       ...   return (a + b) * a\n \n        and, ``x`` and ``y`` be :class:`~chainer.Variable`\\\\ s:\n", "issue": "Docstring of `functions.forget` is incorrect as `+` doesn't retain inputs anymore\nThe docstring says that `(x + y) + x` retains the immediate variable holding `x + y`. \r\n\r\n```\r\n       Let ``f`` be a function defined as:\r\n       >>> def f(a, b):\r\n       ...   return a + b + a\r\n       and, ``x`` and ``y`` be :class:`~chainer.Variable`\\\\ s:\r\n       >>> x = chainer.Variable(np.random.uniform(-1, 1, 5).astype(np.float32))\r\n       >>> y = chainer.Variable(np.random.uniform(-1, 1, 5).astype(np.float32))\r\n       When ``z`` is calculated as ``z = f(x, y)``, its intermediate result\r\n       ``x + y`` is stored in memory. Instead, if you call ``f`` with\r\n       ``F.forget``:\r\n       >>> z = F.forget(f, x, y)\r\n       intermediate ``x + y`` is forgotten.\r\n```\r\n\r\nBut this isn't true for new-style function of `+`, because addition don't requires book-kept inputs for backpropagation.\r\n\r\nI checked the behavior by the following script, which traverses retained variables.\r\n\r\n```python\r\nimport chainer\r\nimport chainer.functions as F\r\nimport numpy as np \r\n\r\n\r\ndef f(a, b):\r\n    return (a + b) + a\r\n\r\n\r\ndef recur_check_vars(v, x, y):\r\n    creator = v.creator_node\r\n    if creator is None:\r\n        return\r\n    for pnode in creator.inputs:\r\n        p = pnode.get_variable()\r\n        assert p.data is None or p is x or p is y\r\n        print(p)\r\n        recur_check_vars(p, x, y) \r\n\r\n\r\ndef main():\r\n    x = chainer.Variable(np.random.uniform(-1, 1, 5).astype(np.float32))\r\n    y = chainer.Variable(np.random.uniform(-1, 1, 5).astype(np.float32))\r\n    print(x)\r\n    print(y)\r\n    print()\r\n    z = f(x, y) \r\n    recur_check_vars(z, x, y) \r\n\r\n\r\nif __name__ == '__main__':\r\n    main()\r\n```\r\n\r\nThe script doesn't fail, and the output is as follows. We can see that`x + y` is discarded. Living variables `x` and `y` are retrieved, as each `VariableNode` instance has a weakref to the corresponding variable.\r\n\r\n```\r\nvariable([-0.7699733  -0.50523347 -0.20869003 -0.7912116   0.92058474])\r\nvariable([ 0.58832335 -0.06183117  0.1939743   0.9021316  -0.19973369])\r\n\r\nvariable(None)\r\nvariable([-0.7699733  -0.50523347 -0.20869003 -0.7912116   0.92058474])\r\nvariable([ 0.58832335 -0.06183117  0.1939743   0.9021316  -0.19973369])\r\nvariable([-0.7699733  -0.50523347 -0.20869003 -0.7912116   0.92058474])\r\n```\n", "before_files": [{"content": "import chainer\nfrom chainer import function\nfrom chainer import function_node\nfrom chainer import variable\n\n\ndef _call_func(func, xs):\n    outs = func(*xs)\n\n    if isinstance(outs, tuple):\n        for i, out in enumerate(outs):\n            if isinstance(out, variable.Variable):\n                continue\n            n = i + 1\n            suffix = {1: 'st', 2: 'nd', 3: 'rd'}.get(\n                n if n < 20 else n % 10, 'th')\n            msg = ('{}{} element of a returned tuple is not Variable, '\n                   'but is {}').format(n, suffix, type(out))\n            raise RuntimeError(msg)\n    elif isinstance(outs, variable.Variable):\n        outs = (outs,)\n    else:\n        msg = ('A tuple of Variables or a Variable are expected, but {} '\n               'is returned.'.format(type(outs)))\n        raise RuntimeError(msg)\n\n    return outs\n\n\nclass Forget(function_node.FunctionNode):\n\n    def __init__(self, func):\n        if not callable(func):\n            raise TypeError('func must be callable')\n        self.func = func\n\n    def forward(self, inputs):\n        self.retain_inputs(tuple(range(len(inputs))))\n        with function.no_backprop_mode():\n            xs = [variable.Variable(x) for x in inputs]\n            outs = _call_func(self.func, xs)\n        return tuple(out.data for out in outs)\n\n    def backward(self, indexes, grad_outputs):\n        # Double backprop is not allowed\n        if chainer.config.enable_backprop:\n            raise RuntimeError('double backpropagation in functions.forget is '\n                               'not allowed.')\n\n        inputs = self.get_retained_inputs()\n        # Create new variables that have no creators\n        dummy_inputs = tuple([variable.Variable(inp.array) for inp in inputs])\n\n        with function.force_backprop_mode():\n            outs = _call_func(self.func, dummy_inputs)\n            assert len(outs) == len(grad_outputs)\n            if len(outs) > 1:\n                # Avoid doing backward multiple times when `outs` is a tuple\n                outs = chainer.functions.identity(*outs)\n\n        for out, grad_output in zip(outs, grad_outputs):\n            out.grad_var = grad_output\n        outs[0].backward()\n\n        return tuple([inp.grad_var for inp in dummy_inputs])\n\n\ndef forget(func, *xs):\n    \"\"\"Calls a function without storing intermediate results.\n\n    On a forward propagation, Chainer normally stores all intermediate results\n    of :class:`~chainer.variable.VariableNode`\\\\ s on a computational graph as\n    they are required on backward propagation.\n    Sometimes these results consume too much memory.\n    ``F.forget`` *forgets* such intermediate results on forward propagation,\n    and still supports backpropagation with recalculation.\n\n    On a forward propagation, ``F.forget`` calls a given function with given\n    variables without creating a computational graph. That means, no\n    intermediate results are stored.\n    On a backward propagation, ``F.forget`` calls the given function again to\n    create a computational graph for backpropagation.\n\n    ``F.forget`` reduces internal memory usage, whereas it requires more\n    calculation time as it calls the function twice.\n\n    .. admonition:: Example\n\n       Let ``f`` be a function defined as:\n\n       >>> def f(a, b):\n       ...   return a + b + a\n\n       and, ``x`` and ``y`` be :class:`~chainer.Variable`\\\\ s:\n\n       >>> x = chainer.Variable(np.random.uniform(-1, 1, 5).astype(np.float32))\n       >>> y = chainer.Variable(np.random.uniform(-1, 1, 5).astype(np.float32))\n\n       When ``z`` is calculated as ``z = f(x, y)``, its intermediate result\n       ``x + y`` is stored in memory. Instead, if you call ``f`` with\n       ``F.forget``:\n\n       >>> z = F.forget(f, x, y)\n\n       intermediate ``x + y`` is forgotten.\n\n    .. note::\n\n        ``F.forget`` does not support functions which behave differently in\n        multiple calls with the same inputs, such as\n        :meth:`F.dropout() <chainer.functions.dropout>` and\n        :meth:`F.negative_sampling() <chainer.functions.negative_sampling>`.\n\n    .. note::\n\n        In case input argument variables are of class :class:`numpy.ndarray` or\n        :class:`cupy.ndarray` objects, arguments will automatically be\n        converted to :class:`~chainer.Variable`\\\\ s.\n        This conversion takes place to ensure that this function is included\n        in the computational graph to enable backward computations.\n\n    .. note::\n\n        ``F.forget`` does not support double backpropagation.\n\n    Args:\n        func (callable): A function to call. It needs to be called with\n            :class:`~chainer.Variable` object(s) and to return a\n            :class:`~chainer.Variable` object or a tuple of\n            :class:`~chainer.Variable` objects.\n        xs (~chainer.Variable): Argument variables of the function.\n\n    Returns:\n        ~chainer.Variable: A variable ``func`` returns. If it returns a tuple,\n        the method returns a tuple too.\n\n    \"\"\"\n    xs = tuple(x if isinstance(x, variable.Variable) else\n               variable.Variable(x, requires_grad=True) for x in xs)\n    y = Forget(func).apply(xs)\n    if len(y) == 1:\n        y, = y\n    return y\n", "path": "chainer/functions/util/forget.py"}], "after_files": [{"content": "import chainer\nfrom chainer import function\nfrom chainer import function_node\nfrom chainer import variable\n\n\ndef _call_func(func, xs):\n    outs = func(*xs)\n\n    if isinstance(outs, tuple):\n        for i, out in enumerate(outs):\n            if isinstance(out, variable.Variable):\n                continue\n            n = i + 1\n            suffix = {1: 'st', 2: 'nd', 3: 'rd'}.get(\n                n if n < 20 else n % 10, 'th')\n            msg = ('{}{} element of a returned tuple is not Variable, '\n                   'but is {}').format(n, suffix, type(out))\n            raise RuntimeError(msg)\n    elif isinstance(outs, variable.Variable):\n        outs = (outs,)\n    else:\n        msg = ('A tuple of Variables or a Variable are expected, but {} '\n               'is returned.'.format(type(outs)))\n        raise RuntimeError(msg)\n\n    return outs\n\n\nclass Forget(function_node.FunctionNode):\n\n    def __init__(self, func):\n        if not callable(func):\n            raise TypeError('func must be callable')\n        self.func = func\n\n    def forward(self, inputs):\n        self.retain_inputs(tuple(range(len(inputs))))\n        with function.no_backprop_mode():\n            xs = [variable.Variable(x) for x in inputs]\n            outs = _call_func(self.func, xs)\n        return tuple(out.data for out in outs)\n\n    def backward(self, indexes, grad_outputs):\n        # Double backprop is not allowed\n        if chainer.config.enable_backprop:\n            raise RuntimeError('double backpropagation in functions.forget is '\n                               'not allowed.')\n\n        inputs = self.get_retained_inputs()\n        # Create new variables that have no creators\n        dummy_inputs = tuple([variable.Variable(inp.array) for inp in inputs])\n\n        with function.force_backprop_mode():\n            outs = _call_func(self.func, dummy_inputs)\n            assert len(outs) == len(grad_outputs)\n            if len(outs) > 1:\n                # Avoid doing backward multiple times when `outs` is a tuple\n                outs = chainer.functions.identity(*outs)\n\n        for out, grad_output in zip(outs, grad_outputs):\n            out.grad_var = grad_output\n        outs[0].backward()\n\n        return tuple([inp.grad_var for inp in dummy_inputs])\n\n\ndef forget(func, *xs):\n    \"\"\"Calls a function without storing intermediate results.\n\n    On a forward propagation, Chainer normally stores all intermediate results\n    of :class:`~chainer.variable.VariableNode`\\\\ s on a computational graph as\n    they are required on backward propagation.\n    Sometimes these results consume too much memory.\n    ``F.forget`` *forgets* such intermediate results on forward propagation,\n    and still supports backpropagation with recalculation.\n\n    On a forward propagation, ``F.forget`` calls a given function with given\n    variables without creating a computational graph. That means, no\n    intermediate results are stored.\n    On a backward propagation, ``F.forget`` calls the given function again to\n    create a computational graph for backpropagation.\n\n    ``F.forget`` reduces internal memory usage, whereas it requires more\n    calculation time as it calls the function twice.\n\n    .. admonition:: Example\n\n       Let ``f`` be a function defined as:\n\n       >>> def f(a, b):\n       ...   return (a + b) * a\n\n       and, ``x`` and ``y`` be :class:`~chainer.Variable`\\\\ s:\n\n       >>> x = chainer.Variable(np.random.uniform(-1, 1, 5).astype(np.float32))\n       >>> y = chainer.Variable(np.random.uniform(-1, 1, 5).astype(np.float32))\n\n       When ``z`` is calculated as ``z = f(x, y)``, its intermediate result\n       ``x + y`` is stored in memory. Instead, if you call ``f`` with\n       ``F.forget``:\n\n       >>> z = F.forget(f, x, y)\n\n       intermediate ``x + y`` is forgotten.\n\n    .. note::\n\n        ``F.forget`` does not support functions which behave differently in\n        multiple calls with the same inputs, such as\n        :meth:`F.dropout() <chainer.functions.dropout>` and\n        :meth:`F.negative_sampling() <chainer.functions.negative_sampling>`.\n\n    .. note::\n\n        In case input argument variables are of class :class:`numpy.ndarray` or\n        :class:`cupy.ndarray` objects, arguments will automatically be\n        converted to :class:`~chainer.Variable`\\\\ s.\n        This conversion takes place to ensure that this function is included\n        in the computational graph to enable backward computations.\n\n    .. note::\n\n        ``F.forget`` does not support double backpropagation.\n\n    Args:\n        func (callable): A function to call. It needs to be called with\n            :class:`~chainer.Variable` object(s) and to return a\n            :class:`~chainer.Variable` object or a tuple of\n            :class:`~chainer.Variable` objects.\n        xs (~chainer.Variable): Argument variables of the function.\n\n    Returns:\n        ~chainer.Variable: A variable ``func`` returns. If it returns a tuple,\n        the method returns a tuple too.\n\n    \"\"\"\n    xs = tuple(x if isinstance(x, variable.Variable) else\n               variable.Variable(x, requires_grad=True) for x in xs)\n    y = Forget(func).apply(xs)\n    if len(y) == 1:\n        y, = y\n    return y\n", "path": "chainer/functions/util/forget.py"}]}