Why is my function running twice?

I have a project in which several functions need to generate waves. Since a function cannot actually "return" a wave, I've come up with the following design pattern to achieve something like "returning" a wave:


Function/S returnsAWave(inputs)
	Variable inputs	
	String returnNm = "thisNameDoesn'tMatter" // This is the wave I want
	Wave temp1 // This is the wave I'll actually generate for now
        
        ... // temp1 is being generated
        
	Duplicate/O temp1, $returnNm
	return returnNm
End


So now, when I run
$(returnsAWave(inputs))
, the result is the wave I need. Nifty, yes?

Here's my problem: While I understand this may be a strange and not-very-Igory design pattern, it actually seems to make my function run twice. This runnable piece of code can verify that:


Function/S returnsAWave(i)
	Variable i
        
    print "This should only print once per function call"
	String returnNm = "thisNameDoesntMatter" // This is the wave I want
	
	Make/O/N=1 temp1 = {i}
	Duplicate/O temp1, $returnNm
	
	return returnNm
End


In the command window:


• print returnsAWave(1)
This should only print once per function call



• print $(returnsAWave(1))
This should only print once per function call
This should only print once per function call
thisNameDoesntMatter[0]= {1}


In the second case, the function is clearly running twice. But it feels as though if I run the function in either of these cases, the wave "thisNameDoesntMatter" should be generated once and only once. If it's happening twice, this is going to lead to some major efficiency issues (and I think it betrays my general confusion about how $ works, which is the main reason I'm asking). What's going on?
First of all you can return a wave from a function.
At least in IP 6.1 or later.

Function/Wave GenerateWave(i)
       Variable i
	String name = "thisNameDoesntMatter"

       print "This should only print once per function call"
 
	Make/O/N=1 temp1 = {i}
	Duplicate/O temp1, $name/Wave=wv
 
	return wv
End

But you can't use that function in the command window as you would in the procedure window.
You would have to write

GenerateWave(5)
  This should only print once per function call
•print thisNameDoesntMatter
  thisNameDoesntMatter[0]= {5}


Now concerning your question. I can't reproduce that here. I always get an error message "expected assignment or operation".

For the $ vs literal have a look at


Function doStuff()

	string str = "strContents"

	Make/O myWaveName
	Wave wv = myWaveName
	print "WaveName=" + NameOfWave(wv)

	Make/O $"str"
	Wave wv = $"str"
	print "WaveName=" + NameOfWave(wv)

	Make/O $("s" + "t" + num2char(114))
	Wave wv = $"str"
	print "WaveName=" + NameOfWave(wv)

	Make/O $str
	Wave wv = $str
	print "WaveName=" + NameOfWave(wv)

//	Make/O str // <- compile error, we already got a string object called str,
//	           // so we can not create a wave called str
End

this is basically all you need to know about $ vs. literal.
thomas_braun wrote: First of all you can return a wave from a function.
Now concerning your question. I can't reproduce that here. I always get an error message "expected assignment or operation".


Thanks for your response! Sorry, I found the error you were talking about and edited my code. (I forgot to put "print" in the the command window part :| )

I understand the job of $ and your post did a great job of naming its many uses. None of them seem to explain this issue in particular though... it's a strange edge case.
johnweeks wrote:
Once when interpreting the command line, and again for the Print command.


Thanks, I thought it might be something like that... Is there a concise way to explain why this happens? I'm continually more confused about how (and where) $ works.
dtadams wrote: Is there a concise way to explain why this happens?

No.
I'm continually more confused about how (and where) $ works.

You and many others, but you have taken it to a new level :)

In general you would use $ in a user function; using it on the command line in interpreted commands is not really expected. So in the function

Function test()

	Wave w = $(returnsAWave(1))
	print w
end

it works as you expect.

And Thomas Braun's advice is good- make ReturnsAWave() return a wave reference rather than a string.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com