When calling a class (say, to convert types), are we calling a function?

I know that we can call built-in MATLAB classes and input values of any other built-in class into it with the same inputting syntax that we use for functions e.g. double('a'). Does this mean a class is a function? Or is it that a separate function is invoked when we call a class?
For example, what is the behind-the-scenes difference between calling sin as a function, and calling logical as a function? They both act like functions, and to make matters worse, both become function handles if we type @ in front of their identifiers:
isSinAfunction = isa(@sin,'function_handle')
isSinAfunction = logical
1
isLogicalAfunction = isa(@logical, 'function_handle')
isLogicalAfunction = logical
1
So is logical a function?

 Accepted Answer

For example, what is the behind-the-scenes difference between calling sin as a function, and calling logical as a function?
Nothing, really. [There may be some technical scenarios that I'm not thinking of offhand where there are differences, but for the most part there should be no difference.]
They both act like functions, and to make matters worse, both become function handles if we type @ in front of their identifiers:
There's a good reason for that. The reason is that they're both functions, in this case both built-in functions.
which sin
built-in (/MATLAB/toolbox/matlab/elfun/@double/sin) % double method
which logical
built-in (/MATLAB/toolbox/matlab/datatypes/logical)
So is logical a function?
Yes. Its purpose is to convert whatever you pass into it into a logical array. You can see this by looking at the documentation page for the logical function. Sometimes it does this by calling a built-in function, sometimes (if the class of its input has overloaded the function) it calls a class method.
I suspect what you may be trying to figure out is whether logical is a class constructor or a function. The answer is it falls more into the "conversion method" (or "conversion function") category, as described in the "Kinds of Methods" section on this documentation page. Some of the functions with the same name as a built-in class straddle the line between constructor and converter, the struct function jumps immediately to mind. But logical is IMO just a converter. If you were trying to construct a logical array (from size data) you'd be more likely to call true, false, or one of the array creation functions like ones or zeros.

9 Comments

[There may be some technical scenarios that I'm not thinking of offhand where there are differences, but for the most part there should be no difference.]
For those especially curious about these technical scenarios, the only thing that comes to mind is Dot Syntax vs Function Syntax. It doesn't apply in the examples that Ardy listed, but it does matter for object methods with more than one input, such as plus. If you want to dive in deeper to how MATLAB determines which functions to call, you can explore this example.
I'll also leave a note about my favorite way to allocate a large array of logicals, indexing! a(100,100) = false;
Hi Kyle,
a(100, 100) = false
or
a = false(100)
Is there any difference within MATLAB? or it’s just a matter of preference?
Hi madhan,
Great question! In general, if there is a builtin MATLAB function to initialize an array, it is best to use it. Syntax like a = false(100) is also less ambiguous to someone reading your code. You know that it will always create a new variable named a. Whereas using indexing to initialize the array will have different behavior if a already exists.
The times where using indexing might be better are if your algorithm actually wants different behavior the first time executing the assignment or if you are working with a data type like an object without its own builtin array creation function. But most people don't know this is even a valid way of initializing an array, so I always enjoy pointing it out!
Is there any difference within MATLAB?
Yes.
a = 42
a = 42
a(2, 2) = false
a = 2×2
42 0 0 0
class(a)
ans = 'double'
If the array already exists, extending it by assigning to a value in a location that doesn't yet exist doesn't change its type. It changes what you're trying to store in the array into the type of the array (in this case, false becomes 0.) For logical in most cases this doesn't make a difference, except if you were to try to use a for indexing. I'll put that code at the end of this comment as it will throw an error.
Compare:
b = 42
b = 42
b = false(2)
b = 2×2 logical array
0 0 0 0
This overwrites b (even though it existed already) and the new b is a logical array.
Indexing example:
a = magic(4)
a = 4×4
16 2 3 13 5 11 10 8 9 7 6 12 4 14 15 1
ind = true(4)
ind = 4×4 logical array
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
ind([1 6 11 16]) = false
ind = 4×4 logical array
0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0
a(ind)
ans = 12×1
5 9 4 2 7 14 3 10 15 13
ind2 = ones(4)
ind2 = 4×4
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
ind2([1 16 11 16]) = false
ind2 = 4×4
0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0
a(ind2) % throws an error
Array indices must be positive integers or logical values.
Thank you for your answer and comment Steven and Kyle. They were both helpful.
The which examples in Steven's answer raise further questions in my mind. The sin function is in the elfun folder (which I presume stands for elementary function), yet logical is in the datatypes folder ... . Doesn't this shake your confidence that logical is just a converter function like any other function?
The source of my confusion is when I compare MATLAB to how objects are constructed in Ptyhon, and over there, they "call" classes. In fact they say classes are "callable".
Doesn't this shake your confidence that logical is just a converter function like any other function?
Why? The datatypes directory is not restricted to only containing data types. For example none of the functions whose names start with "is" are data types. They are querying functions. func2str and str2func are essentially conversion functions between text (char or string) and function handles. cast and typecast are general converter functions.
what(fullfile(matlabroot, 'toolbox', 'matlab', 'datatypes'))
MATLAB Code files in folder /MATLAB/toolbox/matlab/datatypes cast func2str int64 isfloat isnumeric javaObjectEDT properties superiorto uint8 class function_handle int8 isinteger isobject loadobj saveobj swapbytes underlyingType double functions isUnderlyingType isinterface javaArray logical single typecast enumeration inferiorto isa isjava javaMethod metaclass str2func uint16 events int16 iscom islogical javaMethodEDT methods superclasses uint32 formattedDisplayText int32 isenum ismethod javaObject methodsview superiorfloat uint64 P-files in folder /MATLAB/toolbox/matlab/datatypes isprop Classes in folder /MATLAB/toolbox/matlab/datatypes internalArrayUtil opaque Packages in folder /MATLAB/toolbox/matlab/datatypes containers matlab
Don't read that much into the directory names. Generally they group related functionality. But that can still lead to somewhat varying functions all being lumped in the same directory. For example, the elfun directory contains the trigonometric functions, the exponential and logarithm functions, functions for assembling and disassembling complex numbers, and rounding functions.
help elfun
Elementary math functions. Trigonometric. sin - Sine. sind - Sine of argument in degrees. sinh - Hyperbolic sine. asin - Inverse sine. asind - Inverse sine, result in degrees. asinh - Inverse hyperbolic sine. cos - Cosine. cosd - Cosine of argument in degrees. cosh - Hyperbolic cosine. acos - Inverse cosine. acosd - Inverse cosine, result in degrees. acosh - Inverse hyperbolic cosine. tan - Tangent. tand - Tangent of argument in degrees. tanh - Hyperbolic tangent. atan - Inverse tangent. atand - Inverse tangent, result in degrees. atan2 - Four quadrant inverse tangent. atan2d - Four quadrant inverse tangent, result in degrees. atanh - Inverse hyperbolic tangent. sec - Secant. secd - Secant of argument in degrees. sech - Hyperbolic secant. asec - Inverse secant. asecd - Inverse secant, result in degrees. asech - Inverse hyperbolic secant. csc - Cosecant. cscd - Cosecant of argument in degrees. csch - Hyperbolic cosecant. acsc - Inverse cosecant. acscd - Inverse cosecant, result in degrees. acsch - Inverse hyperbolic cosecant. cot - Cotangent. cotd - Cotangent of argument in degrees. coth - Hyperbolic cotangent. acot - Inverse cotangent. acotd - Inverse cotangent, result in degrees. acoth - Inverse hyperbolic cotangent. hypot - Square root of sum of squares. deg2rad - Convert angles from degrees to radians. rad2deg - Convert angles from radians to degrees. Exponential. exp - Exponential. expm1 - Compute exp(x)-1 accurately. log - Natural logarithm. log1p - Compute log(1+x) accurately. log10 - Common (base 10) logarithm. log2 - Base 2 logarithm and dissect floating point number. pow2 - Base 2 power and scale floating point number. realpow - Power that will error out on complex result. reallog - Natural logarithm of real number. realsqrt - Square root of number greater than or equal to zero. sqrt - Square root. nthroot - Real n-th root of real numbers. nextpow2 - Next higher power of 2. Complex. abs - Absolute value. angle - Phase angle. complex - Construct complex data from real and imaginary parts. conj - Complex conjugate. imag - Complex imaginary part. real - Complex real part. unwrap - Unwrap phase angle. isreal - True for real array. cplxpair - Sort numbers into complex conjugate pairs. Rounding and remainder. fix - Round towards zero. floor - Round towards minus infinity. ceil - Round towards plus infinity. round - Round towards nearest integer. mod - Modulus (signed remainder after division). rem - Remainder after division. sign - Signum.
The source of my confusion is when I compare MATLAB to how objects are constructed in Ptyhon, and over there, they "call" classes. In fact they say classes are "callable".
Okay. Do they mean that classes are "callable" (aka constructible, able to be instantiated as long as they're concrete?) via calling their constructor method or via factory functions/methods? If so, then they're behaving the same way as MATLAB. And if they mean something different, well if all programming languages were required to behave exactly the same way we'd all be programming in Short Code, Autocode, or FORTRAN.
"In fact they say classes are "callable"."
They are not really.
In Python everything is an object. Those that are callable simply have a defined __call__ method:
Quoting that last page: "The __call__ method enables Python programmers to write classes where the instances behave like functions and can be called like a function. When the instance is called as a function; if this method is defined, x(arg1, arg2, ...) is a shorthand for x.__call__(arg1, arg2, ...)."
So even in Python, the class itself in not called, the __call__ method is.
Fair enough. I am convinced. Thanks Steven!

Sign in to comment.

More Answers (1)

I like to think of it like this. In standard object oriented programming (OOP) you have a "class" which is an object that is a collection of "properties" and "methods". The "properties" are your variable names. And the "methods" are what MATLAB calls "functions".
So you don't really "call" a class. You "call" methods/functions of the class, and "assign" properties/variables of the class.

Products

Release

R2023b

Asked:

on 17 Dec 2023

Commented:

on 20 Dec 2023

Community Treasure Hunt

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

Start Hunting!