Adoption of Name=Value in Function Calls what is best practice?

19 visualizaciones (últimos 30 días)
Since R2021A there are two syntaxes available for passing name-value arguments.
There is the traditional, comma separated syntax, for example:
z = foo(x,y, "age",23,"animal","cat")
and the new name = value syntax, for example:
z = foo(x,y,age = 23,animal = "cat" )
My question is, when writing new code, when calling functions that use name-value pairs, should I switch over and always adopt the new name = value syntax?
What would be considered best practice in this regard? Seems like it might be a good idea to change with the times and use the newest approach, but not sure.
Since both approaches still work, perhaps this is just a matter of taste, and there is no right answer, but I'd welcome guidance on whether to make this transition.
  2 comentarios
Stephen23
Stephen23 el 5 de Feb. de 2024
A little bit of experimentation shows that the new name=value sytnax is just some syntactic sugar, in actual fact the values are still provided to the function as text + value, e.g. as separate "name",value inputs or as structure fields:
myOne("hello",pi, world=sqrt(2))
ans = "hello"
ans = 3.1416
ans = "world"
ans = 1.4142
myTwo("hello",pi, world=sqrt(2))
inArg = struct with fields:
hello: 3.1416 world: 1.4142
function myOne(varargin)
varargin{:}
end
function myTwo(inArg)
arguments
inArg.hello
inArg.world
inArg.unused
end
inArg
end
It is unclear if there is any performance benefit/disadvantage to this syntactic sugar.
Walter Roberson
Walter Roberson el 5 de Feb. de 2024
I figure that there must be a slight performance penalty when parsing arguments blocks. On the other hand, arguments blocks get automatically detected by the function signatures mechanisms for editing purposes, which is an advantage at edit time.

Iniciar sesión para comentar.

Respuesta aceptada

John D'Errico
John D'Errico el 5 de Feb. de 2024
Editada: John D'Errico el 5 de Feb. de 2024
What is best practice? I kind of like the new syntax. But best practice would seem to be whatever you like. At some point, might the older style be phased out? My guess is since the new syntax is just converted on the fly to the old syntax, you will be ok for the forseeable future. Anything could happen in the future though, and my ability to see the future is rarely good.
It was never valid in the past to use the var=stuff syntax in MATLAB. And you cannot just use it at will on any function. For example...
help prod
PROD Product of elements. P = PROD(X) is the product of the elements of the vector X. If X is a matrix, P is a row vector with the product over each column. For N-D arrays, PROD(X) operates on the first non-singleton dimension. PROD(X,"all") computes the product of all elements of X. PROD(X,DIM) operates along the dimension DIM. PROD(X,VECDIM) operates on the dimensions specified in the vector VECDIM. For example, PROD(X,[1 2]) operates on the elements contained in the first and second dimensions of X. PROD(...,OUTTYPE) specifies the type in which the product is performed, and the type of P. Available options are: "double" - P has class double for any input X "native" - P has the same class as X "default" - If X is floating point, that is double or single, P has the same class as X. If X is not floating point, P has class double. PROD(...,NANFLAG) specifies how NaN values are treated: "includemissing" / "includenan" - (default) The product of a vector containing NaN values is also NaN. "omitmissing" / "omitnan" - The product of a vector containing NaN values is the product of all its non-NaN elements. If all elements are NaN, the result is 1. Examples: X = [0 1 2; 3 4 5] prod(X,1) prod(X,2) X = int8([5 5 5 5]) prod(X) % returns double(625), accumulates in double prod(X,"native") % returns int8(127), because it accumulates in % int8, but overflows and saturates. See also SUM, CUMPROD, DIFF. Documentation for prod doc prod Other uses of prod codistributed/prod laurmat/prod sym/prod dlarray/prod laurpoly/prod tabular/prod gpuArray/prod quaternion/prod tall/prod
A = magic(3)
A = 3×3
8 1 6 3 5 7 4 9 2
prod(A,dim=2)
Error using prod
Invalid option. Option must be 'all', 'double', 'native', 'default', 'omitnan', 'includenan', 'omitmissing' or 'includemissing'.
As shown by @Stephen23 (in what I feel should have been an answer) all if does is convert what you passed in into a name-value pair. For example, in my SLM toolbox, which was written before many of the people on this forum knew how to spell MATLAB, it assumes name-value pairs. As such, my slmengine tool has no ability to directly recognize the name=stuff syntax, and before the syntax was introduced, it would have failed. But it does work now:
x = rand(1,5);
y = rand(1,5);
slmengine(x,y,knots = [0 .5 1])
ans =
struct with fields:
form: 'slm'
degree: 3
knots: [3×1 double]
coef: [3×2 double]
stats: [1×1 struct]
prescription: [1×1 struct]
x: [5×1 double]
y: [5×1 double]
Extrapolation: 'constant'
It works just fine. Note though, you cannot mix your call. So this fails:
slmengine(x,y,knots = [0 .5 1],'plot','on')
Error: Unsupported use of the '=' operator. To compare values for equality, use '=='. To pass
name-value arguments using the name=value format, provide these arguments after all other inputs.
Related documentation
Even though this call did work properly:
slmengine(x,y,knots = [0 .5 1],plot = 'on')
  1 comentario
Cris LaPierre
Cris LaPierre el 6 de Feb. de 2024
Editada: Cris LaPierre el 6 de Feb. de 2024
Minor correction. You can mix your syntaxes but, as the error message states, the name=value syntax must be at the end.
y = rand(1,5);
plot(y,"Color",'r',Marker='*')

Iniciar sesión para comentar.

Más respuestas (3)

Cris LaPierre
Cris LaPierre el 6 de Feb. de 2024
This really comes down to personal preference. They are all equivalent syntatically. Name=value syntax can feel more familiar for some due to their experience with other programming languages. Just keep in mind that, as a new syntax, it may not be available everywhere yet.
  2 comentarios
Jon
Jon el 6 de Feb. de 2024
Thank you very much, for your response on this. Also a good answer but I had to pick one. @John D'Errico gave me some additional insight into what was happening under the covers so I chose that.
John D'Errico
John D'Errico el 6 de Feb. de 2024
Thanks for the observation that the name=value appproach must happen only at the end, if you are going to mix modes. Personally, I can't imagine why one would do that. Using both styles in one call seems a bit silly, even though I tried it myself to see what would happen.
My guess is the name=value style will win in the end, but it may take years for some of us to change over. Inertia is always present, and more so in those of us who have been using the old style for decades now.

Iniciar sesión para comentar.


Matt J
Matt J el 5 de Feb. de 2024
Editada: Matt J el 5 de Feb. de 2024
The only consideration I can think of is if you might need to run your code on an older version of Matlab that predates the new name-value syntax. If so, it won't run, obviously.
  3 comentarios
Matt J
Matt J el 5 de Feb. de 2024
No, that was never a valid call.
Jon
Jon el 6 de Feb. de 2024
Thank you very much, for your response on this. Also a good answer but I had to pick one. @John D'Errico gave me some additional insight into what was happening under the covers so I chose that.

Iniciar sesión para comentar.


Catalytic
Catalytic el 6 de Feb. de 2024
Editada: Catalytic el 6 de Feb. de 2024
One situation where you have to stick with the old style anyway is when you want to pre-package your name value pairs in a cell -
line_args={'LineWidth',2,'Color','red'};
plot(rand(1,7) , line_args{:})
You can't do this -
line_args={LineWidth=2,Color='red'};
plot(rand(1,7) , line_args{:})
  2 comentarios
Cris LaPierre
Cris LaPierre el 6 de Feb. de 2024
Correct. In this case, you are first creating a variable, and the assignment operator would be misinterpretted.
Matt J
Matt J el 6 de Feb. de 2024
Editada: Matt J el 6 de Feb. de 2024
@Catalytic You could write yourself a simple 1-line function to handle that kind of situation. Might be worth implementing it as a permanent mfile for yourself.
nvp=@(varargin) varargin;
line_args=nvp(LineWidth=2,Color='red');
plot(rand(1,7) , line_args{:})

Iniciar sesión para comentar.

Productos


Versión

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by