returning multiple variables

I am making a user-defined function.
I would like to return more than one variable and/or wave

function myfunc
...
return a, b, c

doesn't work. what is the correct syntax?
kperks wrote:
I am making a user-defined function.
I would like to return more than one variable and/or wave


Like most languages that trace their roots back to C, the Igor language doesn't provide for more than one return value. Instead what you probably want to use is pass-by-reference. Try executing

 DisplayHelpTopic "Pass-By-Reference"

The same goes for functions that return waves: only one wave can be returned. Instead many Igor operations and functions support 'returning' more than one wave by creating waves with agreed-upon names. For example:
myFunction() // somewhere in myFunction waves called "MyWave1" and "MyWave2" are created
wave MyWave1, myWave2 // let Igor know that these are wave references pointing to waves with these names

// use MyWave1 and MyWave2 as you normally would


A third option to return multiple values is to simply return a single wave that contains them. You can even make use of waves-containing-wave-references to return multiple waves. But the latter can get confusing.
Especially for waves two more options come to my mind (error checking omitted).

1. Pass a wavename into a function, and let that function create the wave
string wvName1 = "myWave1"
string wvName2 = "myWave2"
doStuff(wvName1,wvName1)
...
Wave wv1 = $wvName1
Wave wv2 = $wvName2

Function doStuff(str1, str2)
string str1, str2

Make $str1
Make $str2
End

This works also for waves in datafolders, just pass either a absolute path in str1, str2, or if they have a common folder use a dfref as additional parameter.

2. In case you don't need the last bit of performance (redimensioning is not as fast as creating it directly at the correct size) you can also do something like
Make/N=0 myWave
doStuff(myWave)
...
// use the wave myWave

..
Function doStuff(wv)
Wave wv

Redimension/N=(desiredSize) wv

End


Especially the second example is quite nice with FREE waves.
Another somewhat ugly way would be to define the function as string function by using Function/S and return your values wrapped up in a string. Then you could use StringByKey or StringFromList to get them back.

Like:
Function/S myfunc()
...
return num2str(a) + ";" + num2str(b) + ";" ...
End

Function get_a()
String funcvalues = myfunc()
print StringFromList(0,funcvalues)
End
... and in Igor 6.2 you can make a free wave and return it as a wave reference from your function.
Function/WAVE test()

    Make/D/FREE freewave={1,2,3}
    return freewave
end

Function testdrive()

    Wave w = test()
    print w
end


Invoked from the command line:

•testdrive()
'_free_'[0]= {1,2,3}


John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
chozo wrote:
Another somewhat ugly way would be to define the function as string function by using Function/S and return your values wrapped up in a string. Then you could use StringByKey or StringFromList to get them back.


Even if the convenience outweighs the added cost, don't forget that you will generally lose precision in doing this:
Print sqrt(2) == str2num(num2str(sqrt(2)))
0