docs: def scatter(x_fn, y_fn, *, options={}, **interact_params):
      """
      Generates an interactive scatter chart that allows users to change the
      parameters of the inputs x_fn and y_fn.
  
      Args:
          x_fn (Array | (*args -> Array str | Array int | Array float)):
              If array, uses array values for x-coordinates.
  
              If function, must take parameters to interact with and return an
              array of strings or numbers. These will become the x-coordinates
              of the scatter plot.
  
          y_fn (Array | (Array, *args -> Array int | Array float)):
              If array, uses array values for y-coordinates.
  
              If function, must take in the output of x_fn as its first parameter
              and optionally other parameters to interact with. Must return an
              array of numbers. These will become the y-coordinates of the
              scatter plot.
  
      Kwargs:
          {options}
  
          interact_params (dict): Keyword arguments in the same format as
              `ipywidgets.interact`. One argument is required for each argument
              of both `x_fn` and `y_fn`. If `x_fn` and `y_fn` have conflicting
              parameter names, prefix the corresponding kwargs with `x__` and
              `y__`.
  
      Returns:
          VBox with two children: the interactive controls and the figure.
  
      >>> def x_values(n): return np.random.choice(100, n)
      >>> def y_values(xs): return np.random.choice(100, len(xs))
      >>> scatter(x_values, y_values, n=(0,200))
      VBox(...)
      """
      params = {
          'marks': [{
              'x': _array_or_placeholder(x_fn),
              'y': _array_or_placeholder(y_fn),
              'marker': _get_option('marker'),
          }]
      }
      fig = options.get('_fig', False) or _create_fig(options=options)
      [scat] = _create_marks(
          fig=fig, marks=[bq.Scatter], options=options, params=params
      )
      _add_marks(fig, [scat])
  
      def wrapped(**interact_params):
          x_data = util.maybe_call(x_fn, interact_params, prefix='x')
          scat.x = x_data
  
          y_bound = util.maybe_curry(y_fn, x_data)
          scat.y = util.maybe_call(y_bound, interact_params, prefix='y')
  
      controls = widgets.interactive(wrapped, **interact_params)
  
      return widgets.VBox([controls, fig])