What is a function handle and how is it useful?
Asked Answered
L

3

38

Can somebody explain to me the meaning of the @ (function handle) operator and why to use it?

Latishalatitude answered 28/4, 2009 at 9:9 Comment(0)
D
50

The function handle operator in MATLAB acts essentially like a pointer to a specific instance of a function. Some of the other answers have discussed a few of its uses, but I'll add another use here that I often have for it: maintaining access to functions that are no longer "in scope".

For example, the following function initializes a value count, and then returns a function handle to a nested function increment:

function fHandle = start_counting(count)

  disp(count);
  fHandle = @increment;

  function increment
    count = count+1;
    disp(count);
  end

end

Since the function increment is a nested function, it can only be used within the function start_counting (i.e. the workspace of start_counting is its "scope"). However, by returning a handle to the function increment, I can still use it outside of start_counting, and it still retains access to the variables in the workspace of start_counting! That allows me to do this:

>> fh = start_counting(3);  % Initialize count to 3 and return handle
     3

>> fh();  % Invoke increment function using its handle
     4

>> fh();
     5

Notice how we can keep incrementing count even though we are outside of the function start_counting. But you can do something even more interesting by calling start_counting again with a different number and storing the function handle in another variable:

>> fh2 = start_counting(-4);
    -4

>> fh2();
    -3

>> fh2();
    -2

>> fh();  % Invoke the first handle to increment
     6

>> fh2();  % Invoke the second handle to increment
    -1

Notice that these two different counters operate independently. The function handles fh and fh2 point to different instances of the function increment with different workspaces containing unique values for count.

In addition to the above, using function handles in conjunction with nested functions can also help streamline GUI design, as I illustrate in this other SO post.

Duncandunce answered 28/4, 2009 at 13:44 Comment(3)
One thing that's important to note is that functions created with the function keyword and functions created by the @ operator have different scoping rules. hGetCount=@getCount;function c=getCount; c=count; end; does the lookup of the count variable at evaluation time (using lexical scoping), as you describe above. The function hGetCount=@()count; will have the count variable's value substituted at creation time.Dodgem
Function handles allow you to work with nested functions or subfunctions, from outside of the main function. They can aid you in GUI programming.Bani
@ Mr. Fooz: Good point! Anonymous functions created with the @ operator will simply substitute values for the variables that exist in the workspace at the time they are created, while "normal" functions have their own workspaces for storing variables.Duncandunce
B
18

Function handles are an extremely powerful tool in matlab. A good start is to read the online help, which will give you far more than I can. At the command prompt, type

doc function_handle

A function handle is a simple way to create a function in one line. For example, suppose I wished to numerically integrate the function sin(k*x), where k has some fixed, external value. I could use an inline function, but a function handle is much neater. Define a function

k = 2;
fofx = @(x) sin(x*k);

See that I can now evaluate the function fofx at the command line. MATLAB knows what k is, so we can use fofx as a function now.

fofx(0.3)
ans =
         0.564642473395035

In fact, we can pass fofx around, effectively as a variable. For example, lets call quad to do the numerical integration. I'll pick the interval [0,pi/2].

quad(fofx,0,pi/2)
ans =
         0.999999998199215

As you can see, quad did the numerical integration. (By the way, an inline function would have been at least an order of magitude slower, and far less easy to work with.)

x = linspace(0,pi,1000);
tic,y = fofx(x);toc
Elapsed time is 0.000493 seconds.

By way of comparison, try an inline function.

finline = inline('sin(x*k)','x','k');
tic,y = finline(x,2);toc
Elapsed time is 0.002546 seconds.

A neat thing about a function handle is you can define it on the fly. Minimize the function cos(x), over the interval [0,2*pi]?

xmin = fminbnd(@(x) cos(x),0,2*pi)
xmin =
          3.14159265358979

There are many, many other uses for function handles in MATLAB. I've only scratched the surface here.

Bani answered 28/4, 2009 at 11:41 Comment(0)
P
15

Disclaimer: code not tested...

The function handle operator allows you to create a reference to a function and pass it around just like any other variable:

% function to add two numbers
function total = add(first, second) 
    total = first + second;
end

% this variable now points to the add function
operation = @add;

Once you've got a function handle, you can invoke it just like a regular function:

operation(10, 20); % returns 30

One nice thing about function handles is that you can pass them around just like any other data, so you can write functions that act on other functions. This often allows you to easily separate out business logic:

% prints hello
function sayHello 
    disp('hello world!');
end

% does something five times
function doFiveTimes(thingToDo) 
    for idx = 1 : 5 
        thingToDo();
    end
end

% now I can say hello five times easily:
doFiveTimes(@sayHello);

% if there's something else I want to do five times, I don't have to write
% the five times logic again, only the operation itself:
function sayCheese 
    disp('Cheese');
end
doFiveTimes(@sayCheese);

% I don't even need to explicitly declare a function - this is an 
% anonymous function:
doFiveTimes(@() disp('do something else'));

The Matlab documentation has a fuller description of the Matlab syntax, and describes some other uses for function handles like graphics callbacks.

Passionless answered 28/4, 2009 at 11:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.