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.
Quote:
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