code: def eval(self, ctx=None, **kwargs):
          
          if ctx is None:
              ctx = current_context()
          return self.bind(ctx, kwargs).forward()
docs: Evaluates a symbol given arguments.
  
          The `eval` method combines a call to `bind` (which returns an executor)
          with a call to `forward` (executor method).
          For the common use case, where you might repeatedly evaluate with same arguments,
          eval is slow.
          In that case, you should call `bind` once and then repeatedly call forward.
          This function allows simpler syntax for less cumbersome introspection.
  
          Example
          -------
          >>> a = mx.sym.Variable('a')
          >>> b = mx.sym.Variable('b')
          >>> c = a + b
          >>> ex = c.eval(ctx = mx.cpu(), a = mx.nd.ones([2,3]), b = mx.nd.ones([2,3]))
          >>> ex
          [<NDArray 2x3 @cpu(0)>]
          >>> ex[0].asnumpy()
          array([[ 2.,  2.,  2.],
                 [ 2.,  2.,  2.]], dtype=float32)
  
          Parameters
          ----------
          ctx : Context
              The device context the generated executor to run on.
  
          kwargs : Keyword arguments of type `NDArray`
              Input arguments to the symbol. All the arguments must be provided.
  
          Returns
          ----------
          result :  a list of NDArrays corresponding to the values taken by each symbol when
          evaluated on given args. When called on a single symbol (not a group),
          the result will be a list with one element.