diff -r 7a7a2849238c libinterp/octave-value/ov-class.cc
--- a/libinterp/octave-value/ov-class.cc	Fri Mar 24 14:07:43 2023 +0100
+++ b/libinterp/octave-value/ov-class.cc	Fri Apr 07 14:23:58 2023 +0200
@@ -465,32 +465,44 @@
           m_count++;
           args(0) = octave_value (this);
 
-          // FIXME: for Matlab compatibility, let us attempt to set up a proper
-          // value for nargout at least in the simple case where the
+          // If the number of output arguments is unknown, attempt to set up
+          // a proper value for nargout at least in the simple case where the
           // cs-list-type expression - i.e., {} or ().x, is the leading one.
-          // Note that Octave does not actually need this, since it will
-          // be able to properly react to varargout a posteriori.
-          bool maybe_cs_list_query = (type[0] == '.' || type[0] == '{'
-                                      || (type.length () > 1 && type[0] == '('
-                                          && type[1] == '.'));
-
-          int true_nargout = nargout;
-
-          if (maybe_cs_list_query)
+          if (nargout <= 0)
             {
-              // Set up a proper nargout for the subsref call by calling numel.
-              octave_value_list tmp;
-              if (type[0] != '.') tmp = idx.front ();
-              true_nargout = xnumel (tmp);
+              bool maybe_cs_list_query = (type[0] == '.' || type[0] == '{'
+                                          || (type.length () > 1 && type[0] == '('
+                                              && type[1] == '.'));
+
+              if (maybe_cs_list_query)
+                {
+                  // Set up a proper nargout for the subsref call by calling numel.
+                  octave_value_list tmp;
+                  int nout;
+                  if (type[0] != '.') tmp = idx.front ();
+                  nout = xnumel (tmp);
+                  if (nargout != 0 || nout > 1)
+                    nargout = nout;
+                }
+              else if (nargout < 0)
+                nargout = 1;
             }
 
-          retval = interp.feval (meth.function_value (), args, true_nargout);
-
-          // Since we're handling subsref, if the list has more than one
-          // element, return it as a comma-separated list so that we can
-          // pass it to the evaluator
-          if (retval.length () > 1)
-            retval = octave_value (retval);
+          retval = interp.feval (meth.function_value (), args, nargout);
+
+          // Since we're handling subsref, if the list has more than one element
+          // and the caller to subsref accepts more that one output, return
+          // the elements as a comma-separated list so that we can pass it to the
+          // evaluator
+          if (retval.length () > 1 && (nargout < 0 || nargout >1))
+            {
+              if (nargout <= 0 || nargout>=retval.length())
+                // Take the whole list
+                retval = octave_value (retval);
+              else
+                // Take nargout elements of the list
+                retval = octave_value(retval.slice(0,nargout));
+            }
         }
       else
         {
diff -r 7a7a2849238c libinterp/octave-value/ov-classdef.cc
--- a/libinterp/octave-value/ov-classdef.cc	Fri Mar 24 14:07:43 2023 +0100
+++ b/libinterp/octave-value/ov-classdef.cc	Fri Apr 07 14:23:58 2023 +0200
@@ -91,28 +91,44 @@
           m_count++;
           args(0) = octave_value (this);
 
-          // Attempt to set up a proper value for nargout at least in the
-          // simple case where the cs-list-type expression - i.e., {} or
-          // ().x, is the leading one.
-          bool maybe_cs_list_query = (type[0] == '.' || type[0] == '{'
-                                      || (type.length () > 1 && type[0] == '('
-                                          && type[1] == '.'));
+          // If the number of output arguments is unknown, attempt to set up
+          // a proper value for nargout at least in the simple case where the
+          // cs-list-type expression - i.e., {} or ().x, is the leading one.
+          if (nargout <= 0)
+            {
+              bool maybe_cs_list_query = (type[0] == '.' || type[0] == '{'
+                                          || (type.length () > 1 && type[0] == '('
+                                              && type[1] == '.'));
 
-          if (maybe_cs_list_query)
-            {
-              // Set up a proper nargout for the subsref call by calling numel.
-              octave_value_list tmp;
-              if (type[0] != '.') tmp = idx.front ();
-              nargout = xnumel (tmp);
+              if (maybe_cs_list_query)
+                {
+                  // Set up a proper nargout for the subsref call by calling numel.
+                  octave_value_list tmp;
+                  int nout;
+                  if (type[0] != '.') tmp = idx.front ();
+                  nout = xnumel (tmp);
+                  if (nargout != 0 || nout > 1)
+                    nargout = nout;
+                }
+              else if (nargout < 0)
+                nargout = 1;
             }
 
           retval = meth.execute (args, nargout, true, "subsref");
 
-          // Since we're handling subsref, if the list has more than one
-          // element, return it as a comma-separated list so that we can
-          // pass it to the evaluator
-          if (retval.length () > 1)
-            retval = octave_value (retval);
+          // Since we're handling subsref, if the list has more than one element
+          // and the caller to subsref accepts more that one output, return
+          // the elements as a comma-separated list so that we can pass it to the
+          // evaluator
+          if (retval.length () > 1 && (nargout < 0 || nargout >1))
+            {
+              if (nargout <= 0 || nargout>=retval.length())
+                // Take the whole list
+                retval = octave_value (retval);
+              else
+                // Take nargout elements of the list
+                retval = octave_value(retval.slice(0,nargout));
+            }
 
           return retval;
         }
diff -r 7a7a2849238c libinterp/parse-tree/pt-binop.cc
--- a/libinterp/parse-tree/pt-binop.cc	Fri Mar 24 14:07:43 2023 +0100
+++ b/libinterp/parse-tree/pt-binop.cc	Fri Apr 07 14:23:58 2023 +0200
@@ -71,11 +71,13 @@
 {
   if (m_lhs)
     {
-      octave_value a = m_lhs->evaluate (tw);
+      // Evaluate with unkown number of output arguments
+      octave_value a = m_lhs->evaluate (tw,-1);
 
       if (a.is_defined () && m_rhs)
         {
-          octave_value b = m_rhs->evaluate (tw);
+          // Evaluate with unkown number of output arguments
+          octave_value b = m_rhs->evaluate (tw,-1);
 
           if (b.is_defined ())
             {
diff -r 7a7a2849238c libinterp/parse-tree/pt-eval.cc
--- a/libinterp/parse-tree/pt-eval.cc	Fri Mar 24 14:07:43 2023 +0100
+++ b/libinterp/parse-tree/pt-eval.cc	Fri Apr 07 14:23:58 2023 +0200
@@ -2283,7 +2283,8 @@
       if (! elt)
         break;
 
-      octave_value tmp = elt->evaluate (*this);
+      // Evaluate with unkown number of output arguments
+      octave_value tmp = elt->evaluate (*this, -1);
 
       if (tmp.is_cs_list ())
         {
@@ -3358,6 +3359,11 @@
 
   octave_builtin::fcn fcn = builtin_function.function ();
 
+  // If number of outputs unknown (and this is not a complete statement),
+  // pass nargout=1 to the function being called
+  if (nargout < 0)
+    nargout = 1;
+
   if (fcn)
     retval = (*fcn) (args, nargout);
   else
@@ -3401,6 +3407,11 @@
 
   profiler::enter<octave_mex_function> block (m_profiler, mex_function);
 
+  // If number of outputs unknown (and this is not a complete statement),
+  // pass nargout=1 to the function being called
+  if (nargout < 0)
+    nargout = 1;
+
   retval = call_mex (mex_function, args, nargout);
 
   return retval;
@@ -3471,6 +3482,11 @@
 
   int nargin = args.length ();
 
+  // If number of outputs unknown (and this is not a complete statement),
+  // pass nargout=1 to the function being called
+  if (nargout < 0)
+    nargout = 1;
+  
   if (user_function.is_classdef_constructor ())
     {
       if (nargin > 0)
diff -r 7a7a2849238c libinterp/parse-tree/pt-tm-const.cc
--- a/libinterp/parse-tree/pt-tm-const.cc	Fri Mar 24 14:07:43 2023 +0100
+++ b/libinterp/parse-tree/pt-tm-const.cc	Fri Apr 07 14:23:58 2023 +0200
@@ -168,7 +168,8 @@
     {
       octave_quit ();
 
-      octave_value tmp = elt->evaluate (tw);
+      // Evaluate with unkown number of output arguments
+      octave_value tmp = elt->evaluate (tw,-1);
 
       if (tmp.is_undefined ())
         error ("undefined element in matrix list");
